我一直在尝试实现前台服务,以便在每 3 秒后获取位置,即使应用程序在后台显示通知也是如此。但是,当我从后台删除我的应用程序时,通知也会删除。但是,只有当我在 MI REDMI NOTE 5(API 版本 28)和 MI REDMI NOTE 4(API 版本 24)中执行此操作时才会发生这种情况,但是当我在 Samsung J5(API 版本 23)中运行相同的应用程序时,通知是即使应用程序从后台删除,直到手动从 Activity 中停止时也会显示。不同的结果行为是由于 API 的变化还是由于不同的手机型号?
这是我的服务等级
package com.example.locationrunandall;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
public class ForeService extends Service {
private static final String PACKAGE_NAME =
"com.example.customizedforeground";
static final String ACTION_BROADCAST = PACKAGE_NAME + ".broadcast";
static final String EXTRA_LOCATION = PACKAGE_NAME + ".location";
private static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME +
".started_from_notification";
private Handler mServiceHandler;
private NotificationManager mNotificationManager;
// private Notification notification;
private LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationClient;
private LocationCallback mLocationCallback;
private Location mLocation;
private static final String CHANNEL_ID = "CHANNEL_ONE";
private static final int NOTIFICATION_ID = 4567123;
private static final String TAG = "123";
String loc;
public ForeService(){}
@Override
public void onCreate() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mLocationCallback = new LocationCallback(){
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
//Do Location Work You Want To Do
onNewLocation(locationResult.getLastLocation());
}
};
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(3*1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
getLastLocation();
HandlerThread handlerThread = new HandlerThread("HANDLER");
handlerThread.start();
mServiceHandler = new Handler(handlerThread.getLooper());
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
CharSequence name = "Name Charseq";
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
NotificationChannel notificationChannel = new
NotificationChannel(CHANNEL_ID,name, NotificationManager.IMPORTANCE_DEFAULT);
mNotificationManager.createNotificationChannel(notificationChannel);
}
startForeground(NOTIFICATION_ID,getNotification());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// startForeground(NOTIFICATION_ID,getNotification());
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceHandler.removeCallbacksAndMessages(null);
//stopForeground(true);
}
@androidx.annotation.Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void getLastLocation() {
try {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful() && task.getResult() != null) {
mLocation = task.getResult();
} else {
Log.d(TAG, "Failed to get location.");
}
}
});
} catch (SecurityException unlikely) {
Log.d(TAG, "Lost location permission." + unlikely);
}
}
private void onNewLocation(Location location) {
mLocation = location;
if(mLocation==null)
Log.d("DSK_OPER","Lat: = "+"Not known");
else
Log.d("DSK_OPER"," : "+location.getLatitude());
//send intent to broadcast reciever
Intent intent = new Intent(ACTION_BROADCAST);
intent.putExtra(EXTRA_LOCATION, location);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
// todo - Write More code here
mNotificationManager.notify(NOTIFICATION_ID,getNotification());
}
private Notification getNotification() {
//Intent intent = new Intent(this,MainActivity.class);
if(mLocation==null)
loc = "unknown loc";
else
loc = String.valueOf(mLocation.getLatitude());
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle("Latitude and longitude")
.setContentText(" = "+loc)
.setOngoing(true)
.setPriority(Notification.PRIORITY_HIGH)
.setSmallIcon(R.mipmap.ic_launcher)
.setWhen(System.currentTimeMillis());
// Set the Channel ID for Android O.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID);
}
return builder.build();
}
}
最佳答案
我正在使用前台服务在一段时间后进行位置更新。如果您的应用程序在后台但未被终止,当您想要更新位置时,前台服务非常有用。但是,当您的应用程序被终止时,您有责任停止前台服务。因此,您只需实现 LifeCycleDelegate,以便您可以在应用程序处于后台时启动服务,并在应用程序处于前台时停止服务。当您的主要 Activity 或 HomeActivity 被终止时,也会终止该服务。 这是 AppLifecycleHandler 的代码。
internal class AppLifecycleHandler(private val lifeCycleDelegate: LifeCycleDelegate) : Application.ActivityLifecycleCallbacks,
ComponentCallbacks2 {
private var appInForeground = false
override fun onActivityPaused(p0: Activity?) {}
/**
* app resumed
*/
override fun onActivityResumed(p0: Activity?) {
if (!appInForeground) {
appInForeground = true
lifeCycleDelegate.onAppForegrounded()
}
}
override fun onActivityStarted(p0: Activity?) {
}
override fun onActivityDestroyed(p0: Activity?) {
}
override fun onActivitySaveInstanceState(p0: Activity?, p1: Bundle?) {
}
override fun onActivityStopped(p0: Activity?) {
}
override fun onActivityCreated(p0: Activity?, p1: Bundle?) {
}
override fun onLowMemory() {}
override fun onConfigurationChanged(p0: Configuration?) {}
/**
* app sent to background
*/
override fun onTrimMemory(level: Int) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
appInForeground = false
lifeCycleDelegate.onAppBackgrounded()
}
}
将此方法添加到您的应用程序类中 私有(private)乐趣 registerLifecycleHandler(lifeCycleHandler: AppLifecycleHandler) { 注册ActivityLifecycleCallbacks(lifeCycleHandler) 注册组件回调(lifeCycleHandler) }
override fun getLifecycle(): Lifecycle {
return mLifecycleRegistry
}
在您的应用程序类中实现 LifeCycleDelegate 并重写方法
internal interface LifeCycleDelegate {
fun onAppBackgrounded()
fun onAppForegrounded()
}
在应用程序类中创建应用程序对象
val lifeCycleHandler = AppLifecycleHandler(this)
registerLifecycleHandler(lifeCycleHandler)
关于java - 为什么从后台删除应用程序后前台服务不工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56359360/