Differences

This shows you the differences between two versions of the page.

Link to this comparison view

android_snippets [2014/01/07 14:45]
android_snippets [2021/04/05 11:23] (current)
Line 1: Line 1:
 +====== 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.
 +<sxh java>
 +    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 +</sxh>
 +
 +==== Get IMEI Id ====
 +<sxh java>
 +    TelephonyManager tManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
 +    String imei = tManager.getDeviceId();
 +</sxh>
 +
 +===== UI =====
 +
 +==== Get Bitmap from Resource ====
 +Sometimes an API wants a Bitmap rather then a resource id.
 +
 +<sxh java>
 +    Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
 +</sxh>
 +
 +==== 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.
 +
 +<sxh xml>
 +<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>
 +</sxh>
 +
 +==== 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.
 +
 +<sxh java>
 +    @Override
 +    public boolean onCreateOptionsMenu(Menu menu) {
 +        MenuInflater inflater = getMenuInflater();
 +        inflater.inflate(R.menu.main, menu);
 +
 +        return true;
 +    }
 +</sxh>
 +
 +==== Add Search Widget to ActionBar ====
 +The search widget can be declared in the menu resource file, see ''res/menu''.
 +
 +<sxh xml>
 +<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>
 +</sxh>
 +
 +If the search widget needs to be further configured, programmatically, it can be done in the overridden method ''onCreateOptionsMenu(Menu)''.
 +
 +<sxh java>
 +    @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;
 +    }
 +</sxh>
 +
 +==== 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.
 +
 +<sxh xml>
 +    <activity android:name="my.Activity" android:windowSoftInputMode="stateHidden"></activity>
 +</sxh>
 +
 +==== 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.
 +
 +<sxh java>
 +    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);
 +            }
 +        }
 +    }
 +</sxh>
 +
 +==== Create Notification ====
 +<sxh java>
 +    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);
 +</sxh>
 +
 +==== Horizontal Line ====
 +Use a View with fixed height
 +
 +<sxh xml>
 +android:layout_width="fill_parent"
 +android:layout_height="2dip"
 +android:background="#FF00FF00" />
 +</sxh>
 +
 +or, in code
 +
 +<sxh java>
 +View ruler = new View(myContext); ruler.setBackgroundColor(0xFF00FF00);
 +theParent.addView(ruler,
 + new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 2));
 +</sxh>
 +
 +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.
 +
 +<sxh xml>
 +<?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>
 +</sxh>
 +
 +<sxh xml>
 +<?xml version="1.0" encoding="utf-8"?>
 +<TextView xmlns:android="http://schemas.android.com/apk/res/android"
 +    ...
 +    android:background="@drawable/main_selection"
 +    ...
 +    />
 +</sxh>
 +
 +===== Contacts =====
 +
 +==== Parse Contacts ====
 +<sxh java>
 +    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();
 +        }
 +    }
 +</sxh>
 +
 +
 +==== Open Contact ====
 +<sxh java>
 +    // 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);
 +</sxh>
 +
 +
 +===== 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.
 +
 +<sxh java>
 +  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);
 +</sxh>
 +
 +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.
 +
 +<sxh java>
 +    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;
 +        }
 +    }
 +</sxh>
 +
 +<note important>
 +For Java objects to be able to work with Simple XML Framework they must implement the ''Serializable'' interface.
 +</note>
 +
 +
 +<note>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.</note>
 +
 +{{tag>android}}