Loading app/src/main/java/net/fabiszewski/ulogger/ExternalCommandReceiver.java +1 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ public class ExternalCommandReceiver extends BroadcastReceiver { private void uploadData(Context context) { if (DbAccess.needsSync(context)) { Intent intent = new Intent(context, WebSyncService.class); WebSyncService.enqueueWork(context, intent); context.startService(intent); } } } app/src/main/java/net/fabiszewski/ulogger/LoggerService.java +11 −65 Original line number Diff line number Diff line Loading @@ -9,18 +9,17 @@ package net.fabiszewski.ulogger; import static net.fabiszewski.ulogger.LoggerTask.E_DISABLED; import static net.fabiszewski.ulogger.LoggerTask.E_PERMISSION; import static net.fabiszewski.ulogger.MainActivity.UPDATED_PREFS; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Build; import android.os.Bundle; import android.os.HandlerThread; import android.os.IBinder; Loading @@ -28,15 +27,8 @@ import android.os.Looper; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import androidx.core.app.TaskStackBuilder; import androidx.preference.PreferenceManager; import static net.fabiszewski.ulogger.LoggerTask.E_DISABLED; import static net.fabiszewski.ulogger.LoggerTask.E_PERMISSION; import static net.fabiszewski.ulogger.MainActivity.UPDATED_PREFS; /** * Background service logging positions to database * and synchronizing with remote server. Loading Loading @@ -66,8 +58,7 @@ public class LoggerService extends Service { private static Location lastLocation = null; private final int NOTIFICATION_ID = 1526756640; private NotificationManager notificationManager; private NotificationHelper notificationHelper; /** * Basic initializations Loading @@ -77,13 +68,9 @@ public class LoggerService extends Service { public void onCreate() { if (Logger.DEBUG) { Log.d(TAG, "[onCreate]"); } notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null) { notificationManager.cancelAll(); } locationHelper = LocationHelper.getInstance(this); locationListener = new mLocationListener(); notificationHelper = new NotificationHelper(this); thread = new HandlerThread("LoggerThread"); thread.start(); Loading @@ -110,7 +97,7 @@ public class LoggerService extends Service { syncIntent = new Intent(getApplicationContext(), WebSyncService.class); if (locationHelper.isLiveSync() && DbAccess.needsSync(this)) { WebSyncService.enqueueWork(getApplicationContext(), syncIntent); getApplicationContext().startService(syncIntent); } return true; } catch (LocationHelper.LoggerException e) { Loading Loading @@ -139,8 +126,8 @@ public class LoggerService extends Service { if (intent != null && intent.getBooleanExtra(UPDATED_PREFS, false)) { handlePrefsUpdated(); } else { final Notification notification = showNotification(NOTIFICATION_ID); startForeground(NOTIFICATION_ID, notification); final Notification notification = notificationHelper.showNotification(); startForeground(notificationHelper.getId(), notification); if (!initializeLocationUpdates()) { setRunning(false); stopSelf(); Loading Loading @@ -191,7 +178,7 @@ public class LoggerService extends Service { setRunning(false); notificationManager.cancel(NOTIFICATION_ID); notificationHelper.cancelNotification(); sendBroadcast(BROADCAST_LOCATION_STOPPED); if (thread != null) { Loading Loading @@ -245,47 +232,6 @@ public class LoggerService extends Service { lastLocation = null; } /** * Show notification * @param mId Notification Id */ @SuppressWarnings("SameParameterValue") private Notification showNotification(int mId) { if (Logger.DEBUG) { Log.d(TAG, "[showNotification " + mId + "]"); } final String channelId = String.valueOf(mId); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel(channelId); } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.ic_stat_notify_24dp) .setContentTitle(getString(R.string.app_name)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_SERVICE) .setContentText(String.format(getString(R.string.is_running), getString(R.string.app_name))); Intent resultIntent = new Intent(this, MainActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); Notification mNotification = mBuilder.build(); notificationManager.notify(mId, mNotification); return mNotification; } /** * Create notification channel * @param channelId Channel Id */ @RequiresApi(Build.VERSION_CODES.O) private void createNotificationChannel(String channelId) { NotificationChannel chan = new NotificationChannel(channelId, getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH); notificationManager.createNotificationChannel(chan); } /** * Send broadcast message * @param broadcast Broadcast message Loading Loading @@ -315,7 +261,7 @@ public class LoggerService extends Service { DbAccess.writeLocation(LoggerService.this, location); sendBroadcast(BROADCAST_LOCATION_UPDATED); if (locationHelper.isLiveSync()) { WebSyncService.enqueueWork(getApplicationContext(), syncIntent); getApplicationContext().startService(syncIntent); } } } Loading app/src/main/java/net/fabiszewski/ulogger/MainFragment.java +4 −4 Original line number Diff line number Diff line Loading @@ -9,6 +9,9 @@ package net.fabiszewski.ulogger; import static net.fabiszewski.ulogger.Alert.showAlert; import static net.fabiszewski.ulogger.Alert.showConfirm; import android.Manifest; import android.app.Activity; import android.content.BroadcastReceiver; Loading Loading @@ -49,9 +52,6 @@ import java.util.Date; import java.util.Locale; import java.util.TimeZone; import static net.fabiszewski.ulogger.Alert.showAlert; import static net.fabiszewski.ulogger.Alert.showConfirm; @SuppressWarnings("WeakerAccess") public class MainFragment extends Fragment { Loading Loading @@ -297,7 +297,7 @@ public class MainFragment extends Fragment { showToast(getString(R.string.provide_user_pass_url)); } else if (DbAccess.needsSync(context)) { Intent syncIntent = new Intent(context, WebSyncService.class); WebSyncService.enqueueWork(context, syncIntent); context.startService(syncIntent); showToast(getString(R.string.uploading_started)); isUploading = true; } else { Loading app/src/main/java/net/fabiszewski/ulogger/NotificationHelper.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 Bartek Fabiszewski * http://www.fabiszewski.net * * This file is part of μlogger-android. * Licensed under GPL, either version 3, or any later. * See <http://www.gnu.org/licenses/> */ package net.fabiszewski.ulogger; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Build; import android.util.Log; import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import androidx.core.app.TaskStackBuilder; class NotificationHelper { private static final String TAG = NotificationHelper.class.getSimpleName(); private final int NOTIFICATION_ID = 1526756640; private final NotificationManager notificationManager; private final Context context; /** * Constructor * @param ctx Context */ NotificationHelper(Context ctx) { context = ctx; notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null) { notificationManager.cancelAll(); } } /** * Show notification * @param mId Notification Id */ Notification showNotification() { if (Logger.DEBUG) { Log.d(TAG, "[showNotification " + NOTIFICATION_ID + "]"); } final String channelId = String.valueOf(NOTIFICATION_ID); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel(channelId); } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_stat_notify_24dp) .setContentTitle(context.getString(R.string.app_name)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_SERVICE) .setContentText(String.format(context.getString(R.string.is_running), context.getString(R.string.app_name))); Intent resultIntent = new Intent(context, MainActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); Notification mNotification = mBuilder.build(); notificationManager.notify(NOTIFICATION_ID, mNotification); return mNotification; } /** * Create notification channel * @param channelId Channel Id */ @RequiresApi(Build.VERSION_CODES.O) private void createNotificationChannel(String channelId) { NotificationChannel channel = new NotificationChannel(channelId, context.getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH); notificationManager.createNotificationChannel(channel); } /** * Cancel notification */ void cancelNotification() { notificationManager.cancel(NOTIFICATION_ID); } /** * Get notification ID * @return Notification ID */ int getId() { return NOTIFICATION_ID; } } app/src/main/java/net/fabiszewski/ulogger/WebSyncService.java +88 −29 Original line number Diff line number Diff line Loading @@ -9,17 +9,27 @@ package net.fabiszewski.ulogger; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import android.app.AlarmManager; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.JobIntentService; import androidx.annotation.Nullable; import org.json.JSONException; Loading @@ -34,49 +44,56 @@ import java.util.HashMap; import java.util.Map; /** * Service synchronizing local database positions with remote server. * * Service synchronizing local database positions with remote server */ public class WebSyncService extends JobIntentService { public class WebSyncService extends Service { private static final String TAG = WebSyncService.class.getSimpleName(); public static final String BROADCAST_SYNC_FAILED = "net.fabiszewski.ulogger.broadcast.sync_failed"; public static final String BROADCAST_SYNC_DONE = "net.fabiszewski.ulogger.broadcast.sync_done"; private HandlerThread thread; private ServiceHandler serviceHandler; private DbAccess db; private WebHelper web; private static PendingIntent pi = null; final private static int FIVE_MINUTES = 1000 * 60 * 5; static final int JOB_ID = 1001; private NotificationHelper notificationHelper; /** * Convenience method for enqueuing work in to this service. * Basic initializations * Start looper to process uploads */ static void enqueueWork(Context context, Intent work) { enqueueWork(context, WebSyncService.class, JOB_ID, work); } @Override public void onCreate() { super.onCreate(); if (Logger.DEBUG) { Log.d(TAG, "[websync create]"); } web = new WebHelper(this); notificationHelper = new NotificationHelper(this); thread = new HandlerThread("WebSyncThread", THREAD_PRIORITY_BACKGROUND); thread.start(); Looper looper = thread.getLooper(); serviceHandler = new ServiceHandler(looper); // keep database open during whole service runtime db = DbAccess.getInstance(); db.open(this); } /** * Handle synchronization intent * @param intent Intent * Handler to do synchronization on background thread */ @Override protected void onHandleWork(@NonNull Intent intent) { if (Logger.DEBUG) { Log.d(TAG, "[websync start]"); } private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { cancelPending(); if (!WebHelper.isAuthorized) { Loading @@ -84,6 +101,7 @@ public class WebSyncService extends JobIntentService { web.authorize(); } catch (WebAuthException|IOException|JSONException e) { handleError(e); stopSelf(msg.arg1); return; } } Loading @@ -93,6 +111,31 @@ public class WebSyncService extends JobIntentService { if (trackId > 0) { doSync(trackId); } stopSelf(msg.arg1); } } /** * Start foreground service * * @param intent Intent * @param flags Flags * @param startId Unique id * @return Always returns START_STICKY */ @Override public int onStartCommand(@NonNull Intent intent, int flags, int startId) { if (Logger.DEBUG) { Log.d(TAG, "[websync start]"); } final Notification notification = notificationHelper.showNotification(); startForeground(notificationHelper.getId(), notification); Message msg = serviceHandler.obtainMessage(); msg.arg1 = startId; serviceHandler.sendMessage(msg); return START_STICKY; } /** Loading Loading @@ -212,7 +255,11 @@ public class WebSyncService extends JobIntentService { if (Logger.DEBUG) { Log.d(TAG, "[websync set alarm]"); } AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent syncIntent = new Intent(getApplicationContext(), WebSyncService.class); pi = PendingIntent.getService(this, 0, syncIntent, FLAG_ONE_SHOT); int flags = FLAG_ONE_SHOT; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { flags |= FLAG_IMMUTABLE; } pi = PendingIntent.getService(this, 0, syncIntent, flags); if (am != null) { am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + FIVE_MINUTES, pi); } Loading Loading @@ -284,7 +331,19 @@ public class WebSyncService extends JobIntentService { if (db != null) { db.close(); } super.onDestroy(); notificationHelper.cancelNotification(); if (thread != null) { thread.interrupt(); thread = null; } } @Nullable @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not implemented"); } } Loading
app/src/main/java/net/fabiszewski/ulogger/ExternalCommandReceiver.java +1 −1 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ public class ExternalCommandReceiver extends BroadcastReceiver { private void uploadData(Context context) { if (DbAccess.needsSync(context)) { Intent intent = new Intent(context, WebSyncService.class); WebSyncService.enqueueWork(context, intent); context.startService(intent); } } }
app/src/main/java/net/fabiszewski/ulogger/LoggerService.java +11 −65 Original line number Diff line number Diff line Loading @@ -9,18 +9,17 @@ package net.fabiszewski.ulogger; import static net.fabiszewski.ulogger.LoggerTask.E_DISABLED; import static net.fabiszewski.ulogger.LoggerTask.E_PERMISSION; import static net.fabiszewski.ulogger.MainActivity.UPDATED_PREFS; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Build; import android.os.Bundle; import android.os.HandlerThread; import android.os.IBinder; Loading @@ -28,15 +27,8 @@ import android.os.Looper; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import androidx.core.app.TaskStackBuilder; import androidx.preference.PreferenceManager; import static net.fabiszewski.ulogger.LoggerTask.E_DISABLED; import static net.fabiszewski.ulogger.LoggerTask.E_PERMISSION; import static net.fabiszewski.ulogger.MainActivity.UPDATED_PREFS; /** * Background service logging positions to database * and synchronizing with remote server. Loading Loading @@ -66,8 +58,7 @@ public class LoggerService extends Service { private static Location lastLocation = null; private final int NOTIFICATION_ID = 1526756640; private NotificationManager notificationManager; private NotificationHelper notificationHelper; /** * Basic initializations Loading @@ -77,13 +68,9 @@ public class LoggerService extends Service { public void onCreate() { if (Logger.DEBUG) { Log.d(TAG, "[onCreate]"); } notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null) { notificationManager.cancelAll(); } locationHelper = LocationHelper.getInstance(this); locationListener = new mLocationListener(); notificationHelper = new NotificationHelper(this); thread = new HandlerThread("LoggerThread"); thread.start(); Loading @@ -110,7 +97,7 @@ public class LoggerService extends Service { syncIntent = new Intent(getApplicationContext(), WebSyncService.class); if (locationHelper.isLiveSync() && DbAccess.needsSync(this)) { WebSyncService.enqueueWork(getApplicationContext(), syncIntent); getApplicationContext().startService(syncIntent); } return true; } catch (LocationHelper.LoggerException e) { Loading Loading @@ -139,8 +126,8 @@ public class LoggerService extends Service { if (intent != null && intent.getBooleanExtra(UPDATED_PREFS, false)) { handlePrefsUpdated(); } else { final Notification notification = showNotification(NOTIFICATION_ID); startForeground(NOTIFICATION_ID, notification); final Notification notification = notificationHelper.showNotification(); startForeground(notificationHelper.getId(), notification); if (!initializeLocationUpdates()) { setRunning(false); stopSelf(); Loading Loading @@ -191,7 +178,7 @@ public class LoggerService extends Service { setRunning(false); notificationManager.cancel(NOTIFICATION_ID); notificationHelper.cancelNotification(); sendBroadcast(BROADCAST_LOCATION_STOPPED); if (thread != null) { Loading Loading @@ -245,47 +232,6 @@ public class LoggerService extends Service { lastLocation = null; } /** * Show notification * @param mId Notification Id */ @SuppressWarnings("SameParameterValue") private Notification showNotification(int mId) { if (Logger.DEBUG) { Log.d(TAG, "[showNotification " + mId + "]"); } final String channelId = String.valueOf(mId); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel(channelId); } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.ic_stat_notify_24dp) .setContentTitle(getString(R.string.app_name)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_SERVICE) .setContentText(String.format(getString(R.string.is_running), getString(R.string.app_name))); Intent resultIntent = new Intent(this, MainActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); Notification mNotification = mBuilder.build(); notificationManager.notify(mId, mNotification); return mNotification; } /** * Create notification channel * @param channelId Channel Id */ @RequiresApi(Build.VERSION_CODES.O) private void createNotificationChannel(String channelId) { NotificationChannel chan = new NotificationChannel(channelId, getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH); notificationManager.createNotificationChannel(chan); } /** * Send broadcast message * @param broadcast Broadcast message Loading Loading @@ -315,7 +261,7 @@ public class LoggerService extends Service { DbAccess.writeLocation(LoggerService.this, location); sendBroadcast(BROADCAST_LOCATION_UPDATED); if (locationHelper.isLiveSync()) { WebSyncService.enqueueWork(getApplicationContext(), syncIntent); getApplicationContext().startService(syncIntent); } } } Loading
app/src/main/java/net/fabiszewski/ulogger/MainFragment.java +4 −4 Original line number Diff line number Diff line Loading @@ -9,6 +9,9 @@ package net.fabiszewski.ulogger; import static net.fabiszewski.ulogger.Alert.showAlert; import static net.fabiszewski.ulogger.Alert.showConfirm; import android.Manifest; import android.app.Activity; import android.content.BroadcastReceiver; Loading Loading @@ -49,9 +52,6 @@ import java.util.Date; import java.util.Locale; import java.util.TimeZone; import static net.fabiszewski.ulogger.Alert.showAlert; import static net.fabiszewski.ulogger.Alert.showConfirm; @SuppressWarnings("WeakerAccess") public class MainFragment extends Fragment { Loading Loading @@ -297,7 +297,7 @@ public class MainFragment extends Fragment { showToast(getString(R.string.provide_user_pass_url)); } else if (DbAccess.needsSync(context)) { Intent syncIntent = new Intent(context, WebSyncService.class); WebSyncService.enqueueWork(context, syncIntent); context.startService(syncIntent); showToast(getString(R.string.uploading_started)); isUploading = true; } else { Loading
app/src/main/java/net/fabiszewski/ulogger/NotificationHelper.java 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (c) 2021 Bartek Fabiszewski * http://www.fabiszewski.net * * This file is part of μlogger-android. * Licensed under GPL, either version 3, or any later. * See <http://www.gnu.org/licenses/> */ package net.fabiszewski.ulogger; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Build; import android.util.Log; import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import androidx.core.app.TaskStackBuilder; class NotificationHelper { private static final String TAG = NotificationHelper.class.getSimpleName(); private final int NOTIFICATION_ID = 1526756640; private final NotificationManager notificationManager; private final Context context; /** * Constructor * @param ctx Context */ NotificationHelper(Context ctx) { context = ctx; notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null) { notificationManager.cancelAll(); } } /** * Show notification * @param mId Notification Id */ Notification showNotification() { if (Logger.DEBUG) { Log.d(TAG, "[showNotification " + NOTIFICATION_ID + "]"); } final String channelId = String.valueOf(NOTIFICATION_ID); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel(channelId); } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_stat_notify_24dp) .setContentTitle(context.getString(R.string.app_name)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_SERVICE) .setContentText(String.format(context.getString(R.string.is_running), context.getString(R.string.app_name))); Intent resultIntent = new Intent(context, MainActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); Notification mNotification = mBuilder.build(); notificationManager.notify(NOTIFICATION_ID, mNotification); return mNotification; } /** * Create notification channel * @param channelId Channel Id */ @RequiresApi(Build.VERSION_CODES.O) private void createNotificationChannel(String channelId) { NotificationChannel channel = new NotificationChannel(channelId, context.getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH); notificationManager.createNotificationChannel(channel); } /** * Cancel notification */ void cancelNotification() { notificationManager.cancel(NOTIFICATION_ID); } /** * Get notification ID * @return Notification ID */ int getId() { return NOTIFICATION_ID; } }
app/src/main/java/net/fabiszewski/ulogger/WebSyncService.java +88 −29 Original line number Diff line number Diff line Loading @@ -9,17 +9,27 @@ package net.fabiszewski.ulogger; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import android.app.AlarmManager; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.JobIntentService; import androidx.annotation.Nullable; import org.json.JSONException; Loading @@ -34,49 +44,56 @@ import java.util.HashMap; import java.util.Map; /** * Service synchronizing local database positions with remote server. * * Service synchronizing local database positions with remote server */ public class WebSyncService extends JobIntentService { public class WebSyncService extends Service { private static final String TAG = WebSyncService.class.getSimpleName(); public static final String BROADCAST_SYNC_FAILED = "net.fabiszewski.ulogger.broadcast.sync_failed"; public static final String BROADCAST_SYNC_DONE = "net.fabiszewski.ulogger.broadcast.sync_done"; private HandlerThread thread; private ServiceHandler serviceHandler; private DbAccess db; private WebHelper web; private static PendingIntent pi = null; final private static int FIVE_MINUTES = 1000 * 60 * 5; static final int JOB_ID = 1001; private NotificationHelper notificationHelper; /** * Convenience method for enqueuing work in to this service. * Basic initializations * Start looper to process uploads */ static void enqueueWork(Context context, Intent work) { enqueueWork(context, WebSyncService.class, JOB_ID, work); } @Override public void onCreate() { super.onCreate(); if (Logger.DEBUG) { Log.d(TAG, "[websync create]"); } web = new WebHelper(this); notificationHelper = new NotificationHelper(this); thread = new HandlerThread("WebSyncThread", THREAD_PRIORITY_BACKGROUND); thread.start(); Looper looper = thread.getLooper(); serviceHandler = new ServiceHandler(looper); // keep database open during whole service runtime db = DbAccess.getInstance(); db.open(this); } /** * Handle synchronization intent * @param intent Intent * Handler to do synchronization on background thread */ @Override protected void onHandleWork(@NonNull Intent intent) { if (Logger.DEBUG) { Log.d(TAG, "[websync start]"); } private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { cancelPending(); if (!WebHelper.isAuthorized) { Loading @@ -84,6 +101,7 @@ public class WebSyncService extends JobIntentService { web.authorize(); } catch (WebAuthException|IOException|JSONException e) { handleError(e); stopSelf(msg.arg1); return; } } Loading @@ -93,6 +111,31 @@ public class WebSyncService extends JobIntentService { if (trackId > 0) { doSync(trackId); } stopSelf(msg.arg1); } } /** * Start foreground service * * @param intent Intent * @param flags Flags * @param startId Unique id * @return Always returns START_STICKY */ @Override public int onStartCommand(@NonNull Intent intent, int flags, int startId) { if (Logger.DEBUG) { Log.d(TAG, "[websync start]"); } final Notification notification = notificationHelper.showNotification(); startForeground(notificationHelper.getId(), notification); Message msg = serviceHandler.obtainMessage(); msg.arg1 = startId; serviceHandler.sendMessage(msg); return START_STICKY; } /** Loading Loading @@ -212,7 +255,11 @@ public class WebSyncService extends JobIntentService { if (Logger.DEBUG) { Log.d(TAG, "[websync set alarm]"); } AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent syncIntent = new Intent(getApplicationContext(), WebSyncService.class); pi = PendingIntent.getService(this, 0, syncIntent, FLAG_ONE_SHOT); int flags = FLAG_ONE_SHOT; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { flags |= FLAG_IMMUTABLE; } pi = PendingIntent.getService(this, 0, syncIntent, flags); if (am != null) { am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + FIVE_MINUTES, pi); } Loading Loading @@ -284,7 +331,19 @@ public class WebSyncService extends JobIntentService { if (db != null) { db.close(); } super.onDestroy(); notificationHelper.cancelNotification(); if (thread != null) { thread.interrupt(); thread = null; } } @Nullable @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not implemented"); } }