@ -80,6 +80,7 @@ flutter {
|
||||
dependencies {
|
||||
implementation 'com.google.firebase:firebase-analytics:17.2.2'
|
||||
implementation 'com.google.firebase:firebase-messaging:20.2.0'
|
||||
implementation 'com.google.android.gms:play-services-location:17.0.0'
|
||||
implementation 'androidx.work:work-runtime:2.3.4'
|
||||
implementation "androidx.concurrent:concurrent-futures:1.0.0"
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
@ -1,9 +1,7 @@
|
||||
package com.keyboardcrumbs.hassclient;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.location.Location;
|
||||
@ -14,7 +12,6 @@ import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.work.BackoffPolicy;
|
||||
import androidx.work.Constraints;
|
||||
import androidx.work.Data;
|
||||
@ -35,20 +32,8 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class LocationUpdatesService extends Service {
|
||||
|
||||
private static final String PACKAGE_NAME =
|
||||
"com.keyboardcrumbs.hassclient";
|
||||
|
||||
private static final String TAG = LocationUpdatesService.class.getSimpleName();
|
||||
|
||||
private static final String CHANNEL_ID = "location_service";
|
||||
|
||||
private static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME +
|
||||
".started_from_notification";
|
||||
|
||||
//private final IBinder mBinder = new LocalBinder();
|
||||
|
||||
private static final int NOTIFICATION_ID = 954311;
|
||||
|
||||
private NotificationManager mNotificationManager;
|
||||
|
||||
private LocationRequest mLocationRequest;
|
||||
@ -59,8 +44,6 @@ public class LocationUpdatesService extends Service {
|
||||
|
||||
private Handler mServiceHandler;
|
||||
|
||||
private Location mLocation;
|
||||
|
||||
public LocationUpdatesService() {
|
||||
}
|
||||
|
||||
@ -86,7 +69,7 @@ public class LocationUpdatesService extends Service {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
CharSequence name = "Location updates";
|
||||
NotificationChannel mChannel =
|
||||
new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW);
|
||||
new NotificationChannel(LocationUtils.SERVICE_NOTIFICATION_CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW);
|
||||
|
||||
mNotificationManager.createNotificationChannel(mChannel);
|
||||
}
|
||||
@ -95,15 +78,8 @@ public class LocationUpdatesService extends Service {
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.i(TAG, "Service started");
|
||||
boolean startedFromNotification = intent.getBooleanExtra(EXTRA_STARTED_FROM_NOTIFICATION,
|
||||
false);
|
||||
|
||||
// We got here because the user decided to remove location updates from the notification.
|
||||
if (startedFromNotification) {
|
||||
stopSelf();
|
||||
} else {
|
||||
requestLocationUpdates();
|
||||
}
|
||||
requestLocationUpdates();
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
@ -132,7 +108,7 @@ public class LocationUpdatesService extends Service {
|
||||
mLocationRequest.setPriority(priority);
|
||||
mLocationRequest.setInterval(requestInterval);
|
||||
mLocationRequest.setFastestInterval(requestInterval);
|
||||
startForeground(NOTIFICATION_ID, getNotification());
|
||||
startForeground(LocationUtils.SERVICE_NOTIFICATION_ID, LocationUtils.getNotification(this, null, LocationUtils.SERVICE_NOTIFICATION_CHANNEL_ID));
|
||||
try {
|
||||
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
|
||||
mLocationCallback, Looper.myLooper());
|
||||
@ -141,40 +117,10 @@ public class LocationUpdatesService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private Notification getNotification() {
|
||||
Intent intent = new Intent(this, LocationUpdatesService.class);
|
||||
|
||||
CharSequence text = LocationUtils.getLocationText(mLocation);
|
||||
|
||||
intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);
|
||||
|
||||
PendingIntent servicePendingIntent = PendingIntent.getService(this, 0, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
|
||||
new Intent(this, MainActivity.class), 0);
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
|
||||
.addAction(R.drawable.blank_icon, "Open app",
|
||||
activityPendingIntent)
|
||||
.addAction(R.drawable.blank_icon, "Stop tracking",
|
||||
servicePendingIntent)
|
||||
.setContentText(text)
|
||||
.setPriority(-1)
|
||||
.setContentTitle(LocationUtils.getLocationTitle(mLocation))
|
||||
.setOngoing(true)
|
||||
.setSmallIcon(R.drawable.mini_icon)
|
||||
.setWhen(System.currentTimeMillis());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void onNewLocation(Location location) {
|
||||
Log.i(TAG, "New location: " + location);
|
||||
|
||||
mLocation = location;
|
||||
|
||||
mNotificationManager.notify(NOTIFICATION_ID, getNotification());
|
||||
mNotificationManager.notify(LocationUtils.SERVICE_NOTIFICATION_ID, LocationUtils.getNotification(this, location, LocationUtils.SERVICE_NOTIFICATION_CHANNEL_ID));
|
||||
|
||||
Constraints constraints = new Constraints.Builder()
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
@ -182,9 +128,9 @@ public class LocationUpdatesService extends Service {
|
||||
|
||||
Data locationData = new Data.Builder()
|
||||
.putInt(SendDataHomeWorker.DATA_TYPE_KEY, SendDataHomeWorker.DATA_TYPE_LOCATION)
|
||||
.putDouble("Lat", mLocation.getLatitude())
|
||||
.putDouble("Long", mLocation.getLongitude())
|
||||
.putFloat("Acc", mLocation.getAccuracy())
|
||||
.putDouble("Lat", location.getLatitude())
|
||||
.putDouble("Long", location.getLongitude())
|
||||
.putFloat("Acc", location.getAccuracy())
|
||||
.build();
|
||||
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
package com.keyboardcrumbs.hassclient;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -25,6 +29,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static android.content.Context.NOTIFICATION_SERVICE;
|
||||
|
||||
public class LocationUpdatesWorker extends ListenableWorker {
|
||||
|
||||
private Context currentContext;
|
||||
@ -78,6 +84,22 @@ public class LocationUpdatesWorker extends ListenableWorker {
|
||||
WorkManager
|
||||
.getInstance(getApplicationContext())
|
||||
.enqueueUniqueWork("SendLocationUpdate", ExistingWorkPolicy.REPLACE, uploadWorkRequest);
|
||||
if (LocationUtils.showNotification(currentContext)) {
|
||||
NotificationManager notificationManager;
|
||||
if (android.os.Build.VERSION.SDK_INT >= 23) {
|
||||
notificationManager = currentContext.getSystemService(NotificationManager.class);
|
||||
} else {
|
||||
notificationManager = (NotificationManager)currentContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
CharSequence name = "Location updates";
|
||||
NotificationChannel mChannel =
|
||||
new NotificationChannel(LocationUtils.WORKER_NOTIFICATION_CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW);
|
||||
|
||||
notificationManager.createNotificationChannel(mChannel);
|
||||
}
|
||||
notificationManager.notify(LocationUtils.WORKER_NOTIFICATION_ID, LocationUtils.getNotification(currentContext, location, LocationUtils.WORKER_NOTIFICATION_CHANNEL_ID));
|
||||
}
|
||||
finish();
|
||||
completer.set(Result.success());
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package com.keyboardcrumbs.hassclient;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.work.ExistingPeriodicWorkPolicy;
|
||||
import androidx.work.PeriodicWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
@ -18,6 +21,12 @@ class LocationUtils {
|
||||
static final String KEY_REQUESTING_LOCATION_UPDATES = "flutter.location-updates-state";
|
||||
static final String KEY_LOCATION_UPDATE_INTERVAL = "flutter.location-updates-interval";
|
||||
static final String KEY_LOCATION_UPDATE_PRIORITY = "flutter.location-updates-priority";
|
||||
static final String KEY_LOCATION_SHOW_NOTIFICATION = "flutter.location-updates-show-notification";
|
||||
|
||||
static final String WORKER_NOTIFICATION_CHANNEL_ID = "location_worker";
|
||||
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 LOCATION_WORK_NAME = "HALocationWorker";
|
||||
|
||||
@ -40,6 +49,10 @@ class LocationUtils {
|
||||
return (int) context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE).getLong(KEY_LOCATION_UPDATE_PRIORITY, 102);
|
||||
}
|
||||
|
||||
static boolean showNotification(Context context) {
|
||||
return context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE).getBoolean(KEY_LOCATION_SHOW_NOTIFICATION, true);
|
||||
}
|
||||
|
||||
static void setLocationUpdatesState(Context context, int locationUpdatesState) {
|
||||
context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
@ -70,6 +83,25 @@ class LocationUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static Notification getNotification(Context context, Location location, String channelId) {
|
||||
CharSequence text = LocationUtils.getLocationText(location);
|
||||
|
||||
PendingIntent activityPendingIntent = PendingIntent.getActivity(context, 0,
|
||||
new Intent(context, MainActivity.class), 0);
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId)
|
||||
.addAction(R.drawable.blank_icon, "Open HA Client",
|
||||
activityPendingIntent)
|
||||
.setContentText(text)
|
||||
.setPriority(-1)
|
||||
.setContentTitle(LocationUtils.getLocationTitle(location))
|
||||
.setOngoing(true)
|
||||
.setSmallIcon(R.drawable.mini_icon)
|
||||
.setWhen(System.currentTimeMillis());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static void startWorker(Context context, long interval) {
|
||||
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(LocationUpdatesWorker.class, interval, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
|
@ -9,10 +9,10 @@ import io.flutter.embedding.engine.FlutterEngine;
|
||||
import io.flutter.plugins.GeneratedPluginRegistrant;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
@ -82,6 +82,10 @@ public class MainActivity extends FlutterActivity {
|
||||
stopLocationUpdates();
|
||||
result.success("");
|
||||
break;
|
||||
case "cancelOldLocationWorker":
|
||||
WorkManager.getInstance(this).cancelAllWorkByTag("haclocation");
|
||||
result.success("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -107,6 +111,13 @@ public class MainActivity extends FlutterActivity {
|
||||
Intent myService = new Intent(MainActivity.this, LocationUpdatesService.class);
|
||||
stopService(myService);
|
||||
WorkManager.getInstance(this).cancelUniqueWork(LocationUtils.LOCATION_WORK_NAME);
|
||||
NotificationManager notificationManager;
|
||||
if (android.os.Build.VERSION.SDK_INT >= 23) {
|
||||
notificationManager = getSystemService(NotificationManager.class);
|
||||
} else {
|
||||
notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
}
|
||||
notificationManager.cancel(LocationUtils.WORKER_NOTIFICATION_ID);
|
||||
LocationUtils.setLocationUpdatesState(this, LocationUtils.LOCATION_UPDATES_DISABLED);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user