Skip to content

Commit

Permalink
Status Widget (intents in manifest instead of extra receiver + other …
Browse files Browse the repository at this point in the history
…minor changes) traccar#429
  • Loading branch information
Anton-V-K committed Aug 1, 2023
1 parent aa688b8 commit 963e357
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 42 deletions.
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="org.traccar.action.SERVICE_STARTED" />
<action android:name="org.traccar.action.SERVICE_STOPPED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
Expand Down
60 changes: 20 additions & 40 deletions app/src/main/java/org/traccar/client/StatusWidget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,52 +28,32 @@ import androidx.preference.PreferenceManager
*/
class StatusWidget : AppWidgetProvider() {

override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
update(context, appWidgetManager, appWidgetIds)
override fun onReceive(context: Context, intent: Intent) {
if (TrackingService.ACTION_STARTED == intent.action
|| TrackingService.ACTION_STOPPED == intent.action) {
updateWidgets(context)
}
else
super.onReceive(context, intent)
}

override fun onEnabled(context: Context) {
// When the first widget is created, we want to start receiving service status broadcasts,
// so we can react and change the look
val filter = IntentFilter()
filter.addAction(TrackingService.ACTION_STARTED)
filter.addAction(TrackingService.ACTION_STOPPED)
// Note: we must register through the app context as a workaround
// for 'BroadcastReceiver components are not allowed to register to receive intents'
context.applicationContext.registerReceiver(Companion, filter)
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
update(context, appWidgetManager, appWidgetIds)
}

override fun onDisabled(context: Context) {
// When the last widget is disabled (removed), we stop receiving service status broadcasts
context.applicationContext.unregisterReceiver(Companion)
fun updateWidgets(context: Context) {
val manager = AppWidgetManager.getInstance(context)
val appWidgetIds = manager.getAppWidgetIds(ComponentName(context, StatusWidget::class.java.name))
update(context, manager, appWidgetIds)
}

companion object: BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
if (TrackingService.ACTION_STARTED == intent.action
|| TrackingService.ACTION_STOPPED == intent.action) {
updateWidgets(context)
}
}

// Performs update for all widgets of this class.
fun updateWidgets(context: Context) {
val manager = AppWidgetManager.getInstance(context)
val appWidgetIds = manager.getAppWidgetIds(ComponentName(context, StatusWidget::class.java.name))
update(context, manager, appWidgetIds)
}

// Performs update for the widgets with given identifiers.
internal fun update(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val enabled = prefs.getBoolean(MainFragment.KEY_STATUS, false)
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
val views = RemoteViews(context.packageName, R.layout.status_widget)
views.setImageViewResource(R.id.ivEnabled, if (enabled) R.mipmap.ic_start else R.mipmap.ic_stop)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
internal fun update(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val enabled = prefs.getBoolean(MainFragment.KEY_STATUS, false)
for (appWidgetId in appWidgetIds) {
val views = RemoteViews(context.packageName, R.layout.status_widget)
views.setImageViewResource(R.id.image_enabled, if (enabled) R.mipmap.ic_start else R.mipmap.ic_stop)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/status_widget.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/ivEnabled"
android:id="@+id/image_enabled"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="spacing_normal">16dp</dimen>
<!-- 40dp is the cell width/height in a "standard launcher" -->
<!-- Refer to samples at https://developer.android.com/develop/ui/views/appwidgets -->
<dimen name="widget_min_size">40dp</dimen>
</resources>
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@
<string name="request_exception">To continuously collect location data please turn off battery optimization for the app.</string>
<string name="request_background">To continuously collect location data please enable \"%s\" permission.</string>
<string name="request_background_option">Allow all the time</string>
<string name="widget_description">The widget shows the service status</string>
<string name="widget_description">Shows the service status</string>
<string name="widget_label">Status widget</string>
</resources>

0 comments on commit 963e357

Please sign in to comment.