The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.
Adding basic permissions to your app to allow it to, say, access the Internet, is fairly easy. However, the full permissions system has many capabilities beyond simply asking the user to let you do something. This chapter explores other uses of permissions, from securing your own components to using signature-level permissions (your own or Android’s).
Understanding this chapter requires that you have read the core chapters, particularly the chapter on permissions and the chapter on signing your app.
One of the sample apps uses RxJava and RxAndroid, which are introduced elsewhere in the book.
Principally, at least initially, permissions are there to allow the user to secure their device. They have to agree to allow you to do certain things, such as reading contacts, that they might not appreciate.
The other side of the coin, of course, is to secure your own application. If your application is mostly activities, security may be just an “outbound” thing, where you request the right to use resources of other applications. If, on the other hand, you put content providers or services in your application, you will want to implement “inbound” security to control which applications can do what with the data.
Note that the issue here is less about whether other applications might “mess up” your data, but rather about privacy of the user’s information or use of services that might incur expense. That is where the stock permissions for built-in Android applications are focused – can you read or modify contacts, can you send SMS, etc. If your application does not store information that might be considered private, security is less an issue. If, on the other hand, your application stores private data, such as medical information, security is much more important.
The first step to securing your own application using permissions is to
declare said permissions, once again in the
In this case, instead of
uses-permission, you add
elements. Once again, you can have zero or more
all as direct children of the root
Declaring a permission is slightly more complicated than using a permission. There are three pieces of information you need to supply:
<permission android:name="vnd.tlagency.sekrits.SEE_SEKRITS" android:label="@string/see_sekrits_label" android:description="@string/see_sekrits_description" />
This does not enforce the permission. Rather, it indicates that it is a possible permission; your application must still flag security violations as they occur.
There are two ways for your application to enforce permissions, dictating where and under what circumstances they are required. The easier one is to indicate in the manifest where permissions are required.
Activities, services, and receivers can all declare an attribute named
android:permission, whose value is the name of the permission that is
required to access those items:
<activity android:name=".SekritApp" android:label="Top Sekrit" android:permission="vnd.tlagency.sekrits.SEE_SEKRITS"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Only applications that have requested your indicated permission will be able to access the secured component. In this case, “access” means:
sendBroadcast()unless the sender has the permission
In your code, you have two additional ways to enforce permissions.
Your services can check permissions on a per-call basis via
checkCallingPermission(). This returns
PERMISSION_DENIED depending on whether the caller has the permission
you specified. For example, if your service implements separate read
and write methods, you could require separate read versus write
permissions in code by checking those methods for the permissions you
need from Java.
Also, you can include a permission when you call
This means that eligible broadcast receivers must hold that permission;
those without the permission are ineligible to receive it. We will
sendBroadcast() in greater detail elsewhere in this book.
While normally you require your own custom permissions using the techniques described above, there is nothing stopping you from reusing a standard system permission, if it would fit your needs.
For example, suppose that you are writing YATC (Yet Another Twitter Client). You decide that in addition to YATC having its own UI, you will design YATC to be a “Twitter engine” for use by third party apps:
You could, and perhaps should, implement your own custom permission.
However, since any app can get to Twitter just by having the
permission, one could argue that a third-party app should just need
INTERNET permission to use your API (rather than integrating
JTwitter or another third-party JAR).
The preview of this section was lost in the sofa cushions.
The preview of this section is being chased by zombies.
The preview of this section was traded for a bag of magic beans.
The preview of this section is in the process of being translated from its native Klingon.