我一直在尝试实施前台服务,以便每隔3秒就通过显示通知来定位应用程序,即使该应用程序在后台也是如此。但是,当我从后台删除我的应用程序时,通知也会同时删除。但是,仅当我在MI REDMI NOTE 5(API版本28)和MI REDMI NOTE 4(API版本24)中执行此操作时,但是当我在Samsung J5(API版本23)中运行相同的应用程序时,通知是即使将应用程序从后台删除,直到从活动中手动停止该应用程序时也显示。结果差异的原因是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();
}
}
答案 0 :(得分:0)
一段时间后,我正在使用前台服务进行位置更新。如果您的应用程序在后台但未被杀死,则当您想更新位置时,前台服务会很有用。但这是您的应用程序被杀死时停止前台服务的责任。因此,您只需实现LifeCycleDelegate即可在应用程序在后台运行时启动服务,而在应用程序在前台运行时停止服务。并且在您的主要活动或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()
}
}
将此方法添加到您的应用程序类中 私人有趣的registerLifecycleHandler(lifeCycleHandler:AppLifecycleHandler){ registerActivityLifecycleCallbacks(lifeCycleHandler) registerComponentCallbacks(lifeCycleHandler) }
override fun getLifecycle(): Lifecycle {
return mLifecycleRegistry
}
在应用程序类中实现LifeCycleDelegate并覆盖方法
internal interface LifeCycleDelegate {
fun onAppBackgrounded()
fun onAppForegrounded()
}
在应用程序类中创建应用程序对象
val lifeCycleHandler = AppLifecycleHandler(this)
registerLifecycleHandler(lifeCycleHandler)