【问题标题】:Share library project's manifest services and permissions共享库项目的清单服务和权限
【发布时间】:2014-04-12 00:24:48
【问题描述】:

我想开发一个包含 GCMIntentService 的库项目,它执行 GCM 注册过程并接收通过 GCM 发送的消息。

我已经使用 AIDL 将我的库项目服务公开给宿主应用程序,但我还需要在应用程序项目中声明该服务.....如何避免这种情况?
此外,我还需要在应用程序清单中声明 GCM 所需的所有权限。
有什么方法可以从宿主应用程序中引用库项目中的所有权限和服务,而无需在清单中再次声明它们?

我已经搜索过这个并发现:
1.Is it possible encapsulate permission inside Android framework (library)
这清楚地表明我想要实现的目标是不可能的。
2. 有用的东西Library Project does the manifest file merge? @Hayes Haugen 的回答说“ADT 工具的版本 20 支持 AndroidManifest.xml 合并”
我正在使用 ADT 版本 20.0.3

我有没有办法让图书馆项目提供 GCM 集成?

【问题讨论】:

  • 使用 manifestmerger.enabled 属性启用
  • @Leonidos 我的 project.properties 文件中有“manifestmerger.enabled=true”...但是当我使用库项目清单中指定的权限时出现异常。

标签: android google-cloud-messaging android-library aidl android-permissions


【解决方案1】:

你遇到了什么错误?

这对我很有用:

图书馆清单

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

另外,我想知道您使用服务和 AIDL 的解决方案是否过于矫枉过正。我从那条路线开始,但因我的情况下进程间通信的复杂性而被关闭。我已经能够在我的库中简单地定义一个广播接收器和意图服务,在我的应用程序中启动一个意图服务。你只需要小心包名。和组件名称。包名将始终是您应用的包名,但组件名将是您的服务的类名。

【讨论】:

    【解决方案2】:

    我希望这会有所帮助,我遇到了与您类似的问题,但找不到不会导致某些或其他问题的解决方案。我的解决方案是当有人使用我的应用程序构建器时,它会将我的库以及我的 GCMintent 类和 CGM lib 文件的副本放入应用程序中。

    然后系统会自动将权限添加到他的应用程序清单中,并弹出一个新的 apk 供他使用。这就是我们的做法,我希望这可以帮助您找到解决方案。

    【讨论】:

      【解决方案3】:

      看看 UrbanAirship 对该特定问题的解决方案。

      UrbanAirship Android documentation

      特别是Configuring your Client Application部分

      【讨论】:

        【解决方案4】:

        afaik 编译时完全忽略库的清单

        【讨论】:

        • 如果你在项目属性中启用manifestmerger(或使用Gradle,默认合并),它不会被忽略。
        • 在回答时这不能正常工作(对我来说)
        【解决方案5】:

        对于合并部分,我遇到了同样的问题,必须再次从主项目清单中的 lib 项目声明我的服务。

        对于那些manifestmerger 不使用Eclipse 的人(提醒一下,我们的想法是将以下行放在project.properties 中):

        manifestmerger.enabled=true

        ...然后您可能需要清理主项目,以便它可以工作...(菜单 ProjectClean...)

        这听起来很愚蠢,但由于我无法找到修改 project.properties 不起作用的原因,其他人可能也遇到了同样的问题。

        您可以通过检查文件bin/AndroidManifest.xml 来检查合并是否正确完成。

        【讨论】:

          猜你喜欢
          • 2012-07-17
          • 2018-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多