【问题标题】:Is it possible encapsulate permission inside Android framework (library)是否可以在Android框架(库)中封装权限
【发布时间】:2012-09-25 21:09:49
【问题描述】:

我有一些项目#1,它是库。

例如它适用于 GCM (C2DM) 消息,并在其清单文件中具有权限(my_package.permission.C2D_MESSAGE 和其他)。

我将项目 #1 (lib) 连接到项目 #2(一些应用程序)。

问题:是否可以从项目 #1 为项目 #2 自动激活权限?

【问题讨论】:

    标签: android frameworks permissions


    【解决方案1】:

    暂时没有。如果“library”的意思是“Android library project”,那么将来可能会这样。

    但是,在您的具体情况下,这可能永远不会奏效。一些 GCM 框架类将使用应用程序的包,无论使用 GCM 的代码是否在 Android 库项目中。

    【讨论】:

    • 嗨 CommonsWare ...我想知道是否可以要求对此进行澄清。我有一个使用 GCM 的应用程序(例如,包名“MyApp”)。我很快将需要维护这个应用程序的两个不同版本,所以我正在考虑将“MyApp”变成一个库项目,该项目被另外两个(“MyApp-A”和“MyApp-B”)引用。 MyApp-A 和 -B 必须能够存在于同一设备上,并且彼此独立使用 GCM。为了实现这一点,我认为我必须将 GCM 的东西从 MyApp 中移出并移到 MyApp-A 和 MyApp-B 中,除了包名之外相同。这基本上就是你在这里所说的吗?
    • @Cephron:您的清单条目需要位于 MyApp-A 和 MyApp-B 中。您的 Java 代码可能在库中——我想不出 GCM 中有什么可以排除这种情况。
    • @CommonsWare:我遇到了与 Cephron 描述的情况相同的情况。我在 MyApp-A 的清单中有 GCMBroadcastReceiver 条目,但 onRegistered() 回调没有进来。具体来说,我已经尝试了“MyApp”(库项目)和“MyApp-A”(依赖项目) android: 的名称。我希望你是对的,但你确定没有必要将 GCM 代码移出库并进入每个依赖应用程序吗?谢谢。
    • @Cephron:您能否使用库项目中留下的 GCM 代码完成这项工作?谢谢。
    • @gcl1:我没试过这个。我不知道 GCM 中的任何内容会阻止库项目中的实现,只要应用程序的包名称用于应用程序清单中的内容。如果您无法使其正常工作,您可以尝试android-gcm Google Group。
    【解决方案2】:

    我已经让它与 AndroidStudio 和 mainfestmerging 一起工作。我拥有库项目中的所有 GCM 权限、广播接收器和意图接收器。我的图书馆中的意图服务在我的应用程序中调用了意图服务。在我的例子中,应用程序向库注册此服务名称并将其存储在数据库中,因此库意图服务知道要为应用程序使用哪个意图。我的应用程序中的任何地方都没有 GCM 代码或权限。这是我的图书馆清单

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="org.plasync.client.android"
              android:versionCode="1"
              android:versionName="1.0">
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <uses-permission android:name="android.permission.INTERNET" />
        <!-- Needed for devices with 4.02 or earlier android -->
        <uses-permission android:name="android.permission.GET_ACCOUNTS" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />
        <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
        <permission android:name="org.plasync.client.android.permission.C2D_MESSAGE"
            android:protectionLevel="signature" />
        <uses-permission android:name="org.plasync.client.android.permission.C2D_MESSAGE" />
       <!-- <uses-permission android:name="com.playsnc.client.android.data.permission.READ_WRITE"/>-->
    
        <application android:label="" android:icon="@drawable/ic_launcher">
            <!-- This is the signin activity for plAsync -->
            <activity android:name="org.plasync.client.android.AsyncMultiplayerSetupActivity"
                      android:label="@string/SETUP_ACTIVITY_NAME"
                      android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
    
                <!-- This is the intent for getting the local user.  Apps that use plAsync must use this
                     intent to retrieve the local user, or allow the user to signin.  Apps should
                     use startActivityForResult as the sigin activity may require user interaction -->
                <intent-filter>
                    <action android:name="@string/SETUP_ASYNC_MULTIPLAYER_SESSION_ACTION"/>
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>
    
            <receiver android:name="org.plasync.client.android.gcm.GcmBroadcastReceiver"
                      android:permission="com.google.android.c2dm.permission.SEND" >
                <intent-filter>
                    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                </intent-filter>
            </receiver>
    
            <service android:name="org.plasync.client.android.gcm.GcmReceiveIntentLauncher"/>
        </application>
    </manifest>
    

    这是我的应用程序清单

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="org.plasync.client.android.testapp"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="11"
            android:targetSdkVersion="17" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
            <activity
                android:name="org.plasync.client.android.testapp.AsyncMultiplayerTestAppActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <activity android:name=".search.FriendSearchActivity"
                      android:launchMode="singleTop">
                <intent-filter>
                    <action android:name="android.intent.action.SEARCH" />
                </intent-filter>
                <meta-data android:name="android.app.searchable"
                    android:resource="@xml/searchable"/>
            </activity>
    
            <service android:name=".AsyncMultiplayerTestAppMessageReceiver"/>
        </application>
    
    </manifest>
    

    正如 CommonsWare 所指出的,你必须小心你的包。您的意图服务(库或应用程序)的 ComponentName 包始终是应用程序包,正如我的 BroadcastReceiver 的代码所示。

    public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Explicitly specify that GcmIntentService will handle the intent.
            ComponentName receiveIntentLauncherComponent =
                    new ComponentName(context.getPackageName(),
                                      GcmReceiveIntentLauncher.class.getName());
            // Start the service, keeping the device awake while it is launching.
            startWakefulService(context, (intent.setComponent(receiveIntentLauncherComponent)));
            setResultCode(Activity.RESULT_OK);
        }
    }
    

    另外,请注意您不能使用 Google BroadcastReceiver;您需要如上所述定义自己的。原则上我可以从广播接收器启动应用意图,但由于我从数据库中获取应用意图名称,因此不建议在广播接收器中执行此类操作。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-08-08
      • 1970-01-01
      • 2012-09-04
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2014-10-16
      相关资源
      最近更新 更多