У меня есть это приложение, которое отправляет местоположение пользователя на сервер, когда он / она вошел в систему.Я хочу, чтобы служба работала, даже когда приложение убито
Я попробовал некоторые из методов, которые были приведены при переполнении стека, служба, кажется, работает ниже android marshmallow, но, похоже, не работает в версиях androidнад ним
Это мой сервис
public class MyLocationService extends Service {
public static final int TWO_MINUTES = 120000; // 120 seconds
public static Boolean isRunning = false;
double sendlat,sendlng;
public LocationManager mLocationManager;
public LocationUpdaterListener mLocationListener;
public Location previousBestLocation = null;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocationListener = new LocationUpdaterListener();
super.onCreate();
}
Handler mHandler = new Handler();
Runnable mHandlerTask = new Runnable() {
@Override
public void run() {
if (!isRunning) {
startListening();
}
mHandler.postDelayed(mHandlerTask, TWO_MINUTES);
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mHandlerTask.run();
return START_STICKY;
}
@Override
public void onDestroy() {
stopListening();
mHandler.removeCallbacks(mHandlerTask);
super.onDestroy();
}
private void startListening() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (mLocationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER))
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener);
if (mLocationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER))
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
}
isRunning = true;
}
private void stopListening() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationManager.removeUpdates(mLocationListener);
}
isRunning = false;
}
public class LocationUpdaterListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
if (isBetterLocation(location, previousBestLocation)) {
previousBestLocation = location;
try {
if (previousBestLocation != null) {
sendlat = previousBestLocation.getLatitude();
sendlng = previousBestLocation.getLongitude();
} else {
CommonObjects.showToast(getApplicationContext(),"Couldn't get the location. Make sure location is enabled on the device");
}
String sLat = String.valueOf(sendlat);
String sLnt = String.valueOf(sendlng);
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
showNotificationWithImage(sLat,sLnt);
Log.i("lat,long",sLat+","+sLnt+","+dateFormat.format(date));
if(CommonObjects.isNetworkAvailable(getApplicationContext())) {
CommonObjects.sendTechLoc(getApplicationContext(),sLat,sLnt);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onProviderDisabled(String provider) {
stopListening();
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
return true;
}
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
if (isSignificantlyNewer) {
return true;
} else if (isSignificantlyOlder) {
return false;
}
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider());
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
private void showNotificationWithImage(String la,String lo) {
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
//Bitmap largeIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.mapimg);
NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
style.setSummaryText("");
Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(getNotificationIcon())
.setColor(getResources().getColor(R.color.app_color))
.setContentTitle("Mr Fix"+la+lo)
.setStyle(style)
.setVisibility(VISIBILITY_PUBLIC);
// Since android Oreo notification channel is needed.
String channelId = getString(R.string.default_notification_channel_id);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Mr Fix",
NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
}
manager.notify(0 , notificationBuilder.build());
}
private void sendNotification(String la,String lo) {
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle(getString(R.string.app_name))
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentText(la+","+lo)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
private int getNotificationIcon() {
boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
return useWhiteIcon ? R.drawable.ic_stat_name: R.mipmap.ic_launcher_round;
}
}
Это мой вызов
Intent i=new Intent(HomeActivity.this, MyLocationService.class);
Log.i("Service","Service Started....");
startService(i);