oscarb pad

Guides, resources, notes, docs and knowledge for everything Oscar.


Android Development Notes


Example from Intents and Intent Filters

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {

Preserve state when navigating upwards


When up-navigation is present, use singleTop for the main activity to preserve state when navigating upwards. This will also stop new activites from being started from a notification.



Build URLs using Uri.Builder

compileSdkVersion, minSdkVersion, and targetSdkVersion

Organizing code

Previewing layouts in Android Studio

Use the tools attribute

Frpm Android Studio 3.0, samples are available:



An Activity appears in the foreground
onCreate -> onStart -> onResume

An Activity is sent to the background (app switched)
onPause -> onStop -> onDestroy

From Active to Visible (but not active) (modals)
onPause -> onResume

From Active or Visible to Background
onPause -> onStop -> onRestart -> onStart




Five ways to persist data in Android:


Reading From SharedPreferences

Gets a SharedPreferences instance that points to the default file that is used by the preference framework in the given context!
Gets a specific SharedPreferences instance by name in case you have more than one preference in the same context!

Preference Change Listener

Update preference fragment


Should it be a setting?

Make it a setting?

SQLLite Database

Create a database

Content provider

Using a ContentProvider

  1. Get permission to use the ContentProvider.

    <uses-permission android:name="com.example.appname.TERMS_READ" />
  2. Get the ContentResolver

    ContentResolver resolver = getContentResolver();
    Cursor cursor = resolver.query(Contract.CONTENT_URI, null, null, null, null);
  3. Pick one of four basic actions on the data: query, insert, update, delete
  4. Identify the data you are reading or manipulating to create a URI
  5. In the case of reading from the ContentProvider, display the information in the UI

Creating a content provider

  1. Extend the ContentProvider class and implement the required methods
  2. Register it in the Manifest
  3. Define URI’s
  4. Add URI’s to the contract class
  5. Build a URIMatcher to match URI patterns

URI Example:



Cursor methods arguments

Match integer: #
Match string: *

Example of getType:

public String getType(@NonNull Uri uri) {
    int match = sUriMatcher.match(uri);

    switch (match) {
        case TASKS:
            // directory
            return "vnd.android.cursor.dir" + "/" + TaskContract.AUTHORITY + "/" + TaskContract.PATH_TASKS;
        case TASK_WITH_ID:
            // single item type
            return "vnd.android.cursor.item" + "/" + TaskContract.AUTHORITY + "/" + TaskContract.PATH_TASKS;
            throw new UnsupportedOperationException("Unknown uri: " + uri);

The best way to asynchronously load data from any ContentProvider is with a CursorLoader

Comparing S09.05-Exercise-MoreDetails…S09.05-Solution-MoreDetails · udacity/ud851-Sunshine

Comparing S09.02-Exercise-ContentProviderBulkInsert…S09.02-Solution-ContentProviderBulkInsert · udacity/ud851-Sunshine

Code Quality


Background task

“More background” than Loader (more front-end)
Loaders outlasts configuration changes
Services outlasts activites

Start a service



Automatically runs on the background thread in order, perfect for one off tasks that need to be handled in the background in order.

Runs on a worker thread (compared to the main thread for a Service).

Stops itself after requests have been handled unlike a Service which needs to be stopped with stopSelf() or stopService()

“Fire and forget”

Comparing T10.01-Exercise-IntentServices…T10.01-Solution-IntentServices · udacity/ud851-Exercises

Android 8.0

Many apps that rely on IntentService do not work properly when targeting Android 8.0 or higher. For this reason, Android Support Library 26.0.0 introduces a new JobIntentService class, which provides the same functionality as IntentService but uses jobs instead of services when running on Android 8.0 or higher.



The base class that handles asynchronous requests that were previously scheduled in a JobScheduler.

Because it runs on the main thread any task needs to be set up on another thread/handler/AsyncTask to avoid blocking future callbacks from the JobManager.

Adding a JobService - YouTube
Exercise: Schedule with FirebaseJobDispatcher - YouTube

It’s important that we verify that we’ve imported jobdispatcher.JobService rather than the Android framework’s JobService, because if you do, you’ll definitely have some headaches. Double and triple check that please.

Android Developers Blog: Moar Power in Android 9 Pie and the future


Service required to have a non-dismissible ongoing notification. Less likely to be destroyed when memory gets low.




Driver driver = new GooglePlayDriver(context);
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(driver);

Job myJob = dispatcher.newJobBuilder()
    // the JobService that will be called
    // uniquely identifies the job
    // one-off job
    // don't persist past a device reboot
    // start between 0 and 15 minutes (900 seconds)     
    .setTrigger(Trigger.executionWindow(0, 900))
    // overwrite an existing job with the same tag
    // retry with exponential backoff 
    // constraints that need to be satisfied for the job to run
        // only run on an unmetered network
        // only run when the device is charging

Scheduling Jobs - YouTube
The Firebase JobDispatcher

Comparing T10.04-Exercise-PeriodicSyncWithJobDispatcher…T10.04-Solution-PeriodicSyncWithJobDispatcher · udacity/ud851-Exercises

String resources



<plurals name="charge_notification_count">
   <item quantity="zero">Hydrate while charging reminder sent %d times</item>
   <item quantity="one">Hydrate while charging reminder sent %d time</item>
   <item quantity="other">Hydrate while charging reminder sent %d times</item>


String formattedChargingReminders = getResources().getQuantityString(R.plurals.charge_notification_count, chargingReminders, chargingReminders);


String format


<string name="format_art_url" translatable="false">https://raw.githubusercontent.com/udacity/Sunshine-Version-2/sunshine_master/app/src/main/res/drawable-xxhdpi/art_<xliff:g id="description">%s</xliff:g>.png</string>


context.getString(R.string.format_art_url, "clear");


Intent in your app designed to be started by another app/service.

This allows a notification (which is handled by the NotificationManager (a system service)) to start your App.


Use a PendingIntent to open your App from a notification.

Notifications - Patterns - Material design guidelines

[Notifications Android Developers](https://developer.android.com/guide/topics/ui/notifiers/notifications.html)
[Using Big View Styles Android Developers](https://developer.android.com/training/notify-user/expanded.html)
[Notification.BigPictureStyle Android Developers](https://developer.android.com/reference/android/app/Notification.BigPictureStyle.html)

Comparing T10.02-Exercise-CreateNotification…T10.02-Solution-CreateNotification · udacity/ud851-Exercises

Add actions to notifications

Engage with rich notifications

Check for Google Play Services both in onCreate() and onResume()

For Android versions >= HONEYCOMB, notifcation image sizes can be found with

int largeIconWidth = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? 
	? resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width)
	: resources.getDimensionPixelSize(R.dimen.notification_large_icon_default);

Where R.dimen.notification_large_icon_default is set to 48dp

Set the color for notifications from Firebase in the manifest with:

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
    android:resource="@color/colorAccent" />

If the device doesn’t have a compatible version of Google Play services, your app can call GoogleApiAvailability.makeGooglePlayServicesAvailable() to allow users to download Google Play services from the Play Store.

Must use channels once target O is targeted.

Memory prioritization

Broadcast Receiver

System Broadcast Intents - triggers for various device changes.

Creating a broadcast receiever:

To handle broadcasts when app isn’t started: JobDispatcher or in some cases a static broadcast receiver
To handle broadcasts when app is started: dynamic broadcast receiver

Register in onResume() and unregister in onPause if it only is needed for foreground stuff.

Comparing T10.05-Exercise-ChargingBroadcastReceiver…T10.05-Solution-ChargingBroadcastReceiver · udacity/ud851-Exercises

Android Debug Bridge

Start app

adb shell am start -n com.package.name/com.package.name.ActivityName

Simulate unplugging from USB

adb shell dumpsys battery set usb 0

Above for Android 6.0+

adb shell dumpsys battery unplug

Simulate plugging into power

adb shell dumpsys battery reset
[Android Debug Bridge Android Studio](https://developer.android.com/studio/command-line/adb.html?utm_source=udacity&utm_medium=mooc&utm_term=android&utm_content=adb&utm_campaign=training)

View and View Groups

Avoid nesting view and viewgroups too deep.

General rule of thumb:

Views & View Groups - YouTube

Correct the ImageView’s adjustViewBounds behaviour on API Level 17 and below with AdjustableImageView :: The Cheese Factory







Center vertically by putting a top-constraint to the bottom of the other view, and a bottom-constraint to the top of the other view






Hierarchy viewer

Tools > Device monitor > Perspective > Hierarcy viewer


[Accessibility Developer Checklist Android Developers](https://developer.android.com/guide/topics/ui/accessibility/checklist.html#recommendations)


Localization Checklist | Android Developers
ISO 639-2 Language Code List - Codes for the representation of names of languages (Library of Congress)
Localization checklist | Android Developers


Different views in a RecyclerView
Comparing S11.02-Exercise-TodayListItem…S11.02-Solution-TodayListItem · udacity/ud851-Sunshine

Provide height and width or face the consequences




Style vs Theme

A theme is a style applied to an activity

For lists, use dimensions such as: @dimen/list_item_icon_margin_right


Use the smallest width qualifier


Touch selectors

  1. Create drawable list_item_selector.xml
  2. Root element should be selector
    0- Add items for different states
    • state_pressed
    • state_activated
    • state_selected
    • default
      Note: each item can have a color as the drawable
  3. Set background of item to be selected to the newly created touch selector

Publishing an app

Material Design


Display 4 corresponds to


and so on…


Look for support, documentation and functionality


Android Testing Codelab

Material design


Default toolbar size height: `?attr/actionBarSize”

Style with





Aliases as resources


  <item type="layout" name="refName">@layout/some_layout</item>


Item choices

Using RecyclerView Part 3 - YouTube

Implementing a modal selection helper for RecyclerView

Parallell scrolling

  1. Attach scrollListener
    • Change translation in y of background by half in relative to the y scroll
    • Clear onScrollListeners in onDestroy

Scrolling in Parallel - YouTube
Scrolling in Parallel - YouTube

Support higher screen ratios

In order to support screen ratios such as 18.5:9 (like that on the Samsung Galaxy S8), add the following to the manifest, in the application element:

_Where ratio_float is the maximum aspect ratio your app can support, expressed as (longer dimension / shorter dimension) in decimal form. _



Exclude navigation bar and status bar with @android:id/statusBarBackground and @android:id/navigationBarBackground respectively.

<item name="android:windowContentTransitions">true</item>
<item name="android:windowEnterTransition">@transition/enter_transition</item>
<item name="android:windowReturnTransition">@transition/return_transition</item>
ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
ActivityCompat.startActivity(this, intent, activityOptions.toBundle());
[Animation Resources Android Developers](https://developer.android.com/guide/topics/resources/animation-resource.html)
[The Transitions Framework Android Developers](https://developer.android.com/training/transitions/overview.html)
[Animating Views Using Scenes and Transitions Android Developers](https://developer.android.com/training/transitions/index.html)
[Applying a Transition Android Developers](https://developer.android.com/training/transitions/transitions.html)

Shared elements

Shared Element Transitions (solution) - YouTube

Android Developers Blog: Continuous Shared Element Transitions: RecyclerView to ViewPager

Places API

Comparing 8.00_Places_API_Start…8.07_Adding_Attributions · udacity/Advanced_Android_Development

[Place Picker     Google Places API for Android     Google Developers](https://developers.google.com/places/android-api/placepicker#add)


Creating the Widget’s view - YouTube
7.01_Sunshines_First_Widget · udacity/Advanced_Android_Development


minResizeWidth can be set to smaller than default size minWidth

Collection widget: YouTube

AppWidgetProviderInfo (XML)

Required attributes

Size = 70dp * n - 30dp
= 40 dp for n = 1
= 110 dp    = n = 2

AppWidgetProvider (Java)

public class TodayWidgetProvider extends AppWidgetProvider {
  public void onUpdate(Context context, AppWidgetManager manager, int[} appWidgetIds) {
    for (int appWidgetId : appWidgetIds) {
      RemoteViews = views = new RemoteViews(context.getPackageName(), R.layot.widget_today_small);
      // Clickable widget
      Intent intent = new Intent(context, MainActivity.class);
      PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
      views.setOnClickPendingIntent(R.id.widget, pendingIntent);
      manager.updateAppWidget(appWidgetId, views);


“Users will complain about performance 3x than any other issue”

[Performance Tips Android Developers](https://developer.android.com/training/articles/perf-tips.html)


Test overdraw

Memory Monitor

[Manage Your App’s Memory Android Developers](https://developer.android.com/topic/performance/memory.html)

Night Mode




MVI - Model View Intent



Getting context

Fragment#requireContext, for example, returns a non-null Context and throws an IllegalStateException if called when a Context would be null. This way, you can treat the resulting Context as non-null without the need for safe-call operators or workarounds.


Check for unessecary added permissions from libraries

How Libraries can silently add permissions to your Android App

Android Architecture

Android Developers Blog: Android and Architecture

[Guide to App Architecture Android Developers](https://developer.android.com/topic/libraries/architecture/guide.html)


Enable Google Safe Browsing API

Same as in Chrome

        android:value="true" />
    <!-- ... --->

Adaptive icons

Date, time and calendars

Android O



Launcer Icon Sizes

size identifier size
ldpi 36x36
mdpi 48x48
hdpi 72x72
xhdpi 96x96
xxhdpi 144x144
xxxhdpi 192x192
Google Play 512x512

Google Play Referrer API

See http://android-developers.googleblog.com/2017/11/google-play-referrer-api-track-and.html

Auto-backup for apps

Android Developers Blog: Discover tools for Android data migration and improve your app retention



Udacity Android Developer Nanodegree - Core App Quality Guidelines

        Visual Design and User Interaction

              Standard Design

                    App does not redefine the expected function of a system icon (such as the Back button).

                    App does not redefine or misuse Android UI patterns, such that icons or behaviors could be misleading or confusing to users.


                    App supports standard system Back button navigation and does not make use of any custom, on-screen "Back button" prompts.

                    All dialogs are dismissible using the Back button.

                    Pressing the Home button at any point navigates to the Home screen of the device.



                          App does not redefine or misuse Android UI patterns, such that icons or behaviors could be misleading or confusing to users.

                          App does not request permissions to access sensitive data or services that can cost the user money, unless related to a core capability of the app.

                    User/App State

                          App correctly preserves and restores user or app state, that is , student uses a bundle to save app state and restores it via onSaveInstanceState/onRestoreInstanceState. For example,

                                When a list item is selected, it remains selected on rotation.

                                When an activity is displayed, the same activity appears on rotation.

                                User text input is preserved on rotation.

                                Maintains list items positions on device rotation.

                          When the app is resumed after the device wakes from sleep (locked) state, the app returns the user to the exact state in which it was last used.

                          When the app is relaunched from Home or All Apps, the app restores the app state as closely as possible to the previous state.

              Performance and Stability


                          App does not crash, force close, freeze, or otherwise function abnormally on any targeted device.

              Google Play

                    Content Policies

                          All content is safe for work content.

                          App adheres to the Google Play Store App policies.

                          App’s code follows standard Java/Android Style Guidelines.

Android TV Development Notes

Best practices



80 % Android 7+ (Source:


Recommendations channels are only available in Android 8.0 (API level 26) and later. You must use them to supply recommendations for apps running in Android 8.0 (API level 26) and later. To supply recommendations for apps running on earlier versions of Android, your app must use the recommendations row instead.

Recommend content on the home screen