Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Status widget #431

Merged
merged 9 commits into from
Aug 24, 2023
14 changes: 14 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@
</intent-filter>
</receiver>

<receiver
android:name=".StatusWidget"
android:label="@string/widget_label"
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"
android:resource="@xml/status_widget_info" />
</receiver>

</application>

</manifest>
65 changes: 65 additions & 0 deletions app/src/main/java/org/traccar/client/StatusWidget.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2016 - 2023 Anton Tananaev ([email protected]), Anton-V-K
Anton-V-K marked this conversation as resolved.
Show resolved Hide resolved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.traccar.client

import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.widget.RemoteViews

import androidx.preference.PreferenceManager

class StatusWidget : AppWidgetProvider() {

override fun onReceive(context: Context, intent: Intent) {
if (TrackingService.ACTION_STARTED == intent.action)
updateWidgets(context, true)
else if (TrackingService.ACTION_STOPPED == intent.action)
updateWidgets(context, false)
else
super.onReceive(context, intent)
Anton-V-K marked this conversation as resolved.
Show resolved Hide resolved
}

override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val enabled = prefs.getBoolean(MainFragment.KEY_STATUS, false)
update(context, appWidgetManager, appWidgetIds, enabled)
}

fun updateWidgets(context: Context, enabled: Boolean) {
val manager = AppWidgetManager.getInstance(context)
val appWidgetIds = manager.getAppWidgetIds(ComponentName(context, StatusWidget::class.java.name))
update(context, manager, appWidgetIds, enabled)
}

private fun update(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, enabled: Boolean) {
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)

val intent = Intent(context, MainActivity::class.java)
val clickIntent = PendingIntent.getActivity(context,0, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
views.setOnClickPendingIntent(R.id.image_enabled, clickIntent)

appWidgetManager.updateAppWidget(appWidgetId, views)
}
}

}
8 changes: 6 additions & 2 deletions app/src/main/java/org/traccar/client/TrackingService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class TrackingService : Service() {
override fun onCreate() {
startForeground(NOTIFICATION_ID, createNotification(this))
Log.i(TAG, "service create")
sendBroadcast(Intent(ACTION_STARTED))
// Explicit package name is required here for manifest-declared receiver of the status widget
// Refer to https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers
sendBroadcast(Intent(ACTION_STARTED).setPackage(packageName))
StatusActivity.addMessage(getString(R.string.status_service_create))

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Expand Down Expand Up @@ -90,7 +92,9 @@ class TrackingService : Service() {
override fun onDestroy() {
stopForeground(true)
Log.i(TAG, "service destroy")
sendBroadcast(Intent(ACTION_STOPPED))
// Explicit package name is required here for manifest-declared receiver of the status widget
// Refer to https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers
Anton-V-K marked this conversation as resolved.
Show resolved Hide resolved
sendBroadcast(Intent(ACTION_STOPPED).setPackage(packageName))
StatusActivity.addMessage(getString(R.string.status_service_destroy))
if (wakeLock?.isHeld == true) {
wakeLock?.release()
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/layout/status_widget.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?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/image_enabled"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/settings_status_title"
android:src="@android:drawable/ic_menu_help"
app:srcCompat="@mipmap/ic_launcher" />
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +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">Shows the service status</string>
<string name="widget_label">Status widget</string>
</resources>
9 changes: 9 additions & 0 deletions app/src/main/res/xml/status_widget_info.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/widget_description"
android:initialKeyguardLayout="@layout/status_widget"
android:initialLayout="@layout/status_widget"
android:previewImage="@mipmap/ic_launcher"
android:previewLayout="@layout/status_widget"
android:resizeMode="none"
android:updatePeriodMillis="0" />