Próbuję obejść problem z limitem czasu GCM, istnieje wiele wątków na ten temat, tutaj jest one w celach informacyjnych.Problemy z utrzymaniem Google Cloud Message przy życiu
Proponowane obejście polega na emisji pary intencji w odstępie krótszym niż limit czasu tcp.
Moja implementacja polega na utworzeniu klasy, która rozszerza klasę CountDownTimer i zatrzymuje instancję tej klasy w istniejącej usłudze. Ta wyprowadzona klasa uruchamia się ponownie po jej zakończeniu, a usługa jest oznaczona jako STICKY_START, więc po uruchomieniu, powinienem uważać, że powinna ona nadal nadawać intencje co 4 minuty, ale z jakiegoś powodu istnieją luki, gdy licznik nie nadaje zamiary i nadal tracę kontakt z serwerem GCM.
Dwie odpowiednie klasy znajdują się poniżej. Czy ktoś może wyjaśnić i zaoferować rozwiązanie, dlaczego ta strategia nie działa?
Stworzyłem klasę rozszerzającą CounDownTimer, która powinna nadawać intencje co 4 minuty.
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();
}
}
tutaj jest usługa w mojej aplikacji, która posiada instancję klasy 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;
}
}
Oto przykład luki widziany w 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
Tutaj przykład zastosowania ma znaczenie. Pozostajesz w aplikacji, gdy tak się dzieje, czy aplikacja jest zminimalizowana? System może zabić proces aplikacji, jeśli aplikacja nie jest na pierwszym planie, a START_STICKY nie będzie miało znaczenia, jeśli tak się stanie. Użyj usługi startForeground w usłudze http://developer.android.com/reference/android/app/Service.html # startForeground (int,% 20android.app.Notification), jeśli chcesz zagwarantować, że nie zostanie zabity. –
@ErikZ Dzięki za komentarz. Rozwiązałem to chwilę, używając menedżera alarmów. Poniżej zamieściłem moje rozwiązanie, ale usługa polegająca na zabijaniu zdecydowanie zepsuła luki. – nPn
Nie działa na moim notebooku Samsung Note 4, ale działa doskonale na wszystkich innych sprawdzanych urządzeniach (około 10 różnych urządzeń). – FunkSoulBrother