4

我的一个 Android 应用程序需要一些在权限方面“危险”的功能。他们需要一些权限,例如“互联网访问”,这些权限与私人数据相结合是至关重要的。

这就是为什么我想创建一个单独的“附加组件”,即提供这些权限关键功能的第二个应用程序。因此,如果用户需要它们,他们可以安装附加组件,但主应用程序在没有这些权限的情况下仍然可以运行。

使用 asharedUserId显然是最简单的解决方案,但之后添加它,当很多用户已经使用该应用程序时,可能会导致严重的问题。这不是意味着应用程序不能再访问自己的数据了吗?

所以我不得不选择另一种方法。ContentProviders 是我尽量避免的,因为在我看来它们对于这个简单的需求来说太复杂了。

我认为自定义权限可以解决这个问题。他们可以吗?我已将以下权限声明添加到主应用程序以及作为子项的附加组件到manifest标签中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" />

此外,两个清单文件现在都有这部分:

<uses-permission android:name="com.my.package.ADDON"></uses-permission>

附加应用程序IntentService现在包含一个具有以下属性的应用程序:

android:permission="com.my.package.ADDON"

这不应该完成这项工作,以便我可以IntentService通过此代码从我的主应用程序调用附加组件吗?

Intent addonIntent = new Intent();
addonIntent.setClassName("com.my.package", "com.my.package.MyService");
startService(addonIntent);

不幸的是,这个调用总是失败,并出现以下异常:

E/AndroidRuntime(16721): java.lang.SecurityException: Not allowed to start service Intent { cmp=com.mypackage.addon/.MyService } without permission com.mypackage.permission.ADDON

我做错什么了?非常感谢您!

添加 #1 - 附加清单:

<?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>

补充 #2 - 主应用清单:

<?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>
4

1 回答 1

6

这不是意味着应用程序不能再访问自己的数据了吗?

正确的。

我添加了以下权限

我会转储permission-group,因为这不是必需的。

此外,两个清单文件现在都有这部分

只有打电话给你的人IntentService可能需要那个。

这不应该完成这项工作,以便我可以通过此代码从我的主应用程序调用附加组件的 IntentService 吗?

如果IntentService不导出,则不会。确保您的IntentServiceany 具有<intent-filter>or android:exported="true"。我建议您走这<intent-filter>条路线,这样您就可以声明和使用自定义操作字符串,这样您就可以摆脱客户端应用程序中的硬编码包和类名称。

这是一个包含两个使用这种基本方法的示例项目的目录,尽管在我的情况下,通信是基于安全的ContentProvider而不是安全的IntentService。但是,这个概念是相同的,因此通过这些细微的调整,我希望您所做的一切都能正常工作。

于 2012-08-03T17:31:55.133 回答