来自GCMIntentService的onRegistered()从未被调用过

And*_*oid 7 android google-cloud-messaging

我想在GCM上注册我的应用程序,但我不知道为什么我的应用程序从未注册.GCMRegistrar.register(this, SENDER_ID);被调用但我的GCMIntentService中的onRegistered()从未被调用过.我不知道为什么.

这是我的Logcat

01-17 11:03:00.015: D/GCMRegistrar(3509): resetting backoff for com.abc.xyz.ui.activity
01-17 11:03:03.210: V/GCMRegistrar(3509): Registering app com.abc.xyz.ui.activity of senders 964256581311
01-17 11:03:06.070: V/GCMBroadcastReceiver(3509): onReceive: com.google.android.c2dm.intent.REGISTRATION
01-17 11:03:06.070: V/GCMBroadcastReceiver(3509): GCM IntentService class: com.abc.xyz.ui.activity.GCMIntentService
01-17 11:03:06.070: V/GCMBaseIntentService(3509): Acquiring wakelock
Run Code Online (Sandbox Code Playgroud)

这是我的完整清单

    <?xml version="1.0" encoding="utf-8"?>
<manifest package="com.abc.xyz.ui.activity"
    android:versionCode="1"
    android:versionName="1.5.6" xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-sdk 
        android:minSdkVersion="11" android:targetSdkVersion="16"/>
    <uses-feature 
        android:name="android.hardware.usb.host"/>

    <!-- This app has permission to register and receive data message. -->
    <uses-permission
        android:name="com.google.android.c2dm.permission.RECEIVE" />

    <uses-permission 
        android:name="android.permission.INTERNET" />
    <uses-permission 
        android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission 
        android:name="android.permission.GET_TASKS" />
    <uses-permission 
        android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission
        android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission 
        android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission 
        android:name="android.permission.CALL_PHONE" /> 
    <uses-permission 
        android:name="android.permission.BLUETOOTH" />

    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 

    <!--
     Creates a custom permission so only this app can receive its messages.

     NOTE: the permission *must* be called PACKAGE.permission.C2D_MESSAGE,
           where PACKAGE is the application's package name.
    -->
    <uses-permission
        android:name="com.abc.xyz.ui.activity.permission.C2D_MESSAGE" />   
    <permission
        android:name="com.abc.xyz.ui.activity.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" 
        android:theme="@android:style/Theme.Holo.Light" 
        android:name="com.abc.xyz.MyApplication" 
        android:allowBackup="false">
        <activity
            android:name=".StartupActivity"
            android:noHistory="true"
            android:label="@string/title_startup_screen" 
            android:configChanges="orientation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".LoginActivity"
            android:windowSoftInputMode="stateAlwaysVisible|adjustResize"
            android:label="@string/title_login_screen"
            android:configChanges="orientation">
        </activity>
        //my other activity defination

        <!--
          BroadcastReceiver that will receive intents from GCM
          services and handle them to the custom IntentService.

          The com.google.android.c2dm.permission.SEND permission is necessary
          so only GCM services can send data messages for the app.
        -->
        <receiver
            android:name="com.google.android.gcm.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <!-- Receives the actual messages. -->
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <!-- Receives the registration id. -->
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.abc.xyz.ui.activity" />
            </intent-filter>
        </receiver>

        <!--
          Application-specific subclass of GCMBaseIntentService that will
          handle received messages.

          By default, it must be named .GCMIntentService, unless the
          application uses a custom BroadcastReceiver that redefines its name.
        -->
        <service android:name="com.abc.xyz.ui.activity.GCMIntentService" />

    </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

我不知道出了什么问题,为什么onRegistered()永远不会被调用.任何帮助将不胜感激.

Rap*_*ira 10

我在另一篇文章中想出了什么问题.我的GCMIntentService类在我的清单中定义为

<service android:name="MY_PACKAGE.gcm.GCMIntentService" />
Run Code Online (Sandbox Code Playgroud)

因为我不想把这个类放在root包中,而是把它放在MY_PACKAGE.gcm".这似乎引起了一个问题,正如文档所说,

添加以下意图服务

<service android:name=".GCMIntentService" />
Run Code Online (Sandbox Code Playgroud)

所以,当我转移到root包时,它工作了!还有另一种方法可以将GCMIntentServiceSubclass放在任何位置,并以不同的方式命名.您应该将GCMBroadcastReceiver子类化,并在清单和子类中进行更改,如此其他帖子所示.


War*_*ith 2

我回答是因为在注释中粘贴代码几乎难以阅读:

我从你的 logcat 中丢失了一些日志,这些日志表明你的服务甚至被调用了。注册时我的 Logcat 中有这个:

GCMBroadcastReceiver  V  onReceive: com.google.android.c2dm.intent.REGISTRATION
GCMBroadcastReceiver  V  GCM IntentService class: com.package.android.app.GCMIntentService
GCMBaseIntentService  V  Acquiring wakelock
GCMBaseIntentService  V  Intent service name: GCMIntentService-DynamicSenderIds-1
Run Code Online (Sandbox Code Playgroud)

特别是最后一行丢失或者您忘记粘贴它。您能确保您发布了完整的 LogCat 吗?进行筛选以GCM确保您没有错过任何内容。

更新

正如OP在评论中提到的,他使用该服务做了更多事情。这在某种程度上干扰了 GCM 功能,将其分成两个服务后它就可以工作了。经验教训:不要将 GCMIntentService 用于 GCM 以外的任何其他用途。

  • 我很好奇为什么你的清单中有包“com.abc.xyz.ui.activity”,但应用程序包却有“com.abc.xyz”。我不确定这是否会造成任何麻烦。GCMIntentService 需要位于一个非常特定的位置,通常您会使用根包,但由于您的清单包是应用程序包的子包......这很不寻常。 (2认同)