无法保持Google Cloud Message的活力

nPn*_*nPn 6 java android google-cloud-messaging

我正在尝试解决gcm超时问题,关于这个主题有很多线程,这里有一个供参考.

建议的解决方法是以比tcp超时短的间隔广播一对意图.

我的实现是创建一个扩展CountDownTimer类的类,并在现有服务中保存该类的实例.这个派生类在完成后重新启动并且服务被标记为STICKY_START,所以一旦启动,我认为它应该每4分钟继续广播意图,但由于某种原因存在间隙,当计数器没有广播时意图和我仍然与GCM服务器失去联系.

两个相关的课程如下.任何人都可以解释并提供一个解决方案,为什么这个策略不起作用?

我创建了一个扩展CounDownTimer的类,它应该每4分钟广播一次意图.

public class GcmKeepAlive extends CountDownTimer {

    protected CountDownTimer timer;
    protected Context mContext;
    protected Intent gTalkHeartBeatIntent;
    protected Intent mcsHeartBeatIntent;


    public GcmKeepAlive(Context context) {
        super(4*60* 1000,4*60*1000);
        mContext = context;
        gTalkHeartBeatIntent = new Intent("com.google.android.intent.action.GTALK_HEARTBEAT");
        mcsHeartBeatIntent = new Intent("com.google.android.intent.action.MCS_HEARTBEAT");
        System.out.println("stariing heartbeat countdown timer");
        this.start();
    }


    @Override
    public void onTick(long millisUntilFinished) {

    }

    @Override
    public void onFinish() {
        System.out.println("sending heart beat to keep gcm alive");
        mContext.sendBroadcast(gTalkHeartBeatIntent);
        mContext.sendBroadcast(mcsHeartBeatIntent);
        this.start();

    }

}
Run Code Online (Sandbox Code Playgroud)

这是我的应用程序中的服务,它包含GcmKeepAlive类的实例

import android.app.Service; import android.content.Intent; import android.os.IBinder;

public class LocationMonitorService extends Service {

    private DeviceLocationClient deviceLocationClient;
    private GcmKeepAlive gcmKeepAlive;

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        System.out.println("creating the LocationMonitorService");
        deviceLocationClient = new DeviceLocationClient(this);
        gcmKeepAlive = new GcmKeepAlive(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        System.out.println("inside service making request for location updates");
        deviceLocationClient.requestLLocationUpdates();
        gcmKeepAlive.start();
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }


}
Run Code Online (Sandbox Code Playgroud)

这是一个在logcat中看到的间隙的例子.

07-13 14:59:05.583 I/System.out(21651): sending heart beat to keep gcm alive
07-13 15:03:05.640 I/System.out(21651): sending heart beat to keep gcm alive
07-13 15:07:05.776 I/System.out(21651): sending heart beat to keep gcm alive
07-13 15:11:05.922 I/System.out(21651): sending heart beat to keep gcm alive
07-13 15:27:31.994 I/System.out(21651): sending heart beat to keep gcm alive
Run Code Online (Sandbox Code Playgroud)

nPn*_*nPn 4

我实际上前段时间已经解决了这个问题,Erik Z 最近的评论仍然是我发布我的解决方案。

我通过创建一个触发广播的重复警报来解决这个问题,广播创建并广播意图。这些间隙由于原始服务被终止然后由于 START_STICKY 标志而重新启动造成的。

这是各个部分(从各个文件中提取)

至少在奇巧之前是需要的,我不知道是否仍然需要,我想是的。不过我还没有关闭它来确认。


警报管理器、意图和待处理意图。

AlarmManager alarmManager = (AlarmManager) Context.getSystemService(Context.ALARM_SERVICE);

Intent gcmKeepAliveIntent = new Intent("com.gmail.npnster.ourlatitude.gcmKeepAlive");

PendingIntent gcmKeepAlivePendingIntent = PendingIntent.getBroadcast(mContext, 0, gcmKeepAliveIntent, PendingIntent.FLAG_CANCEL_CURRENT);

alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, 4*60*1000, gcmKeepAlivePendingIntent);
Run Code Online (Sandbox Code Playgroud)

广播接收器:

public class GcmKeepAliveBroadcastReceiver extends BroadcastReceiver {

    private GcmKeepAlive gcmKeepAlive;

    @Override
    public void onReceive(Context context, Intent intent) {
        MyLog.p(this,"inside gcm keep alive receiver");
        gcmKeepAlive = new GcmKeepAlive(context);
        gcmKeepAlive.broadcastIntents();

    }

}
Run Code Online (Sandbox Code Playgroud)

发送保活广播的保活类。

public class GcmKeepAlive  {

    protected Context mContext;
    protected Intent gTalkHeartBeatIntent;
    protected Intent mcsHeartBeatIntent;

    public GcmKeepAlive(Context context) {
        mContext = context;
        gTalkHeartBeatIntent = new Intent(
                "com.google.android.intent.action.GTALK_HEARTBEAT");
        mcsHeartBeatIntent = new Intent(
                "com.google.android.intent.action.MCS_HEARTBEAT");  
    }

    public void broadcastIntents() {
        MyLog.p(this,"sending heart beat to keep gcm alive");
        mContext.sendBroadcast(gTalkHeartBeatIntent);
        mContext.sendBroadcast(mcsHeartBeatIntent);
    }

}
Run Code Online (Sandbox Code Playgroud)