2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-22 01:51:47 +00:00

Allow having widgets for more than once device

Rewrites the RunCommand widget. Now we can have different widgets for
different devices at the same time. Also removes the startService call
that could cause ForegroundServiceStartNotAllowedException on API 12+.
This commit is contained in:
Albert Vaca Cintora 2023-05-29 14:28:18 +02:00
parent 2fda82cd02
commit 11634b2cde
9 changed files with 312 additions and 308 deletions

View File

@ -202,7 +202,7 @@
android:value="org.kde.kdeconnect.UserInterface.MainActivity" /> android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity> </activity>
<activity <activity
android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandWidgetDeviceSelector" android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandWidgetConfig"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:label="@string/pref_plugin_runcommand" android:label="@string/pref_plugin_runcommand"
android:launchMode="singleTask" android:launchMode="singleTask"
@ -211,12 +211,12 @@
android:theme="@style/Theme.AppCompat.Light.Dialog" /> android:theme="@style/Theme.AppCompat.Light.Dialog" />
<service <service
android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandWidgetDataProviderService" android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.CommandsRemoteViewsService"
android:exported="false" android:exported="false"
android:permission="android.permission.BIND_REMOTEVIEWS" /> android:permission="android.permission.BIND_REMOTEVIEWS" />
<receiver <receiver
android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandWidget" android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandWidgetProvider"
android:label="@string/pref_plugin_runcommand" android:label="@string/pref_plugin_runcommand"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>

View File

@ -7,6 +7,8 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin; package org.kde.kdeconnect.Plugins.RunCommandPlugin;
import static org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandWidgetProviderKt.forceRefreshWidgets;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -129,8 +131,7 @@ public class RunCommandPlugin extends Plugin {
sharedPreferences.edit().putString(KEY_COMMANDS_PREFERENCE + device.getDeviceId(), array.toString()).apply(); sharedPreferences.edit().putString(KEY_COMMANDS_PREFERENCE + device.getDeviceId(), array.toString()).apply();
} }
Intent updateWidget = new Intent(context, RunCommandWidget.class); forceRefreshWidgets(context);
context.sendBroadcast(updateWidget);
} catch (JSONException e) { } catch (JSONException e) {
Log.e("RunCommand", "Error parsing JSON", e); Log.e("RunCommand", "Error parsing JSON", e);

View File

@ -1,149 +0,0 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin;
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.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.KdeConnect;
import org.kde.kdeconnect_tp.R;
import java.util.concurrent.ConcurrentHashMap;
public class RunCommandWidget extends AppWidgetProvider {
public static final String RUN_COMMAND_ACTION = "RUN_COMMAND_ACTION";
public static final String TARGET_COMMAND = "TARGET_COMMAND";
public static final String TARGET_DEVICE = "TARGET_DEVICE";
private static final String SET_CURRENT_DEVICE = "SET_CURRENT_DEVICE";
private static String currentDeviceId;
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent != null && intent.getAction() != null && intent.getAction().equals(RUN_COMMAND_ACTION)) {
final String targetCommand = intent.getStringExtra(TARGET_COMMAND);
final String targetDevice = intent.getStringExtra(TARGET_DEVICE);
RunCommandPlugin plugin = KdeConnect.getInstance().getDevicePlugin(targetDevice, RunCommandPlugin.class);
if (plugin != null) {
try {
plugin.runCommand(targetCommand);
} catch (Exception ex) {
Log.e("RunCommandWidget", "Error running command", ex);
}
}
} else if (intent != null && TextUtils.equals(intent.getAction(), SET_CURRENT_DEVICE)) {
setCurrentDevice(context);
}
try {
// FIXME: Remove the need for a background service, we are not allowed to start them in API 31+
final Intent newIntent = new Intent(context, RunCommandWidgetDataProviderService.class);
context.startService(newIntent);
updateWidget(context);
} catch(IllegalStateException exception) { // Meant to catch BackgroundServiceStartNotAllowedException on API 31+
exception.printStackTrace();
}
}
private void setCurrentDevice(final Context context) {
Intent popup = new Intent(context, RunCommandWidgetDeviceSelector.class);
popup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(popup);
}
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
updateWidget(context);
}
private void updateWidget(final Context context) {
Device device = getCurrentDevice();
if (device == null || !device.isReachable()) {
ConcurrentHashMap<String, Device> devices = KdeConnect.getInstance().getDevices();
if (devices.size() > 0) {
currentDeviceId = devices.elements().nextElement().getDeviceId();
}
}
updateWidgetImpl(context);
}
private void updateWidgetImpl(Context context) {
try {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, RunCommandWidget.class));
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_remotecommandplugin);
PendingIntent pendingIntent;
Intent intent;
intent = new Intent(context, RunCommandWidget.class);
intent.setAction(SET_CURRENT_DEVICE);
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
views.setOnClickPendingIntent(R.id.runcommandWidgetTitleHeader, pendingIntent);
Device device = getCurrentDevice();
if (device == null || !device.isReachable()) {
views.setTextViewText(R.id.runcommandWidgetTitle, context.getString(R.string.kde_connect));
views.setViewVisibility(R.id.run_commands_list, View.GONE);
views.setViewVisibility(R.id.not_reachable_message, View.VISIBLE);
} else {
views.setTextViewText(R.id.runcommandWidgetTitle, device.getName());
views.setViewVisibility(R.id.run_commands_list, View.VISIBLE);
views.setViewVisibility(R.id.not_reachable_message, View.GONE);
}
for (int appWidgetId : appWidgetIds) {
intent = new Intent(context, RunCommandWidgetDataProviderService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
views.setRemoteAdapter(R.id.run_commands_list, intent);
intent = new Intent(context, RunCommandWidget.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
views.setPendingIntentTemplate(R.id.run_commands_list, pendingIntent);
AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, views);
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.run_commands_list);
}
} catch (Exception ex) {
Log.e("RunCommandWidget", "Error updating widget", ex);
}
KdeConnect.getInstance().addDeviceListChangedCallback("RunCommandWidget", () -> {
Intent updateWidget = new Intent(context, RunCommandWidget.class);
context.sendBroadcast(updateWidget);
});
}
public static Device getCurrentDevice() {
return KdeConnect.getInstance().getDevice(currentDeviceId);
}
public static void setCurrentDevice(final String DeviceId) {
currentDeviceId = DeviceId;
}
}

View File

@ -0,0 +1,85 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import org.kde.kdeconnect.Device
import org.kde.kdeconnect.KdeConnect
import org.kde.kdeconnect_tp.R
import org.kde.kdeconnect_tp.databinding.WidgetRemoteCommandPluginDialogBinding
import kotlin.streams.toList
class RunCommandWidgetConfig : AppCompatActivity() {
private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID
override fun onCreate(bundle: Bundle?) {
super.onCreate(bundle)
setResult(RESULT_CANCELED) // Default result
appWidgetId = intent.extras?.getInt(EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish()
return
}
supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
val binding = WidgetRemoteCommandPluginDialogBinding.inflate(layoutInflater)
setContentView(binding.root)
val pairedDevices = KdeConnect.getInstance().devices.values.stream().filter(Device::isPaired).toList()
binding.runCommandsDeviceList.adapter = object : ArrayAdapter<Device>(this, 0, pairedDevices) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view : View = convertView ?: layoutInflater.inflate(R.layout.list_item_with_icon_entry, parent, false)
val device = pairedDevices[position]
view.findViewById<TextView>(R.id.list_item_entry_title).text = device.name
view.findViewById<ImageView>(R.id.list_item_entry_icon).setImageDrawable(device.icon)
return view
}
}
binding.runCommandsDeviceList.setOnItemClickListener { _, _, position, _ ->
val deviceId = pairedDevices[position].deviceId
saveWidgetDeviceIdPref(this, appWidgetId, deviceId)
val appWidgetManager = AppWidgetManager.getInstance(this)
updateAppWidget(this, appWidgetManager, appWidgetId)
val resultValue = Intent()
resultValue.putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
setResult(RESULT_OK, resultValue)
finish()
}
}
}
private const val PREFS_NAME = "org.kde.kdeconnect_tp.WidgetProvider"
private const val PREF_PREFIX_KEY = "appwidget_"
internal fun saveWidgetDeviceIdPref(context: Context, appWidgetId: Int, deviceName: String) {
val prefs = context.getSharedPreferences(PREFS_NAME, 0).edit()
prefs.putString(PREF_PREFIX_KEY + appWidgetId, deviceName)
prefs.apply()
}
internal fun loadWidgetDeviceIdPref(context: Context, appWidgetId: Int): String? {
val prefs = context.getSharedPreferences(PREFS_NAME, 0)
return prefs.getString(PREF_PREFIX_KEY + appWidgetId, null)
}
internal fun deleteWidgetDeviceIdPref(context: Context, appWidgetId: Int) {
val prefs = context.getSharedPreferences(PREFS_NAME, 0).edit()
prefs.remove(PREF_PREFIX_KEY + appWidgetId)
prefs.apply()
}

View File

@ -1,94 +0,0 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
class RunCommandWidgetDataProvider implements RemoteViewsService.RemoteViewsFactory {
private final Context mContext;
public RunCommandWidgetDataProvider(Context context, Intent intent) {
mContext = context;
}
private boolean checkPlugin() {
return RunCommandWidget.getCurrentDevice() != null && RunCommandWidget.getCurrentDevice().isReachable() && RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class) != null;
}
@Override
public void onCreate() {
}
@Override
public void onDataSetChanged() {
}
@Override
public void onDestroy() {
}
@Override
public int getCount() {
return checkPlugin() ? RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class).getCommandItems().size() : 0;
}
@Override
public RemoteViews getViewAt(int i) {
RemoteViews remoteView = new RemoteViews(mContext.getPackageName(), R.layout.list_item_entry);
if (checkPlugin() && RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class).getCommandItems().size() > i) {
CommandEntry listItem = RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class).getCommandItems().get(i);
final Intent configIntent = new Intent(mContext, RunCommandWidget.class);
configIntent.setAction(RunCommandWidget.RUN_COMMAND_ACTION);
configIntent.putExtra(RunCommandWidget.TARGET_COMMAND, listItem.getKey());
configIntent.putExtra(RunCommandWidget.TARGET_DEVICE, RunCommandWidget.getCurrentDevice().getDeviceId());
remoteView.setTextViewText(R.id.list_item_entry_title, listItem.getName());
remoteView.setTextViewText(R.id.list_item_entry_summary, listItem.getCommand());
remoteView.setViewVisibility(R.id.list_item_entry_summary, View.VISIBLE);
remoteView.setOnClickFillInIntent(R.id.list_item_entry, configIntent);
}
return remoteView;
}
@Override
public RemoteViews getLoadingView() {
return null;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public long getItemId(int i) {
int id = 0;
if (RunCommandWidget.getCurrentDevice() != null) {
RunCommandPlugin plugin = RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class);
if (plugin != null) {
ArrayList<CommandEntry> items = plugin.getCommandItems();
id = items.get(i).getKey().hashCode();
}
}
return id;
}
@Override
public boolean hasStableIds() {
return false;
}
}

View File

@ -0,0 +1,83 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.View
import android.widget.RemoteViews
import android.widget.RemoteViewsService
import android.widget.RemoteViewsService.RemoteViewsFactory
import org.kde.kdeconnect.KdeConnect
import org.kde.kdeconnect_tp.R
internal class RunCommandWidgetDataProvider(private val context: Context, val intent: Intent?) : RemoteViewsFactory {
private lateinit var deviceId : String
private var widgetId : Int = AppWidgetManager.INVALID_APPWIDGET_ID
override fun onCreate() {
widgetId = intent?.getIntExtra(EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID
if (widgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
Log.e("KDEConnect/Widget", "RunCommandWidgetDataProvider: No widget id extra set")
return
}
deviceId = loadWidgetDeviceIdPref(context, widgetId)!!
}
override fun onDataSetChanged() {}
override fun onDestroy() {}
override fun getCount(): Int {
return KdeConnect.getInstance().getDevicePlugin(deviceId, RunCommandPlugin::class.java)?.commandItems?.size ?: 0
}
override fun getViewAt(i: Int): RemoteViews {
val remoteView = RemoteViews(context.packageName, R.layout.list_item_entry)
val plugin : RunCommandPlugin? = KdeConnect.getInstance().getDevicePlugin(deviceId, RunCommandPlugin::class.java)
if (plugin == null) {
Log.e("getViewAt", "RunCommandWidgetDataProvider: Plugin not found");
return remoteView
}
val listItem = plugin.commandItems[i]
remoteView.setTextViewText(R.id.list_item_entry_title, listItem.name)
remoteView.setTextViewText(R.id.list_item_entry_summary, listItem.command)
remoteView.setViewVisibility(R.id.list_item_entry_summary, View.VISIBLE)
val runCommandIntent = Intent(context, RunCommandWidgetProvider::class.java)
runCommandIntent.action = RUN_COMMAND_ACTION
runCommandIntent.putExtra(EXTRA_APPWIDGET_ID, widgetId)
runCommandIntent.putExtra(TARGET_COMMAND, listItem.key)
runCommandIntent.putExtra(TARGET_DEVICE, deviceId)
remoteView.setOnClickFillInIntent(R.id.list_item_entry, runCommandIntent)
return remoteView
}
override fun getLoadingView(): RemoteViews? {
return null
}
override fun getViewTypeCount(): Int {
return 1
}
override fun getItemId(i: Int): Long {
return KdeConnect.getInstance().getDevicePlugin(deviceId, RunCommandPlugin::class.java)?.commandItems?.get(i)?.key?.hashCode()?.toLong() ?: 0
}
override fun hasStableIds(): Boolean {
return false
}
}
class CommandsRemoteViewsService : RemoteViewsService() {
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
return RunCommandWidgetDataProvider(this.applicationContext, intent)
}
}

View File

@ -1,12 +0,0 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin;
import android.content.Intent;
import android.widget.RemoteViewsService;
public class RunCommandWidgetDataProviderService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new RunCommandWidgetDataProvider(this, intent);
}
}

View File

@ -1,48 +0,0 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;
import androidx.appcompat.app.AppCompatActivity;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.KdeConnect;
import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect_tp.databinding.WidgetRemoteCommandPluginDialogBinding;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class RunCommandWidgetDeviceSelector extends AppCompatActivity {
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
final WidgetRemoteCommandPluginDialogBinding binding =
WidgetRemoteCommandPluginDialogBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
final List<CommandEntry> deviceItems = KdeConnect.getInstance().getDevices().values().stream()
.filter(Device::isPaired).filter(Device::isReachable)
.map(device -> new CommandEntry(device.getName(), null, device.getDeviceId()))
.sorted(Comparator.comparing(CommandEntry::getName))
.collect(Collectors.toList());
ListAdapter adapter = new ListAdapter(RunCommandWidgetDeviceSelector.this, deviceItems);
binding.runCommandsDeviceList.setAdapter(adapter);
binding.runCommandsDeviceList.setOnItemClickListener((adapterView, viewContent, i, l) -> {
CommandEntry entry = deviceItems.get(i);
RunCommandWidget.setCurrentDevice(entry.getKey());
Intent updateWidget = new Intent(RunCommandWidgetDeviceSelector.this, RunCommandWidget.class);
RunCommandWidgetDeviceSelector.this.sendBroadcast(updateWidget);
finish();
});
}
}

View File

@ -0,0 +1,138 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.util.Log
import android.view.View
import android.widget.RemoteViews
import org.kde.kdeconnect.Device
import org.kde.kdeconnect.KdeConnect
import org.kde.kdeconnect_tp.BuildConfig
import org.kde.kdeconnect_tp.R
const val RUN_COMMAND_ACTION = "RUN_COMMAND_ACTION"
const val TARGET_COMMAND = "TARGET_COMMAND"
const val TARGET_DEVICE = "TARGET_DEVICE"
private const val SET_CURRENT_DEVICE = "SET_CURRENT_DEVICE"
class RunCommandWidgetProvider : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
for (appWidgetId in appWidgetIds) {
deleteWidgetDeviceIdPref(context, appWidgetId)
}
}
override fun onEnabled(context: Context) {
super.onEnabled(context)
KdeConnect.getInstance().addDeviceListChangedCallback("RunCommandWidget") {
forceRefreshWidgets(context)
}
}
override fun onDisabled(context: Context) {
KdeConnect.getInstance().removeDeviceListChangedCallback("RunCommandWidget")
super.onDisabled(context)
}
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
Log.d("WidgetProvider", "onReceive " + intent.action)
val appWidgetId = intent.getIntExtra(EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
Log.e("KDEConnect/Widget", "No widget id extra set")
return
}
if (intent.action == RUN_COMMAND_ACTION) {
val targetCommand = intent.getStringExtra(TARGET_COMMAND)
val targetDevice = intent.getStringExtra(TARGET_DEVICE)
val plugin = KdeConnect.getInstance().getDevicePlugin(targetDevice, RunCommandPlugin::class.java)
if (plugin != null) {
try {
plugin.runCommand(targetCommand)
} catch (ex: Exception) {
Log.e("RunCommandWidget", "Error running command", ex)
}
}
} else if (intent.action == SET_CURRENT_DEVICE) {
val popup = Intent(context, RunCommandWidgetConfig::class.java)
popup.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
popup.putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
context.startActivity(popup)
}
}
}
fun getAllWidgetIds(context : Context) : IntArray {
return AppWidgetManager.getInstance(context).getAppWidgetIds(
ComponentName(context, RunCommandWidgetProvider::class.java)
)
}
fun forceRefreshWidgets(context : Context) {
val intent = Intent(context, RunCommandWidgetProvider::class.java)
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, getAllWidgetIds(context))
context.sendBroadcast(intent)
}
internal fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
Log.d("WidgetProvider", "updateAppWidget")
val deviceId = loadWidgetDeviceIdPref(context, appWidgetId)
val device: Device? = if (deviceId != null) KdeConnect.getInstance().getDevice(deviceId) else null
val views = RemoteViews(BuildConfig.APPLICATION_ID, R.layout.widget_remotecommandplugin)
val setDeviceIntent = Intent(context, RunCommandWidgetProvider::class.java)
setDeviceIntent.putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
setDeviceIntent.action = SET_CURRENT_DEVICE
val setDevicePendingIntent = PendingIntent.getBroadcast(context,0,setDeviceIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
views.setOnClickPendingIntent(R.id.runcommandWidgetTitleHeader, setDevicePendingIntent)
if (device == null) {
views.setTextViewText(R.id.runcommandWidgetTitle, context.getString(R.string.kde_connect))
views.setViewVisibility(R.id.run_commands_list, View.VISIBLE)
views.setViewVisibility(R.id.not_reachable_message, View.GONE)
} else {
views.setTextViewText(R.id.runcommandWidgetTitle, device.name)
if (device.isReachable) {
views.setViewVisibility(R.id.run_commands_list, View.VISIBLE)
views.setViewVisibility(R.id.not_reachable_message, View.GONE)
// Configure remote adapter
val dataProviderIntent = Intent(context, CommandsRemoteViewsService::class.java)
dataProviderIntent.putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
dataProviderIntent.data = Uri.parse(dataProviderIntent.toUri(Intent.URI_INTENT_SCHEME))
views.setRemoteAdapter(R.id.run_commands_list, dataProviderIntent)
// This pending intent allows the remote adapter to call fillInIntent so list items can do things
val runCommandTemplateIntent = Intent(context, RunCommandWidgetProvider::class.java)
runCommandTemplateIntent.action = RUN_COMMAND_ACTION
runCommandTemplateIntent.putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
val runCommandTemplatePendingIntent = PendingIntent.getBroadcast(context, 0, runCommandTemplateIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
views.setPendingIntentTemplate(R.id.run_commands_list, runCommandTemplatePendingIntent)
} else {
views.setViewVisibility(R.id.run_commands_list, View.GONE)
views.setViewVisibility(R.id.not_reachable_message, View.VISIBLE)
}
}
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.run_commands_list)
appWidgetManager.updateAppWidget(appWidgetId, views)
}