Index: AndroidManifest.xml
===================================================================
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -30,6 +30,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:paddingStart="12dip"
+ android:id="@+id/list_item_entry">
Index: res/layout/widget_remotecommandplugin.xml
===================================================================
--- res/layout/widget_remotecommandplugin.xml
+++ res/layout/widget_remotecommandplugin.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: res/layout/widget_remotecommandplugin_dialog.xml
===================================================================
--- res/layout/widget_remotecommandplugin_dialog.xml
+++ res/layout/widget_remotecommandplugin_dialog.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
Index: res/xml/remotecommandplugin_widget.xml
===================================================================
--- res/xml/remotecommandplugin_widget.xml
+++ res/xml/remotecommandplugin_widget.xml
@@ -0,0 +1,3 @@
+
+
Index: src/org/kde/kdeconnect/Plugins/RunCommandPlugin/CommandEntry.java
===================================================================
--- src/org/kde/kdeconnect/Plugins/RunCommandPlugin/CommandEntry.java
+++ src/org/kde/kdeconnect/Plugins/RunCommandPlugin/CommandEntry.java
@@ -37,4 +37,8 @@
public String getName() {
return title;
}
+
+ public String getCommand() {
+ return subtitle;
+ }
}
Index: src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandPlugin.java
===================================================================
--- src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandPlugin.java
+++ src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandPlugin.java
@@ -33,6 +33,7 @@
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
public class RunCommandPlugin extends Plugin {
@@ -42,6 +43,7 @@
private ArrayList commandList = new ArrayList<>();
private ArrayList callbacks = new ArrayList<>();
+ private final ArrayList commandItems = new ArrayList<>();
private boolean canAddCommand;
@@ -61,6 +63,10 @@
return commandList;
}
+ public ArrayList getCommandItems() {
+ return commandItems;
+ }
+
@Override
public String getDisplayName() {
return context.getResources().getString(R.string.pref_plugin_runcommand);
@@ -88,6 +94,7 @@
if (np.has("commandList")) {
commandList.clear();
try {
+ commandItems.clear();
JSONObject obj = new JSONObject(np.getString("commandList"));
Iterator keys = obj.keys();
while (keys.hasNext()) {
@@ -95,7 +102,25 @@
JSONObject o = obj.getJSONObject(s);
o.put("key", s);
commandList.add(o);
+
+ try {
+ commandItems.add(
+ new CommandEntry(
+ o.getString("name"),
+ o.getString("command"),
+ o.getString("key")
+ )
+ );
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
}
+
+ Collections.sort(commandItems, (lhs, rhs) -> lhs.getName().compareTo(rhs.getName()) );
+
+ Intent updateWidget = new Intent(context, RunCommandWidget.class);
+ context.sendBroadcast(updateWidget);
+
} catch (JSONException e) {
e.printStackTrace();
}
Index: src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidget.java
===================================================================
--- src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidget.java
+++ src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidget.java
@@ -0,0 +1,151 @@
+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.os.Build;
+import android.support.annotation.RequiresApi;
+import android.util.Log;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import org.kde.kdeconnect.BackgroundService;
+import org.kde.kdeconnect.Device;
+import org.kde.kdeconnect_tp.R;
+
+import java.util.Enumeration;
+
+@RequiresApi( api = Build.VERSION_CODES.ICE_CREAM_SANDWICH )
+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";
+ public 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);
+
+ BackgroundService.RunCommand(context, service -> {
+ RunCommandPlugin plugin = service.getDevice(targetDevice).getPlugin(RunCommandPlugin.class);
+
+ if (plugin != null) {
+ try {
+
+ plugin.runCommand(targetCommand);
+ } catch (Exception ex) {
+ Log.e("RunCommandWidget", "Error running command", ex);
+ }
+ }
+ });
+ } else if (intent != null && intent.getAction() != null && intent.getAction().equals(SET_CURRENT_DEVICE)) {
+ setCurrentDevice(context);
+ }
+
+ final Intent newIntent = new Intent(context, RunCommandWidgetDataProviderService.class);
+ context.startService(newIntent);
+ updateWidget(context);
+
+ }
+
+ 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) {
+
+ if (getCurrentDevice() == null || !getCurrentDevice().isReachable()) {
+
+ BackgroundService.RunCommand(context, service -> {
+ if (service.getDevices().size() > 0)
+ currentDeviceId = service.getDevices().elements().nextElement().getDeviceId();
+
+ updateWidgetImpl(context);
+ });
+ }
+
+ 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);
+ views.setOnClickPendingIntent(R.id.runcommandWidgetTitleHeader, pendingIntent);
+
+ if (getCurrentDevice() == null || !getCurrentDevice().isReachable()) {
+ views.setTextViewText(R.id.runcommandWidgetTitle, context.getString(R.string.pref_plugin_runcommand));
+ views.setViewVisibility(R.id.runcommandslist, View.GONE);
+ views.setViewVisibility(R.id.not_reachable_message, View.VISIBLE);
+ } else {
+ views.setTextViewText(R.id.runcommandWidgetTitle, getCurrentDevice().getName());
+ views.setViewVisibility(R.id.runcommandslist, 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.runcommandslist, intent);
+
+ intent = new Intent(context, RunCommandWidget.class);
+ pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ views.setPendingIntentTemplate(R.id.runcommandslist, pendingIntent);
+
+ AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, views);
+ AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged( appWidgetId, R.id.runcommandslist );
+ }
+
+ } catch (Exception ex) {
+ Log.e("RunCommandWidget", "Error updating widget", ex);
+ }
+ }
+
+ public static Device getCurrentDevice() {
+ try{
+ return BackgroundService.getInstance().getDevice(currentDeviceId);
+ }
+ catch (Exception ex){
+
+ }
+
+ return null;
+ }
+
+ public static void setCurrentDevice(final String DeviceId) {
+ currentDeviceId = DeviceId;
+ }
+}
\ No newline at end of file
Index: src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDataProvider.java
===================================================================
--- src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDataProvider.java
+++ src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDataProvider.java
@@ -0,0 +1,90 @@
+package org.kde.kdeconnect.Plugins.RunCommandPlugin;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.view.View;
+import android.widget.RemoteViews;
+import android.widget.RemoteViewsService;
+
+import org.kde.kdeconnect_tp.R;
+
+
+@RequiresApi( api = Build.VERSION_CODES.ICE_CREAM_SANDWICH )
+public class RunCommandWidgetDataProvider implements RemoteViewsService.RemoteViewsFactory {
+
+ private final Context mContext;
+
+ public RunCommandWidgetDataProvider(Context context, Intent intent) {
+ mContext = context;
+ }
+
+ private boolean checkPlugin() {
+ if (RunCommandWidget.getCurrentDevice() == null || !RunCommandWidget.getCurrentDevice().isReachable())
+ return false;
+
+ return 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()) {
+ 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) {
+ return RunCommandWidget.getCurrentDevice().getPlugin(RunCommandPlugin.class).getCommandItems().get(i).getKey().hashCode();
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+}
\ No newline at end of file
Index: src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDataProviderService.java
===================================================================
--- src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDataProviderService.java
+++ src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDataProviderService.java
@@ -0,0 +1,16 @@
+package org.kde.kdeconnect.Plugins.RunCommandPlugin;
+
+import android.content.Intent;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.widget.RemoteViewsService;
+
+@RequiresApi( api = Build.VERSION_CODES.ICE_CREAM_SANDWICH )
+public class RunCommandWidgetDataProviderService extends RemoteViewsService{
+
+ @Override
+ public RemoteViewsFactory onGetViewFactory( Intent intent ){
+
+ return ( new RunCommandWidgetDataProvider( RunCommandWidgetDataProviderService.this, intent ) );
+ }
+}
\ No newline at end of file
Index: src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDeviceSelector.java
===================================================================
--- src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDeviceSelector.java
+++ src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandWidgetDeviceSelector.java
@@ -0,0 +1,59 @@
+package org.kde.kdeconnect.Plugins.RunCommandPlugin;
+
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.RequiresApi;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Window;
+import android.widget.ListView;
+
+import org.kde.kdeconnect.BackgroundService;
+import org.kde.kdeconnect.Device;
+import org.kde.kdeconnect.UserInterface.List.ListAdapter;
+import org.kde.kdeconnect_tp.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+@RequiresApi( api = Build.VERSION_CODES.ICE_CREAM_SANDWICH )
+public class RunCommandWidgetDeviceSelector extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.widget_remotecommandplugin_dialog);
+
+ BackgroundService.RunCommand(this, service -> runOnUiThread(() -> {
+ ListView view = (ListView) findViewById(R.id.runcommandsdevicelist);
+
+ final ArrayList commandItems = new ArrayList<>();
+
+ for (Device device : service.getDevices().values()) {
+ commandItems.add(
+ new CommandEntry(
+ device.getName(),
+ null,
+ device.getDeviceId()
+ )
+ );
+ }
+
+ Collections.sort(commandItems, (lhs, rhs) -> ((CommandEntry) lhs).getName().compareTo(((CommandEntry) rhs).getName()));
+
+ ListAdapter adapter = new ListAdapter(RunCommandWidgetDeviceSelector.this, commandItems);
+
+ view.setAdapter(adapter);
+ view.setOnItemClickListener((adapterView, viewContent, i, l) -> {
+ CommandEntry entry = (CommandEntry) commandItems.get(i);
+ RunCommandWidget.setCurrentDevice(entry.getKey());
+
+ Intent updateWidget = new Intent(RunCommandWidgetDeviceSelector.this, RunCommandWidget.class);
+ RunCommandWidgetDeviceSelector.this.sendBroadcast(updateWidget);
+
+ finish();
+ });
+ }));
+ }
+}
\ No newline at end of file