Resolves #571, Resolves #490, Resolves #517

This commit is contained in:
estevez-dev
2020-07-07 22:49:51 +03:00
parent 3a7f3db6cd
commit dce93966e3
11 changed files with 235 additions and 418 deletions

View File

@ -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'

View File

@ -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();

View File

@ -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());
}

View File

@ -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();

View File

@ -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);
}