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 @@ -245,5 +245,11 @@ Dark theme Stop the current player + 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,74 @@ +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); + } + +}