Code gets stuck at acquiring wake lock while regis

2019-02-26 01:39发布

问题:

I am using GCM for push notifications for my project, but am stuck at acquiring wake lock.

Log message:

09-03 17:04:05.003: V/GCMBroadcastReceiver(5772): onReceive:com.google.android.c2dm.intent.REGISTRATION
09-03 17:04:05.003: V/GCMBroadcastReceiver(5772): GCM IntentService class: example.pro.GCMIntentService
09-03 17:04:05.049: V/GCMBaseIntentService(5772): Acquiring wakelock

Below is my manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="example.pro"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- 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. -->
    <permission
        android:name="example.pro.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="example.pro.permission.C2D_MESSAGE" />
    <!-- This app has permission to register and receive data message. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <!-- Network State Permissions to detect Internet status -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- Permission to vibrate -->
    <uses-permission android:name="android.permission.VIBRATE" />
    <application
        android:name="com.thinkappz.advancedtictactoe.FriendPickerApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar" >
        <activity
            android:name="com.thinkappz.advancedtictactoe.Splash"
            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="com.google.ads.AdActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
        <activity
            android:name="com.thinkappz.advancedtictactoe.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name=".MainActivity" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.GcmMainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name=".GcmMainActivity" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.NewGame"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.NewGame" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.Vs_Facebook"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.Vs_Facebook" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.RandomPlayer"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.RandomPlayer" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.Register"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.Register" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.RegisterActivity" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.SendRequest"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.SendRequest" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.PickFriendsActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.PickFriendsActivity" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.getFinishedGames"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.getFinishedGames" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.thinkappz.advancedtictactoe.HomeScreen"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="example.pro.HomeScreen" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/app_id" />
        <activity android:name="com.facebook.LoginActivity" />
        <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="example.pro" />
            </intent-filter>
        </receiver>
        <service android:name="com.thinkappz.advancedtictactoe.GCMIntentService" />
    </application>
</manifest>

GCMIntentService----> This class file is inside com.thinkappz.advancedtictactoe package, but my R.java file is generated inside example.pro. I don't know why.

package com.thinkappz.advancedtictactoe;

import javax.management.Notification;

public class GCMIntentService extends GCMBaseIntentService {

    private static final String TAG = "GCMIntentService";

    public GCMIntentService() {
        super(SENDER_ID);
    }

    /**
     * Method called on device registered
     **/
    @Override
    protected void onRegistered(Context context, String registrationId) {
        Log.i(TAG, "Device registered: regId = " + registrationId);
        displayMessage(context, "Your device registred with GCM");
        Log.d("NAME", GcmMainActivity.name);
        ServerUtilities.register(context, GcmMainActivity.name,
            GcmMainActivity.email, registrationId);
    }

    /**
     * Method called on device un registred
     * */
    @Override
    protected void onUnregistered(Context context, String registrationId) {
        Log.i(TAG, "Device unregistered");
        displayMessage(context, getString(R.string.gcm_unregistered));
        ServerUtilities.unregister(context, registrationId);
    }

    /**
     * Method called on Receiving a new message
     * */
    @Override
    protected void onMessage(Context context, Intent intent) {
        Log.i(TAG, "Received message");
        String message = intent.getExtras().getString("price");
        displayMessage(context, message);
        // notifies user
        generateNotification(context, message);
    }

    /**
     * Method called on receiving a deleted message
     * */
    @Override
    protected void onDeletedMessages(Context context, int total) {
        Log.i(TAG, "Received deleted messages notification");
        String message = getString(R.string.gcm_deleted, total);
        displayMessage(context, message);
        // notifies user
        generateNotification(context, message);
    }

    /**
     * Method called on Error
     * */
    @Override
    public void onError(Context context, String errorId) {
        Log.i(TAG, "Received error: " + errorId);
        displayMessage(context, getString(R.string.gcm_error, errorId));
    }

    @Override
    protected boolean onRecoverableError(Context context, String errorId) {
        // log message
        Log.i(TAG, "Received recoverable error: " + errorId);
        displayMessage(context,
            getString(R.string.gcm_recoverable_error, errorId));
        return super.onRecoverableError(context, errorId);
    }

    /**
     * Issues a notification to inform the user that server has sent a message.
     */
    private static void generateNotification(Context context, String message) {
        int icon = R.drawable.ic_launcher;
        long when = System.currentTimeMillis();
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = new Notification(icon, message, when);
        String title = context.getString(R.string.app_name);
        Intent notificationIntent = new Intent(context, MainActivity.class);
        // set intent so it does not start a new activity
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
            | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(context, 0,
            notificationIntent, 0);
        notification.setLatestEventInfo(context, title, message, intent);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        // Play default notification sound
        notification.defaults |= Notification.DEFAULT_SOUND;
        // notification.sound = Uri.parse("android.resource://" +
        // context.getPackageName() + "your_sound_file_name.mp3");
        // Vibrate if vibrate is enabled
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        notificationManager.notify(0, notification);
    }
}

I also tried <service android:name="example.pro.GCMIntentService" /> But then it is giving me an error while registering, saying that it can't instantiate service.

回答1:

You are using the com.google.android.gcm.GCMBroadcastReceiver broadcast receiver from the Google GCM client library. This class expects the intent service to be in the main package of your app (example.pro) but your intent service is in a different package - com.thinkappz.advancedtictactoe. That's why the receiver can't find the service.

You should either move the GCMIntentService to the main package of your app, or override GCMBroadcastReceiver.