Enable communication between two Android apps via custom permissions

╄→гoц情女王★ 提交于 2019-12-12 11:28:04

问题


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>

回答1:


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.



来源:https://stackoverflow.com/questions/11800258/enable-communication-between-two-android-apps-via-custom-permissions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!