Location requests through foreground service

This commit is contained in:
estevez-dev 2020-07-20 16:23:12 +03:00
parent f87cff7a7e
commit f4b6d7a332
4 changed files with 185 additions and 10 deletions

View File

@ -60,6 +60,10 @@
android:name=".LocationUpdatesService"
android:enabled="true"
android:exported="false" />
<service
android:name=".LocationRequestService"
android:enabled="true"
android:exported="false" />
<receiver android:name=".NotificationActionReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>

View File

@ -0,0 +1,146 @@
package com.keyboardcrumbs.hassclient;
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.os.Looper;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.ExistingWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
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;
public class LocationRequestService extends Service {
private static final String TAG = LocationRequestService.class.getSimpleName();
private NotificationManager mNotificationManager;
private LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationClient;
private LocationCallback mLocationCallback;
private Handler mServiceHandler;
public LocationRequestService() {
}
@Override
public void onCreate() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
onNewLocation(locationResult.getLastLocation());
}
};
mLocationRequest = new LocationRequest();
HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
mServiceHandler = new Handler(handlerThread.getLooper());
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Location requests";
NotificationChannel mChannel =
new NotificationChannel(LocationUtils.ONETIME_NOTIFICATION_CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW);
mNotificationManager.createNotificationChannel(mChannel);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service started. startId="+startId);
requestLocationUpdates();
return START_STICKY;
}
@Override
public void onDestroy() {
try {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
} catch (SecurityException unlikely) {
//When we lost permission
Log.i(TAG, "No location permission");
}
mServiceHandler.removeCallbacksAndMessages(null);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void requestLocationUpdates() {
Log.i(TAG, "Requesting location update in 5 seconds.");
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
startForeground(LocationUtils.ONETIME_NOTIFICATION_ID, LocationUtils.getRequestNotification(this, null, LocationUtils.ONETIME_NOTIFICATION_CHANNEL_ID));
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
} catch (SecurityException unlikely) {
stopSelf();
}
}
private void onNewLocation(Location location) {
Log.i(TAG, "New location: " + location);
mNotificationManager.notify(LocationUtils.ONETIME_NOTIFICATION_ID, LocationUtils.getRequestNotification(
this,
location,
LocationUtils.ONETIME_NOTIFICATION_CHANNEL_ID
));
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
Data locationData = new Data.Builder()
.putInt(SendDataHomeWorker.DATA_TYPE_KEY, SendDataHomeWorker.DATA_TYPE_LOCATION)
.putDouble("Lat", location.getLatitude())
.putDouble("Long", location.getLongitude())
.putFloat("Acc", location.getAccuracy())
.build();
OneTimeWorkRequest uploadWorkRequest =
new OneTimeWorkRequest.Builder(SendDataHomeWorker.class)
.setConstraints(constraints)
.setInputData(locationData)
.build();
WorkManager
.getInstance(getApplicationContext())
.enqueueUniqueWork("SendLocationUpdate", ExistingWorkPolicy.REPLACE, uploadWorkRequest);
stopSelf();
}
}

View File

@ -12,7 +12,6 @@ import android.os.IBinder;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.work.BackoffPolicy;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.ExistingWorkPolicy;
@ -28,8 +27,6 @@ import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import java.util.concurrent.TimeUnit;
public class LocationUpdatesService extends Service {
private static final String TAG = LocationUpdatesService.class.getSimpleName();
@ -77,7 +74,7 @@ public class LocationUpdatesService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service started");
Log.i(TAG, "Service started. startId="+startId);
requestLocationUpdates();
@ -110,9 +107,10 @@ public class LocationUpdatesService extends Service {
} else {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY;
}
Log.i(TAG, "Requesting location updates. Every " + requestInterval + "ms with priority of " + priority);
mLocationRequest.setPriority(priority);
mLocationRequest.setInterval(requestInterval);
Log.i(TAG, "Requesting location updates. Every " + requestInterval + "ms with priority of " + priority);
startForeground(LocationUtils.SERVICE_NOTIFICATION_ID, LocationUtils.getNotification(this, null, LocationUtils.SERVICE_NOTIFICATION_CHANNEL_ID));
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
@ -125,7 +123,11 @@ public class LocationUpdatesService extends Service {
private void onNewLocation(Location location) {
Log.i(TAG, "New location: " + location);
mNotificationManager.notify(LocationUtils.SERVICE_NOTIFICATION_ID, LocationUtils.getNotification(this, location, LocationUtils.SERVICE_NOTIFICATION_CHANNEL_ID));
mNotificationManager.notify(LocationUtils.SERVICE_NOTIFICATION_ID, LocationUtils.getNotification(
this,
location,
LocationUtils.SERVICE_NOTIFICATION_CHANNEL_ID
));
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)

View File

@ -28,6 +28,8 @@ class LocationUtils {
static final int WORKER_NOTIFICATION_ID = 954322;
static final String SERVICE_NOTIFICATION_CHANNEL_ID = "location_service";
static final int SERVICE_NOTIFICATION_ID = 954311;
static final String ONETIME_NOTIFICATION_CHANNEL_ID = "location_request";
static final int ONETIME_NOTIFICATION_ID = 954333;
static final String REQUEST_LOCATION_NOTIFICATION = "request_location_update";
@ -89,15 +91,17 @@ class LocationUtils {
}
static void requestLocationOnce(Context context) {
OneTimeWorkRequest oneTimeWork = new OneTimeWorkRequest.Builder(LocationUpdatesWorker.class)
.build();
WorkManager.getInstance(context).enqueueUniqueWork(LocationUtils.LOCATION_REQUEST_NAME, ExistingWorkPolicy.REPLACE, oneTimeWork);
Intent myService = new Intent(context, LocationRequestService.class);
context.startService(myService);
//OneTimeWorkRequest oneTimeWork = new OneTimeWorkRequest.Builder(LocationUpdatesWorker.class)
// .build();
//WorkManager.getInstance(context).enqueueUniqueWork(LocationUtils.LOCATION_REQUEST_NAME, ExistingWorkPolicy.REPLACE, oneTimeWork);
}
static Notification getNotification(Context context, Location location, String channelId) {
CharSequence title = "Location tracking";
CharSequence text = location == null ? "Accuracy: unknown" : "Accuracy: " + location.getAccuracy() + " m";
CharSequence bigText = location == null ? "Waiting for location..." : "Location updated at " + DateFormat.getDateTimeInstance().format(new Date(location.getTime())) +
CharSequence bigText = location == null ? "Waiting for location..." : "Time: " + DateFormat.getDateTimeInstance().format(new Date(location.getTime())) +
System.getProperty("line.separator") + "Accuracy: " + location.getAccuracy() + " m" +
System.getProperty("line.separator") + "Location: " + location.getLatitude() + ", " + location.getLongitude();
@ -117,4 +121,23 @@ class LocationUtils {
return builder.build();
}
static Notification getRequestNotification(Context context, Location location, String channelId) {
CharSequence title = "Updating location...";
CharSequence text = location == null ? "Waiting for location..." : "Accuracy: " + location.getAccuracy() + " m";
PendingIntent activityPendingIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId)
.setContentIntent(activityPendingIntent)
.setContentTitle(title)
.setContentText(text)
.setPriority(-1)
.setOngoing(true)
.setSmallIcon(R.drawable.mini_icon_location)
.setWhen(System.currentTimeMillis());
return builder.build();
}
}