我建议你使用这些:
AlarmManager
, PowerManager
, WakeLock
, Thread
, WakefulBroadcastReceiver
, Handler
,Looper
我假设您已经在使用那些“单独的过程”和其他调整。
所以在你的Application
课上:
MyApp.java
:
import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.Log;
public final class MyApp extends Application{
public static PendingIntent pendingIntent = null;
public static Thread infiniteRunningThread;
public static PowerManager pm;
public static PowerManager.WakeLock wl;
@Override
public void onCreate(){
try{
Thread.setDefaultUncaughtExceptionHandler(
(thread, e)->restartApp(this, "MyApp uncaughtException:", e));
}catch(SecurityException e){
restartApp(this, "MyApp uncaughtException SecurityException", e);
e.printStackTrace();
}
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if(pm != null){
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
wl.acquire(10 * 60 * 1000L /*10 minutes*/);
}
infiniteRunningThread = new Thread();
super.onCreate();
}
public static void restartApp(Context ctx, String callerName, Throwable e){
Log.w("TAG", "restartApp called from " + callerName);
wl.release();
if(pendingIntent == null){
pendingIntent =
PendingIntent.getActivity(ctx, 0,
new Intent(ctx, ActivityMain.class), 0);
}
AlarmManager mgr = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
if(mgr != null){
mgr.set(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + 10, pendingIntent);
}
if(e != null){
e.printStackTrace();
}
System.exit(2);
}
}
然后为您服务:
ServiceTrackerTest.java
:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
public class ServiceTrackerTest extends Service{
private static final int SERVICE_ID = 2018;
private static PowerManager.WakeLock wl;
@Override
public IBinder onBind(Intent intent){
return null;
}
@Override
public void onCreate(){
super.onCreate();
try{
Thread.setDefaultUncaughtExceptionHandler(
(thread, e)->MyApp.restartApp(this,
"called from ServiceTracker onCreate "
+ "uncaughtException:", e));
}catch(SecurityException e){
MyApp.restartApp(this,
"called from ServiceTracker onCreate uncaughtException "
+ "SecurityException", e);
e.printStackTrace();
}
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if(pm != null){
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
wl.acquire(10 * 60 * 1000L /*10 minutes*/);
}
Handler h = new Handler();
h.postDelayed(()->{
MyApp.infiniteRunningThread = new Thread(()->{
try{
Thread.setDefaultUncaughtExceptionHandler(
(thread, e)->MyApp.restartApp(this,
"called from ServiceTracker onCreate "
+ "uncaughtException "
+ "infiniteRunningThread:", e));
}catch(SecurityException e){
MyApp.restartApp(this,
"called from ServiceTracker onCreate uncaughtException "
+ "SecurityException "
+ "infiniteRunningThread", e);
e.printStackTrace();
}
Looper.prepare();
infiniteRunning();
Looper.loop();
});
MyApp.infiniteRunningThread.start();
}, 5000);
}
@Override
public void onDestroy(){
wl.release();
MyApp.restartApp(this, "ServiceTracker onDestroy", null);
}
@SuppressWarnings("deprecation")
@Override
public int onStartCommand(Intent intent, int flags, int startId){
if(intent != null){
try{
WakefulBroadcastReceiver.completeWakefulIntent(intent);
}catch(Exception e){
e.printStackTrace();
}
}
startForeground(SERVICE_ID, getNotificationBuilder().build());
return START_STICKY;
}
private void infiniteRunning(){
//do your stuff here
Handler h = new Handler();
h.postDelayed(this::infiniteRunning, 300000);//5 minutes interval
}
@SuppressWarnings("deprecation")
private NotificationCompat.Builder getNotificationBuilder(){
return new NotificationCompat.Builder(this)
.setContentIntent(MyApp.pendingIntent)
.setContentText(getString(R.string.notification_text))
.setContentTitle(getString(R.string.app_name))
.setLargeIcon(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher))
.setSmallIcon(R.drawable.ic_stat_tracking_service);
}
}
忽略“弃用”之类的东西,别无选择时使用它们。我认为代码很清楚,不需要解释。这只是关于解决方法的建议和解决方案。