[英]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.