Android 是否可以模拟从adb shell/am命令行接收GCM?I';我犯了一个错误

Android 是否可以模拟从adb shell/am命令行接收GCM?I';我犯了一个错误,android,Android,我试图通过使用adb和命令行模拟设备是否正在接收GCM推送消息。我已尝试此命令来广播GCM意图: adb shell am broadcast -c com.myapp -a com.google.android.c2dm.intent.RECEIVE -e data "SomeData" 这会触发“权限拒绝”日志行,但: 09-19 12:23:34.820 725-787/? W/BroadcastQueue﹕ Permission Denial: broadcasting In

我试图通过使用adb和命令行模拟设备是否正在接收GCM推送消息。我已尝试此命令来广播GCM意图:

adb shell am broadcast -c com.myapp -a com.google.android.c2dm.intent.RECEIVE -e data "SomeData"
这会触发“权限拒绝”日志行,但:

09-19 12:23:34.820      725-787/? W/BroadcastQueue﹕ Permission Denial: broadcasting Intent { act=com.google.android.c2dm.intent.RECEIVE cat=[com.myapp] flg=0x10 (has extras) } from null (pid=21244, uid=2000) requires com.google.android.c2dm.permission.SEND due to receiver com.myapp/com.google.android.gcm.GCMBroadcastReceiver
我的舱单的相关部分:

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application>
<receiver
    android:name="com.google.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" />
        <category android:name="com.myapp" />
    </intent-filter>
</receiver>
</application>

有什么想法吗


编辑/澄清:推送/GCM接收生产中的工作。我正在寻找一种更简单的方法来测试更改。

我建议使用命令行curl,因为发送GCM推送就像调用一些restapi一样简单。请参见下面的示例shell脚本:

#!/bin/bash

REGISTRATION_ID=YOUR_GCM_REGISTRATION_ID

SERVER_KEY=YOUR_SERVER_KEY_FROM_GOOGLE_API_CONSOLE

curl --header "Authorization: key=$SERVER_KEY" --header  Content-Type:"application/json"  https://android.googleapis.com/gcm/send  -d  "{ \"data\" : {\"foo\": \"bar\"}, \"registration_ids\":[\"$REGISTRATION_ID\"]  }"

您需要删除接收方定义中的权限属性,如下所示:

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application>
<receiver
    android:name="com.google.android.gcm.GCMBroadcastReceiver" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="com.myapp" />
    </intent-filter>
</receiver>
</application>

与临时编辑AndroidManifest.xml以删除权限检查并记住稍后恢复权限检查相比,您可以在调试版本中自动禁用权限检查

为此,请通过占位符设置属性:

<receiver
  android:name="com.google.android.gcm.GCMBroadcastReceiver"
  android:permission="${gcmPermissionRequired}">
(注意:之前我使用了调试和发布字符串资源。结果表明,如果Play store使用字符串资源定义了意向过滤器权限,则会拒绝该应用。)

  • 首先安装adb sudo-apt-get-install-adb

  • 从manifest.xml中删除发送权限 android:permission=“com.google.android.c2dm.permission.SEND”>

  • 命令从shell推送通知
  • 亚行壳牌am广播-c com.myapp-a com.google.android.c2dm.intent.RECEIVE-e数据“SomeData”

  • 根据需要更改包名(com.myapp)和“SomeData”
    好提示!另外,您可以从“GoogleCloudMessaging.getInstance(context.register(…)”中获得应用程序中的您的注册ID。我决定再写几句话来说明这一点,对于iOS和Android来说:这是一个很好的解决方案,但不是最优的。如果你离线了怎么办?或者,如果您希望在生成服务器上作为集成测试运行,而不希望将服务器密钥存储在其中,该怎么办?我明白您的观点,但我看不到更好的解决方案-但是,您可以尝试添加第二个接收器(可能仅在某些gradle构建变体中公开)&使用它将消息传递到GCMinentService。仍然-不完美,但只允许您测试如何处理推送。工作!我误解了这一许可。有了这个参数,我们只需要来自具有发送权限的活动的消息,而命令行工具没有这个权限。不确定我是否希望在生产中使用它,但也许我可以为调试构建定制清单。如果有效负载数据是JSON格式的,那么在
    adb shell am broadcast
    命令中正确引用它是一个难题。有关解决方案,请参阅。由于Play store不接受字符串资源技术,因此我将其更改为使用清单合并占位符。如何添加多个键值或一个意图
    buildTypes {
        debug {
            ...
            manifestPlaceholders = [gcmPermissionRequired: ""] // "" => let the GCM BroadcastReceiver accept Intents from 'adb shell am broadcast'
        }
        release {
            ...
            manifestPlaceholders = [gcmPermissionRequired: "com.google.android.c2dm.permission.SEND"]
        }
    }