允许通过自定义权限两款Android应用程序之间的通信 [英] Enable communication between two Android apps via custom permissions

查看:372
本文介绍了允许通过自定义权限两款Android应用程序之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个Android应用程序需要一定的功能,是危险的,当涉及到权限。他们需要一些权限,如互联网接入,这是与私有数据的组合是至关重要的。

这就是为什么我要创建一个单独的附加,即第二个应用程序,提供这些许可的关键特性。因此,如果用户希望,他们可以在插件安装,但主要应用还是会没有这些权限的工作。

使用 sharedUserId 显然是最简单的解决方案,但后来加入这一点,当大量用户使用的应用程序已经,可能会造成严重的问题。这是不是意味着该应用程序不能再访问自己的数据?

所以我不得不选择另一种方法。 ContentProviders的东西,我会尽量避免,因为他们在我看来,这简单的需求太复杂了。

我想自定义权限可以解决这个问题。他们能?我已经添加了以下权限声明,双方主要的应用程序,以及在 AndroidManifest.xml中附加上作为一个孩子的清单标签

 <许可
    机器人:名字=com.my.package.ADDON
    机器人:标签=@字符串/ permission_title
    机器人:说明=@字符串/ permission_description
    机器人:permissionGroup =android.permission-group.PERSONAL_INFO
    安卓的ProtectionLevel =签名/>

此外,这两个清单文件已经得到这部分现在:

 <使用许可权的android:NAME =com.my.package.ADDON>< /使用许可权>

的附加应用包括 IntentService ,现在具有以下属性:

 安卓权限=com.my.package.ADDON

不应该这样做的工作,这样我可以调用附加的 IntentService 从我这通过code主应用程序?

 意图addonIntent =新意图();
addonIntent.setClassName(com.my.package,com.my.package.MyService);
startService(addonIntent);

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

  E / AndroidRuntime(16721):java.lang.SecurityException异常:不允许启动服务意向{CMP = com.mypackage.addon / .MyService}擅自com.mypackage.permission 。加上

我做了什么错?非常感谢你提前!

加#1 - 附加清单:

 <?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
      安卓版code =1
      机器人:=的versionName1.0
      包=com.mypackage.addon>
    <采用-SDK安卓的minSdkVersion =8/>
    <许可
        机器人:名字=com.mypackage.permission.ADDON
        机器人:标签=@字符串/ permission_title
        机器人:说明=@字符串/ permission_description
        机器人:permissionGroup =android.permission-group.PERSONAL_INFO
        安卓的ProtectionLevel =签名/>
    <使用许可权的android:NAME =android.permission.WRITE_EXTERNAL_STORAG​​E>< /使用许可权>
    <使用许可权的android:NAME =android.permission.INTERNET对>< /使用许可权>
<应用
    机器人:图标=@绘制/ ic_launcher
    机器人:标签=@字符串/ APP_NAME
    机器人:权限=com.mypackage.permission.ADDON
    机器人:出口=真正的>
    <服务
        机器人:启用=真
        机器人:名字=则将MyService/>
< /用途>
< /清单>

加#2 - 主要的应用程序清单:

 <?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
      安卓版code =1
      机器人:=的versionName1.0
      包=com.mypackage.mainapp>
    <采用-SDK安卓的minSdkVersion =8/>
    <许可
        机器人:名字=com.mypackage.permission.ADDON
        机器人:标签=@字符串/ permission_title
        机器人:说明=@字符串/ permission_description
        机器人:permissionGroup =android.permission-group.PERSONAL_INFO
        安卓的ProtectionLevel =签名/>
    <使用许可权的android:NAME =com.mypackage.permission.ADDON>< /使用许可权>
<应用机器人:图标=@绘制/ ic_launcher机器人:标签=@字符串/ APP_NAME机器人:名字=MyApp的>
    <活动机器人:MainActivityNAME =机器人:launchMode =singleTask机器人:标签=@字符串/ APP_NAME>
        &所述;意图滤光器>
            <作用机器人:名字=android.intent.action.MAIN/>
            <类机器人:名字=android.intent.category.LAUNCHER/>
        &所述; /意图滤光器>
    < /活性GT;
< /用途>
< /清单>


解决方案

  

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


正确的。


  

我已经添加了以下权限


我会倾权限组,因为这不应该是必要的。


  

此外,这两个清单文件已经得到这部分现在


只有一个呼唤你的 IntentService 可能需要这一点。


  

不应该这样做的工作,这样我可以从我的主要的应用程序通过这个code调用附加的IntentService?


如果说 IntentService 未导出。请确保您的 IntentService 或者一个<意向滤光器> 的android:出口=真正的。我建议去了<意向滤光器> 的路线,所以你可以声明和使用自定义操作字符串,所以你在远离硬编码包和类名客户端应用程序。

下面是两个示例项目目录采用这种基本做法,尽管在我的情况下,通信是基于安全的的ContentProvider ,而不是一个固定 IntentService 。这个概念是一样的,不过,和这些小的调整的话,我希望你在做什么工作得很好。

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>

解决方案

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.

这篇关于允许通过自定义权限两款Android应用程序之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆