Reputation: 31497
One of my Android applications needs some features that are "dangerous" when it comes to permissions. They require some permissions such as "Internet access" which are critical in combination with private data.
This is why I want to create a separate "Add-on", i.e. a second app that provides these permission-critical features. So if users want them, they can install the add-on, but the main app will still work without those permissions.
Using a sharedUserId
would obviously be the easiest solution, but adding this afterwards, when lots of users use the app already, could cause serious problems. Wouldn't this mean that the app can't access its own data any longer?
So I have to choose another approach. ContentProviders are something that I try to avoid, because they're too complex for this simple need in my opinion.
I thought custom permissions could solve the issue. Can they? I've added the following permission declaration to both the main app as well as the add-on as a child to the manifest
tag in AndroidManifest.xml
:
<permission
android:name="com.my.package.ADDON"
android:label="@string/permission_title"
android:description="@string/permission_description"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:protectionLevel="signature" />
Furthermore, both manifest files have got this part now:
<uses-permission android:name="com.my.package.ADDON"></uses-permission>
The add-on app includes an IntentService
that has the following attribute now:
android:permission="com.my.package.ADDON"
Shouldn't this do the job so that I can call the add-on's IntentService
from my main app via this code?
Intent addonIntent = new Intent();
addonIntent.setClassName("com.my.package", "com.my.package.MyService");
startService(addonIntent);
Unfortunately, this call always fails with the following exception:
E/AndroidRuntime(16721): java.lang.SecurityException: Not allowed to start service Intent { cmp=com.mypackage.addon/.MyService } without permission com.mypackage.permission.ADDON
What did I do wrong? Thank you very much in advance!
Addition #1 - Add-on manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.mypackage.addon">
<uses-sdk android:minSdkVersion="8" />
<permission
android:name="com.mypackage.permission.ADDON"
android:label="@string/permission_title"
android:description="@string/permission_description"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:permission="com.mypackage.permission.ADDON"
android:exported="true">
<service
android:enabled="true"
android:name=".MyService" />
</application>
</manifest>
Addition #2 - main app manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.mypackage.mainapp">
<uses-sdk android:minSdkVersion="8" />
<permission
android:name="com.mypackage.permission.ADDON"
android:label="@string/permission_title"
android:description="@string/permission_description"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:protectionLevel="signature" />
<uses-permission android:name="com.mypackage.permission.ADDON"></uses-permission>
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name="MyApp">
<activity android:name=".MainActivity" android:launchMode="singleTask" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Upvotes: 4
Views: 2696
Reputation: 1007658
Wouldn't this mean that the app can't access its own data any longer?
Correct.
I've added the following permission
I would dump the permission-group
, as that should not be necessary.
Furthermore, both manifest files have got this part now
Only the one calling your IntentService
might need that.
Shouldn't this do the job so that I can call the add-on's IntentService from my main app via this code?
Not if that IntentService
is not exported. Make sure that your IntentService
either has an <intent-filter>
or android:exported="true"
. I would recommend going the <intent-filter>
route, so you can declare and use a custom action string, so you get away from hard-coding package and class names in the client app.
Here is a directory with two sample projects using this basic approach, though in my case the communications are based on a secured ContentProvider
rather than a secured IntentService
. The concept is the same, though, and so with these minor tweaks, I would expect what you are doing to work just fine.
Upvotes: 6