Android Custom Permissions

Google encourages developers to define custom permissions to protect our publicly available activities and custom data providers.  The first step is to define such permissions in your manifest so that your app as well as all other apps can display pretty text for the permissions.  Apps that merely use your custom permissions will display the text you defined in your app for each permission. One issue I discovered is that you should never define the permission group as an empty string (android:permissionGroup=””) or else the permission definition becomes invalid and no other app will be able to use it.

Custom permissions should also define a custom Permission Group if they are not part of one of the Android built-in groups, otherwise they will be displayed as part of a permission called “Default” and all your custom permissions will be shown as a comma separated list underneath it. For example:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mydomain.myapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <permission-group android:name="com.mydomain.provider.permissions" 
        android:label="@string/perm_text_group_mydomain_provider" />

    <permission android:name="com.mydomain.provider.permission.ACCESS_DATA"
        android:permissionGroup="com.mydomain.provider.permissions" 
        android:label="@string/perm_text_access_mydomain_provider" />

    <permission android:name="com.mydomain.provider.permission.WRITE_DATA"
        android:permissionGroup="com.mydomain.provider.permissions" 
        android:label="@string/perm_text_modify_mydomain_provider" />

    <uses-permission android:name="com.mydomain.provider.permission.ACCESS_DATA" />
    <uses-permission android:name="com.mydomain.provider.permission.WRITE_DATA" />

    <application
      android:label="@string/app_name"
      android:description="@string/app_desc" 
      android:icon="@drawable/app_icon" >

        <provider android:name="com.mydomain.MyProvider" 
            android:authorities="com.mydomain.provider.myprovider" 
            android:readPermission="com.mydomain.provider.permission.ACCESS_DATA" 
            android:writePermission="com.mydomain.provider.permission.WRITE_DATA" 
            android:exported="true" >
        </provider>

    </application>

</manifest>

Once you have defined all your permissions, other apps can simply use them with <uses-permission> and their apps will use your string definitions when displaying them in Settings as part of managing the device’s apps.

Android’s onCreateContextMenu() called with no ContextMenuInfo

I recently had an exception report from an eeePC using a mouse which caused the following code to give a NullPointerException:

public void onCreateContextMenu(ContextMenu aMenu, View aView, ContextMenuInfo aMenuInfo) {
	AdapterView.AdapterContextMenuInfo theMenuInfo = null;
	try {
		theMenuInfo = (AdapterView.AdapterContextMenuInfo) aMenuInfo;
	} catch (ClassCastException e) {
		return;
	}
	File theFile = myActivity.getListItem(theMenuInfo.position);
	//...snip rest of code...
}

The only way that theMenuInfo would be NULL in order to cause the NullPointerException is that the passed in aMenuInfo was NULL — and that is not supposed to be the case.

I am not quite sure how such an event occurred. It could be a result of “right-clicking” on a spot where there is no list item shown, except that the behavior in that case should have not resulted in a context menu since there is no item there at all. While I should not have to protect my code against a NULL being passed in for the required ContextMenuInfo parameter, I have to live in the world that is, not the world of should. Who knows, maybe this is the start of a trend where “right clicking” on the “white space” of a list will pass in NULL for that parameter and cause a completely different menu to popup for quick actions that provide the same functionality as clicking on the Menu button and choosing some deeper submenu from that list. Then again, it is probably just a bug in the OS and will be fixed at a later point in time. Either way, it’s best to protect against NULL parameters even if they should never be NULL.

My new code:

public void onCreateContextMenu(ContextMenu aMenu, View aView, ContextMenuInfo aMenuInfo) {
	AdapterView.AdapterContextMenuInfo theMenuInfo = null;
	File theFile = null;
	try {
		theMenuInfo = (AdapterView.AdapterContextMenuInfo) aMenuInfo;
		theFile = myActivity.getListItem(theMenuInfo.position);
	} catch (ClassCastException cce) {
		return;
	} catch (NullPointerException npe) {
		return;
	}
	//...snip rest of code...
}

If you know why the ContextMenuInfo parameter is sometimes NULL, please feel free to share the reason as I know several developers that would be interested in it besides myself.

Picking a Contact photo with Motorola Cliq

Some Motorola Cliq phones are having issues trying to pick a contact photo using something other than the Gallery app that comes with the phone. Motorola is aware of the issue, but I am trying out a workaround for it in my File Browser app. Basically, the problem is that an OutOfMemoryError could result from attempting to pick a large photo because the Intent being used does not specify the size to be returned. Normally, I would just use getIntExtra(“outputX”,defX) and getIntExtra(“outputY”,defY) in order to get what the caller wanted as a size, but since Motorola’s contact app does not provide those Intent Extras, it would return the full sized photo.

Instead of waiting for Motorola to modify their app, I decided to check the name of the caller and provide a default size for that particular app.

if (myActivity.getCallingPackage().equals("com.motorola.blur.contacts")) {
    outputX = outputY = 48;
}

Android: Update to Postmortem Reports via email

With the addition of an Activity stack to my portmortem email reporter, it became apparent that relying on the garbage collector to restore the original exception handler was not an ideal solution. I have added a new method called restoreOriginalHandler() that should be called in your Activity class’s onDestroy() method.

public class MyActivity extends Activity {
    protected PostMortemReportExceptionHandler mDamageReport = new PostMortemReportExceptionHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDamageReport.initialize();
    }

    @Override
    protected void onDestroy() {
        mDamageReport.restoreOriginalHandler();
        mDamageReport = null;
        super.onDestroy();
    }
}

Original post, updated.

Updated code link (copied from original post):
Full Source

Android: Update to Postmortem Reports via email

It has been a while since my post about Postmortem Reports via email and since then I have upgraded it, commented more on it and fixed a few issues as well. The class now protects against a null exception and uses the application label instead of the activity title in the subject. The class also unregisters itself on finalize as well as protects against sending multiple reports for a single exception if you have several activities active and each has their own handler registered. I am also happy to report that people are willing to send you debug reports. I do not receive more than a handful, but I only need one or two in order to figure out what is going on and fix it. I also can tell how serious it is depending on how frequently I get a report about it. I even get reports from people using a pirated version of my paid apps. Continue reading

Avoid uncaught NullPointerException at Android app launch

While we all strive to avoid any kind of exceptions in software, we all make mistakes. One exception to be particularly mindful of is causing an uncaught NullPointerException during the app launch process on Android pre-2.2 (meaning the initial onCreate+onStart+onResume chain). The reason to avoid such a situation is that your app will crash, of course, but furthermore, the Android OS will notice that launching your app failed and will automatically try to launch it again — ad infinitum. Continue reading

Android: Postmortem Reports via email

How can I get postmortem exception information from my deployed app without requiring net access?

One of the major breakthroughs I have had with my Android development has been the addition of a postmortem exception reporter into my apps. I started out my development on the emulator only as I did not have an Android phone of my own yet. I ran into the dilemma of having code that worked fine on the emulator, but crashed on some phones out in the field. Comments were pouring into my app with 1 star ratings and “FC on open”. I searched far and wide for a solution to use with postmortem crash analysis, but each one I researched required net access on the phone in order to report back. I was not going to force the requirement onto my fans because I don’t trust apps that should not need net access but do, so why should I force my fans to trust me? Continue reading