Android Snippets

System

Get Layout Inflater

As with all system services the LayoutInflater service can be retrieved via the getSystemService() method call of the Activity class.

    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Get IMEI Id

    TelephonyManager tManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    String imei = tManager.getDeviceId();

UI

Get Bitmap from Resource

Sometimes an API wants a Bitmap rather then a resource id.

    Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);

Set Theme for Application

The application does not have to inherit the theme from the device but can define a theme by itself. This can be done in the AndroidManifest.xml file.

<manifest ... >
   <application 
        android:allowBackup="true"
        android:icon="@drawable/app_icon"
        android:theme="@android:style/Theme.Holo.Light" 
        android:label="@string/app_name" 
        android:name="MyApplication"
        >

   </application>
</manifest>

Add Context Menu

Menu entries are declared in XML resource files, see res/menu. The Activity class contains a method onCreateOptionsMenu(Menu) which needs to be overridden to load the XML resource file.

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);

        return true;
    }

Add Search Widget to ActionBar

The search widget can be declared in the menu resource file, see res/menu.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_search"
        android:actionViewClass="android.widget.SearchView"
        android:showAsAction="always"
        android:title="@string/main_menu_search" />

    ...
</menu>

If the search widget needs to be further configured, programmatically, it can be done in the overridden method onCreateOptionsMenu(Menu).

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);

        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        searchView.setIconifiedByDefault(false);
        searchView.setSubmitButtonEnabled(true);
        searchView.setOnQueryTextListener(this);

        return true;
    }

Hide keyboard on activity start up

Normally if an editable view is visible and has the focus on starting of the activity the software keyboard will be shown. Regardless if the user wants to enter something or not. This behaviour can be changed with an entry in the AndroidManifest.xml file.

    <activity android:name="my.Activity" android:windowSoftInputMode="stateHidden"></activity>

Show ProgressDialog during AsyncTask

Sometimes a long running task is executed on the main thread and the user must wait till it finished. It would be nice to show some info or at least show that the background task is still running.

    class MyTask extends AsyncTask<Void, Void, Object> {

        private ProgressDialog progressDialog;
        
        private final Integer entityId;
        private final String name;
        
        public ShowProspectTask(Integer id, String name) {
            entityId = id;
            this.name = name;
        }
        
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(MyActivity.this);
            progressDialog.setCancelable(false);
            progressDialog.setCanceledOnTouchOutside(false);
            progressDialog.setTitle("Loading entity");
            progressDialog.setMessage("Loading entity " + name + "(" + entityId + ")");
            progressDialog.setIndeterminate(true);
            progressDialog.show();
        };

        @Override
        protected Prospect doInBackground(Void... args) {
            return MyService.get(getBaseContext(), Constants.SERVICE_URL, entityId);
        }

        @Override
        protected void onPostExecute(Prospect result) {
            progressDialog.dismiss();
            if (result == null) {
                Toast.makeText(getBaseContext(),
                                "Could not load entity " + name + ".",
                                Toast.LENGTH_LONG).show();
            }
            else {
                showEntityDetails(result);
            }
        }
    }

Create Notification

    NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_action_warning_white);

    Notification notification = new Notification.Builder(context).setContentTitle("My Title")
                            .setContentText("My message to be shown.")
                            .setSmallIcon(R.drawable.ic_action_warning_white)
                            .setLargeIcon(largeIcon)
                            .getNotification();

    mNotificationManager.notify(1, notification);

Horizontal Line

Use a View with fixed height

android:layout_width="fill_parent"
android:layout_height="2dip"
android:background="#FF00FF00" />

or, in code

View ruler = new View(myContext); ruler.setBackgroundColor(0xFF00FF00);
theParent.addView(ruler,
 new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 2));

Link: http://sonnygill.net/android/horizontal-rule/

State dependent Style

The background of a view can be styled dependent of the state. A pressed view can be painted with a different background color.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <item 
        android:drawable="@color/main_entry_selected"
        android:state_pressed="true"
        />
    
    <item 
        android:drawable="@color/main_entry"
        />
    
</selector>

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:background="@drawable/main_selection"
    ...
    />

Contacts

Parse Contacts

    public static void parseProspectContactId(Context context) {
        String[] columns = new String[] {
            ContactsContract.Data.RAW_CONTACT_ID, ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, ContactsContract.Contacts.DISPLAY_NAME
        };

        String selection = null;
        String[] selectionArgs = { };
        
        ContentResolver contentResolver = context.getContentResolver();
        Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, columns, selection, selectionArgs,
                        null);
        
        while (cursor.moveToNext()) {
            String cid = cursor.getString(0);
            if (cursor.getString(1) != null) {
                Log.d("ContactsUtil", "Contact: " + cid + cursor.getString(1));
            }
            else if (cursor.getString(2) != null) {
                Log.d("ContactsUtil", "Contact: " + cid + cursor.getString(2));
            }
            else {
                Log.d("ContactsUtil", "Contact: " + cid + "no name");
            }
        }

        // cleanup
        if (!cursor.isClosed()) {
            cursor.close();
        }
    }

Open Contact

    // open a contact using the lookup key id
    Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, contactId);
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    this.startActivity(intent);

Web Service

Calling a web service can be achieved by using the HTTP Client which comes shipped with Android.

Basic Auth

Basic Authentication on the client side is done by just adding the username and password Base64 encoded to the HTTP headers.

In Android you can use the HttpClient for setting the values.

  DefaultHttpClient httpClient = new DefaultHttpClient();
  CredentialsProvider credProvider = new BasicCredentialsProvider();
  credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
                  new UsernamePasswordCredentials(username, password));
  httpClient.setCredentialsProvider(credProvider);

If a HttpComponentsClientHttpRequestFactory is needed for some reason then the HttpClient object can be passed to the constructor of the HttpComponentsClientHttpRequestFactory class thus enabling Basic Authentication.

REST with POJOs

Most of the time when making a REST call either the serialized representation of a Java Object is passed or received by the client. To not have to fiddle with extracting the information from the raw response or concating some request text a framework can be used for doing this, http://static.springsource.org/spring-android/docs/current/reference/html/ RestTemplate from SpringSource and http://simple.sourceforge.net/ Simple XML Framework hosted on Sourceforge.net.

    public static Prospect get(Context context, String url, Integer id) {
        HttpComponentsClientHttpRequestFactory requestFactory = createHttpRequestFactory(context);
        RestTemplate restTemplate = new RestTemplate(requestFactory);

        Log.i(ProspectService.class.getName(), "Fetch sales prospect from url " + url + "/" + id);
        try {
            Prospect prospect = restTemplate.getForObject(url + "/" + id, Prospect.class);
            Log.i(ProspectService.class.getName(), "Interessent: " + prospect.getName());
            return prospect;
        }
        catch (Exception e) {
            Log.i(ProspectService.class.getName(), "Error on rest call. " + e.getClass().getName() + ": " + e.getLocalizedMessage());
            return null;
        }
    }

For Java objects to be able to work with Simple XML Framework they must implement the Serializable interface.
If not all attributes of a Java object are passed to and from the web service the attribute strict=false should be added to the @Root annotation.