繁体   English   中英

Android GCM Intent Service在释放Wakelock时陷入困境

[英]Android GCM Intent Service got stuck at Releasing Wakelock

我正在使用GCM进行项目的推送通知,但仍无法释放唤醒锁。 我正在使用Android Hive中的GCM代码。

以下是我的清单文件。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.estorm.filingotp"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="18" />

<uses-permission android:name="android.permission.INTERNET"/>  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
 <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<permission
    android:name="com.estorm.filingotp.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.estorm.filingotp.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<permission
    android:name="com.estorm.filingotp.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.estorm.filingotp.permission.C2D_MESSAGE" />

 <application
    android:allowBackup="true"
    android:icon="@drawable/otp_appicon"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Light.NoTitleBar" >

      <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.estorm.filingotp" />
        </intent-filter>
    </receiver>

    <service android:name=".GCMIntentService" />

我的推力很好,但日志猫卡在了释放Wavelock上。 而且我没有在应用启动时使用GCM。 我在应用程序的中间调用GCM。 我呼叫GCM和GCM意向服务的类都在相同的程序包名称下。 我的应用程序有很多软件包,例如Packagename.constants,Packagename.utils等。

请帮我。 我坚持了两天。

这是我的GCM意向服务代码

    package com.estorm.filingotp;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.estorm.filingotp.constants.Globals;
import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService {

    private static final String TAG = "Test";
    public static final String SENDER_ID = "401189754081";
    public static final String DISPLAY_MESSAGE_ACTION = "com.estorm.filingotp.OTPLogon";
    public static final String EXTRA_MESSAGE = "message";

    Context ctx;
    public GCMIntentService() {
        super(GCMIntentService.SENDER_ID);
    }

    @Override
    protected void onRegistered(Context context, final String registrationId) {

        Log.v("", "Device registered: PUSHId = " + registrationId);


    }

    @Override
    protected void onUnregistered(Context context, String registrationId) {
        Log.i(TAG, "Device unregistered");
        // CommonUtilities.displayMessage(context,
        // getString(R.string.gcm_unregistered));
        // if (GCMRegistrar.isRegisteredOnServer(context)) {
        // ServerUtilities.unregister(context, registrationId);
        // } else {
        // Log.i(TAG, "Ignoring unregister callback");
        // }
    }

    @Override
    protected void onMessage(Context context, Intent intent) {
        Log.v("", "Received message");
        Log.v("", "message is" + intent.getExtras().getString("message"));
        ctx = context;
        String other_key = intent.getExtras().getString("message");
        Globals.IPtoken=other_key;
        generateNotification(context, other_key);
    }


    @Override
    protected void onDeletedMessages(Context context, int total) {
        Log.i(TAG, "Received deleted messages notification");
        // String message = getString(R.string.gcm_deleted, total);
        // CommonUtilities.displayMessage(context, message);
        // generateNotification(context, message);
    }

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

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

    @SuppressWarnings("deprecation")
    private static void generateNotification(Context context, String message) {
        int icon = R.drawable.otp_appicon;
        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, OTPLogon.class);
        notificationIntent.putExtra("message", message);

        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(context, 0,
                notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        notification.setLatestEventInfo(context, message,
                message, intent);

        notification.defaults = Notification.DEFAULT_ALL;
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(0, notification);

    }
    }

我使用以下代码在Activity类中调用GCM

    private void gcm(final Context context) {
        GCMRegistrar.checkDevice(context);
        GCMRegistrar.checkManifest(context);

    registerReceiver(mHandleMessageReceiver, new IntentFilter(
            GCMIntentService.DISPLAY_MESSAGE_ACTION));
    Globals.RegistrationId = GCMRegistrar.getRegistrationId(context);
    Log.v("","reg uid is"+Globals.RegistrationId);

    if (Globals.RegistrationId.equals("")) {

        GCMRegistrar.register(context, GCMIntentService.SENDER_ID);

    } else {
        if (GCMRegistrar.isRegisteredOnServer(context)) {
            Log.v("", "GCM Display Message : "
                    + "Already registered");
        }
    }

}
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
//      String newMessage = intent.getExtras().getString(
//              GCMIntentService.EXTRA_MESSAGE);
        Log.v("", "broadcast done");
        new Apiconnector().execute();
    }
};

您可以这样进行:通过Intent Service扩展GCMIntentService

public class GcmIntentService extends IntentService{
Context context;
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public static final String TAG = "GCM Demo";

public GcmIntentService() {
    super("GcmIntentService");
    // TODO Auto-generated constructor stub
}

@Override
protected void onHandleIntent(Intent intent) {
    // TODO Auto-generated method stub
    Bundle extras = intent.getExtras();
    String msg = intent.getStringExtra("message");
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    String messageType = gcm.getMessageType(intent);

     if (!extras.isEmpty()) {

         if (GoogleCloudMessaging.
                    MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_DELETED.equals(messageType)) {
                sendNotification("Deleted messages on server: " +
                        extras.toString());
            // If it's a regular GCM message, do some work.
            } else if (GoogleCloudMessaging.
                    MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                // This loop represents the service doing some work.
                for (int i=0; i<5; i++) {
                    Log.i(TAG, "Working... " + (i+1)
                            + "/5 @ " + SystemClock.elapsedRealtime());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                    }
                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                // Post notification of received message.
                //sendNotification("Received: " + extras.toString());
                sendNotification(msg);
                Log.i(TAG, "Received: " + extras.toString());
            }
        }
     GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
    mNotificationManager = (NotificationManager)
            this.getSystemService(Context.NOTIFICATION_SERVICE);

    Intent myintent = new Intent(this, ReceiveActivity.class);
    myintent.putExtra("message", msg);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            myintent, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.ic_stat_gcm)
    .setContentTitle("GCM Notification")
    .setStyle(new NotificationCompat.BigTextStyle()
    .bigText(msg))
    .setContentText(msg);

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    mNotificationManager.cancel(NOTIFICATION_ID);
}

}

GCMBroadCastReceiver看起来像

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub

    // Explicitly specify that GcmIntentService will handle the intent.
    ComponentName comp = new ComponentName(context.getPackageName(),
            GcmIntentService.class.getName());
    // Start the service, keeping the device awake while it is launching.
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);


}

}

我查看了本教程 希望这对您有帮助

您必须使用completeWakefulIntent(intent)才能释放唤醒锁。 您必须将意图作为参数传递,该意图与WakefulBroadcastReceiver最初传入的意图相同。

这是示例代码:

import android.app.IntentService;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;

public class SimpleWakefulService extends IntentService {
    public SimpleWakefulService() {
        super("SimpleWakefulService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point SimpleWakefulReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.  This sample just does some slow work,
        // but more complicated implementations could take their own wake
        // lock here before releasing the receiver's.
        //
        // Note that when using this approach you should be aware that if your
        // service gets killed and restarted while in the middle of such work
        // (so the Intent gets re-delivered to perform the work again), it will
        // at that point no longer be holding a wake lock since we are depending
        // on SimpleWakefulReceiver to that for us.  If this is a concern, you can
        // acquire a separate wake lock here.
        for (int i=0; i<5; i++) {
            Log.i("SimpleWakefulReceiver", "Running service " + (i+1)
                    + "/5 @ " + SystemClock.elapsedRealtime());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }
        }
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM