diff --git a/AndroidManifest.xml b/AndroidManifest.xml
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -28,6 +28,7 @@
+
@@ -157,7 +158,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -241,5 +241,11 @@
Control your phones media players from another device
Dark theme
+ Copy URL to clipboard
+ Copied to clipboard
+ Device is not reachable
+ Device is not paired
+ There is no such device
+ This device does not have the Run Command Plugin enabled
diff --git a/src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandActivity.java b/src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandActivity.java
--- a/src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandActivity.java
+++ b/src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandActivity.java
@@ -21,15 +21,23 @@
package org.kde.kdeconnect.Plugins.RunCommandPlugin;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.RequiresApi;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
+import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
@@ -41,12 +49,12 @@
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
public class RunCommandActivity extends AppCompatActivity {
private String deviceId;
private final RunCommandPlugin.CommandsChangedCallback commandsChangedCallback = this::updateView;
+ private ArrayList commandItems;
private void updateView() {
BackgroundService.RunCommand(this, service -> {
@@ -61,7 +69,11 @@
runOnUiThread(() -> {
ListView view = (ListView) findViewById(R.id.runcommandslist);
- final ArrayList commandItems = new ArrayList<>();
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ registerForContextMenu(view);
+ }
+
+ commandItems = new ArrayList<>();
for (JSONObject obj : plugin.getCommandList()) {
try {
commandItems.add(new CommandEntry(obj.getString("name"),
@@ -133,6 +145,28 @@
updateView();
}
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.runcommand_context, menu);
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ if (item.getItemId() == R.id.copy_url_to_clipboard) {
+ CommandEntry entry = (CommandEntry) commandItems.get(info.position);
+ String url = "kdeconnect://runcommand/" + deviceId + "/" + entry.getKey();
+ ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+ cm.setText(url);
+ Toast toast = Toast.makeText(this, R.string.clipboard_toast, Toast.LENGTH_SHORT);
+ toast.show();
+ }
+ return false;
+ }
+
@Override
protected void onResume() {
super.onResume();
diff --git a/src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandUrlActivity.java b/src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandUrlActivity.java
new file mode 100644
--- /dev/null
+++ b/src/org/kde/kdeconnect/Plugins/RunCommandPlugin/RunCommandUrlActivity.java
@@ -0,0 +1,75 @@
+package org.kde.kdeconnect.Plugins.RunCommandPlugin;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.Gravity;
+import android.widget.TextView;
+
+import org.kde.kdeconnect.BackgroundService;
+import org.kde.kdeconnect.Device;
+import org.kde.kdeconnect_tp.R;
+
+public class RunCommandUrlActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (getIntent().getAction() != null) {
+ try {
+ Uri uri = getIntent().getData();
+ String deviceId = uri.getPathSegments().get(0);
+
+ BackgroundService.RunCommand(this, service -> {
+ final Device device = service.getDevice(deviceId);
+
+ if(device == null) {
+ error(R.string.runcommand_nosuchdevice);
+ return;
+ }
+
+ if (!device.isPaired()) {
+ error(R.string.runcommand_notpaired);
+ return;
+ }
+
+ if (!device.isReachable()) {
+ error(R.string.runcommand_notreachable);
+ return;
+ }
+
+ final RunCommandPlugin plugin = device.getPlugin(RunCommandPlugin.class);
+ if (plugin == null) {
+ error(R.string.runcommand_noruncommandplugin);
+ return;
+ }
+
+ plugin.runCommand(uri.getPathSegments().get(1));
+ RunCommandUrlActivity.this.finish();
+
+
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
+ Vibrator vibrator = RunCommandUrlActivity.this.getSystemService(Vibrator.class);
+ if(vibrator != null && vibrator.hasVibrator()) {
+ vibrator.vibrate(100);
+ }
+ }
+ });
+ } catch (Exception e) {
+ Log.e("RuncommandPlugin", "Exception", e);
+ }
+ }
+ }
+
+ void error(int message) {
+ TextView view = new TextView(this);
+ view.setText(message);
+ view.setGravity(Gravity.CENTER);
+ setContentView(view);
+ }
+
+}