mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 01:51:47 +00:00
Use kdeconnect:// url to trigger commands
Summary: Make it possible to trigger commands by opening an URI like kdeconnect://runcommand/<deviceid>/<commandid> Makes it possible to trigger commands from NFC tags. To ease the setup the url can be added to the clipboard Test Plan: Long-press a command entry Select Copy URL to clipboard Write into NFC tag or use kdeconnect-handler to trigger url See command executing Reviewers: #kde_connect, albertvaka Reviewed By: #kde_connect, albertvaka Subscribers: albertvaka, apol, kdeconnect, #kde_connect Tags: #kde_connect Differential Revision: https://phabricator.kde.org/D13447
This commit is contained in:
parent
7ab7222f7f
commit
57fc625af9
@ -28,6 +28,7 @@
|
||||
<uses-permission android:name="android.permission.READ_SMS" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
|
||||
@ -157,7 +158,22 @@
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
|
||||
|
||||
</activity>
|
||||
|
||||
<activity android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandUrlActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED"></action>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="kdeconnect" android:host="runcommand"/>
|
||||
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
|
8
res/menu/runcommand_context.xml
Normal file
8
res/menu/runcommand_context.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/copy_url_to_clipboard"
|
||||
android:title="@string/copy_url_to_clipboard" />
|
||||
</menu>
|
@ -245,5 +245,11 @@
|
||||
|
||||
<string name="dark_theme">Dark theme</string>
|
||||
<string name="mpris_stop">Stop the current player</string>
|
||||
<string name="copy_url_to_clipboard">Copy URL to clipboard</string>
|
||||
<string name="clipboard_toast">Copied to clipboard</string>
|
||||
<string name="runcommand_notreachable">Device is not reachable</string>
|
||||
<string name="runcommand_notpaired">Device is not paired</string>
|
||||
<string name="runcommand_nosuchdevice">There is no such device</string>
|
||||
<string name="runcommand_noruncommandplugin">This device does not have the Run Command Plugin enabled</string>
|
||||
|
||||
</resources>
|
||||
|
@ -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 org.kde.kdeconnect_tp.R;
|
||||
|
||||
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<ListAdapter.Item> commandItems;
|
||||
|
||||
private void updateView() {
|
||||
BackgroundService.RunCommand(this, service -> {
|
||||
@ -61,7 +69,11 @@ public class RunCommandActivity extends AppCompatActivity {
|
||||
runOnUiThread(() -> {
|
||||
ListView view = (ListView) findViewById(R.id.runcommandslist);
|
||||
|
||||
final ArrayList<ListAdapter.Item> 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 @@ public class RunCommandActivity extends AppCompatActivity {
|
||||
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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user