为什么我的前台服务被Android系统杀死?

问题描述

我的应用程序是一个跟踪应用程序,我想在其中跟踪服务中的用户位置,然后显示片段中的每个位置。 我的后台服务有问题:几分钟后(有时 30分钟),我的服务停止了。 我在这个片段中启动了位置服务,使用我的应用程序后一切正常。 问题是当我关闭(而不是终止)我的应用程序并在手机上启动其他功能(或只是阻止它)时,几分钟后我的服务停止了,我不知道为什么。 当我的服务正在运行时,我会显示一个前台通知,但android系统仍然会停止它,我注意到这一点是因为我的通知消失了,我的应用程序重新启动了。

这是我的服务代码

public class LocationService extends Service {

private static final String TAG = "LocationService";
public static final String NEW_VALUE_INTENT_ACTION = "service_new_value";
public static final String INTENT_LATITUDE = "latitude";
public static final String INTENT_LONGITUDE = "longitude";
public static final String INTENT_SPEED = "speed";
public static final String INTENT_ACCURACY = "accuracy";
private static final long TWO_MINUTES = 1000 * 60 * 2;
private static final long INTERVAL = 5000;
private static final long FASTEST_INTERVAL = 2000;
private int ONGOING_NOTIFICATION = 1111;

private Location currentLocation;
NotificationCompat.Builder builder = null;

private LocationRequest mLocationRequest;

/**
 * Provides access to the Fused Location Provider API.
 */
private FusedLocationProviderClient mFusedLocationClient;

/**
 * Callback for changes in location.
 */
private LocationCallback mLocationCallback;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    Log.d(LocationService.TAG,"LocationService ---> onCreate()");
    super.onCreate();
}

@Override
public void onDestroy() {
    Log.d(LocationService.TAG,"LocationService ---> onDestroy()");
    super.onDestroy();
    stopForeground(true);
     mFusedLocationClient.removeLocationUpdates(mLocationCallback);

}

@Override
public int onStartCommand(Intent intent,int flags,int startId) {
    Log.d(LocationService.TAG,"LocationService ---> onStartCommand()");
    startServiceTask();
    return super.onStartCommand(intent,flags,startId);
}

@Override
public boolean onUnbind(Intent intent) {
    Log.d(LocationService.TAG,"LocationService ---> onUnbind()");
    return super.onUnbind(intent);
}

private void startServiceTask() {
    Log.d(LocationService.TAG,"GpsService ---> Starting ...");

    setServiceAsForeground();

    initFusedLocationProvider();

    Log.d(LocationService.TAG,"MyStartedService ---> Starting ...");


}

private void initFusedLocationProvider() {
    mFusedLocationClient = new FusedLocationProviderClient(this);

    mLocationRequest = new LocationRequest();

    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

    mFusedLocationClient.requestLocationUpdates(mLocationRequest,mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);
            if (currentLocation == null)
                currentLocation = locationResult.getLastLocation();

            else if (isBetterLocation(locationResult.getLastLocation(),currentLocation)) {
                Log.d(TAG,"onLocationChanged(): Updating Location ... " + currentLocation.getProvider());
                currentLocation = locationResult.getLastLocation();
        }
            notifyValueUpdate();
    } },getMainLooper());
}


protected boolean isBetterLocation(Location location,Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return true;
    }

    // Check whether the new location fix is newer or older
    long timedelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timedelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timedelta < -TWO_MINUTES;
    boolean isNewer = timedelta > 0;

    // If it's been more than two minutes since the current location,use
    // the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return true;
        // If the new location is more than two minutes older,it must be
        // worse
    } else if (isSignificantlyOlder) {
        return false;
    }

    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
            .getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),currentBestLocation.getProvider());

    // Determine location quality using a combination of timeliness and
    // accuracy
    if (isMoreAccurate) {
        return true;
    } else if (isNewer && !isLessAccurate) {
        return true;
    } else if (isNewer && !isSignificantlyLessAccurate
            && isFromSameProvider) {
        return true;
    }
    return false;
}

/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1,String provider2) {
    if (provider1 == null) {
        return provider2 == null;
    }
    return provider1.equals(provider2);
}

private void setServiceAsForeground() {
    Log.d(LocationService.TAG,"GpsService ---> setServiceAsForeground()");

    // Prepare the intent triggered if the notification is selected
    Intent intent = new Intent(this,LocationService.class);
    PendingIntent pIntent = PendingIntent.getActivity(this,intent,0);

    notificationmanager notificationmanager = (notificationmanager) getSystemService(Context.NOTIFICATION_SERVICE);
    builder = null;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        int importance = notificationmanager.IMPORTANCE_LOW;
        NotificationChannel notificationChannel = new NotificationChannel("ID","Name",importance);
        notificationmanager.createNotificationChannel(notificationChannel);
        builder = new NotificationCompat.Builder(getApplicationContext(),notificationChannel.getId());
    } else {
        builder = new NotificationCompat.Builder(getApplicationContext());
    }

    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        v.vibrate(VibrationEffect.createOneshot(500,VibrationEffect.DEFAULT_AMPLITUDE));
    } else {
        //deprecated in API 26
        v.vibrate(500);
    }
    // Build the notification
    // Use NotificationCompat.Builder instead of just Notification.Builder to support older Android versions
    Notification notification = builder.setContentTitle("MyMovements")
            .setContentText("Running ...")
            .setSmallIcon(getNotificationIcon())
            .setBadgeIconType(getNotificationIcon())
            .setContentIntent(pIntent)
            .setAutoCancel(true).build();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        startForeground(ONGOING_NOTIFICATION,notification,FOREGROUND_SERVICE_TYPE_LOCATION);
    }
    else {
        startForeground(ONGOING_NOTIFICATION,notification);
    }
}

private int getNotificationIcon(){

    SharedPreferences settings = this.getSharedPreferences(MainActivity.PREFERENCE,0);
    String icon = settings.getString(MapFragment.NOTIFICATION_PREF," ");
    switch (icon) {
        case "Walking":
            return R.drawable.walk;
        case "Public Transportation":
            return R.drawable.bus;
        case "Driving":
            return R.drawable.car;
        default:
            return 0;
    }
}

private void updateNotification(){
    notificationmanager notificationmanager = (notificationmanager) getSystemService(Context.NOTIFICATION_SERVICE);
    String conc = "Running...\n" + "Lat: " + currentLocation.getLatitude() + " " + "Lng: " + currentLocation.getLongitude();
    Notification notification = builder.setStyle(new NotificationCompat.BigTextStyle()
            .bigText(conc))
            .setContentText(conc).build();
    notificationmanager.notify(ONGOING_NOTIFICATION,notification);
}

private void notifyValueUpdate(){
    Log.d(TAG,"MyStartedService ---> notifyValueUpdate()");

    if(currentLocation != null) {
        updateNotification();
        Log.d(LocationService.TAG,currentLocation.getProvider());
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction(NEW_VALUE_INTENT_ACTION);

        Bundle bundle = new Bundle();
        bundle.putDouble(INTENT_LATITUDE,currentLocation.getLatitude());
        bundle.putDouble(INTENT_LONGITUDE,currentLocation.getLongitude());
        bundle.putDouble(INTENT_SPEED,currentLocation.getSpeed()*3.6);
        bundle.putDouble(INTENT_ACCURACY,currentLocation.getAccuracy());
        broadcastIntent.putExtras(bundle);

        LocalbroadcastManager.getInstance(this).sendbroadcast(broadcastIntent);
    }
}

}

我在OnServiceCommand()-> startServiceTask()-> setServiceAsForeground()中启动了服务

我将非常感谢我编写代码的所有技巧(这是一个学者项目,这是我的第一个应用程序,所以我可能做错了什么。)

谢谢大家

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...