2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-28 12:47:43 +00:00

Clipboard Plugin: Added support to send clipboard to multiple devices on Android 10 and later.

This commit is contained in:
Anjani Kumar 2020-04-05 15:22:22 +05:30
parent be34aa6f72
commit b92271105a
2 changed files with 65 additions and 20 deletions

View File

@ -347,10 +347,10 @@ public class BackgroundService extends Service {
}
ArrayList<String> connectedDevices = new ArrayList<>();
ArrayList<String> deviceIds = new ArrayList<>();
ArrayList<String> connectedDeviceIds = new ArrayList<>();
for (Device device : getDevices().values()) {
if (device.isReachable() && device.isPaired()) {
deviceIds.add(device.getDeviceId());
connectedDeviceIds.add(device.getDeviceId());
connectedDevices.add(device.getName());
}
}
@ -359,28 +359,30 @@ public class BackgroundService extends Service {
notification.setContentText(getString(R.string.foreground_notification_no_devices));
} else {
notification.setContentText(getString(R.string.foreground_notification_devices, TextUtils.join(", ", connectedDevices)));
if (deviceIds.size() == 1) {
// Adding an action button to send clipboard manually in Android 10 and later.
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
Intent sendClipboard = new Intent(this, ClipboardFloatingActivity.class);
sendClipboard.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
sendClipboard.putExtra("connectedDeviceIds", connectedDeviceIds);
PendingIntent sendPendingClipboard = PendingIntent.getActivity(this, 3, sendClipboard, PendingIntent.FLAG_UPDATE_CURRENT);
notification.addAction(0, getString(R.string.foreground_notification_send_clipboard), sendPendingClipboard);
}
if (connectedDeviceIds.size() == 1) {
// Adding two action buttons only when there is a single device connected.
// Setting up Send File Intent.
Intent sendFile = new Intent(this, SendFileActivity.class);
sendFile.putExtra("deviceId", deviceIds.get(0));
sendFile.putExtra("deviceId", connectedDeviceIds.get(0));
PendingIntent sendPendingFile = PendingIntent.getActivity(this, 1, sendFile, PendingIntent.FLAG_UPDATE_CURRENT);
notification.addAction(0, getString(R.string.send_files), sendPendingFile);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
Intent sendClipboard = new Intent(this, ClipboardFloatingActivity.class);
sendClipboard.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
sendClipboard.putExtra("deviceId", deviceIds.get(0));
PendingIntent sendPendingClipboard = PendingIntent.getActivity(this, 3, sendClipboard, PendingIntent.FLAG_UPDATE_CURRENT);
notification.addAction(0, getString(R.string.foreground_notification_send_clipboard), sendPendingClipboard);
}
// Checking if there are registered commands and adding the button.
Device device = getDevice(deviceIds.get(0));
Device device = getDevice(connectedDeviceIds.get(0));
RunCommandPlugin plugin = (RunCommandPlugin) device.getPlugin("RunCommandPlugin");
if (plugin != null && !plugin.getCommandList().isEmpty()) {
Intent runCommand = new Intent(this, RunCommandActivity.class);
runCommand.putExtra("deviceId", deviceIds.get(0));
runCommand.putExtra("deviceId", connectedDeviceIds.get(0));
PendingIntent runPendingCommand = PendingIntent.getActivity(this, 2, runCommand, PendingIntent.FLAG_UPDATE_CURRENT);
notification.addAction(0, getString(R.string.pref_plugin_runcommand), runPendingCommand);
}

View File

@ -1,3 +1,23 @@
/*
* Copyright 2020 Anjani Kumar <anjanik012@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.Plugins.ClibpoardPlugin;
import androidx.appcompat.app.AppCompatActivity;
@ -13,24 +33,43 @@ import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
/*
An activity to access the clipboard on Android 10 and later by raising over other apps.
This is invisible and doesn't require any interaction from the user.
This should be called when a change in clipboard is detected. This can be done by manually
when user wants to send the clipboard or by reading system log files which requires a special
privileged permission android.permission.READ_LOGS.
https://developer.android.com/reference/android/Manifest.permission#READ_LOGS
This permission can be gained by only from the adb by the user.
https://www.reddit.com/r/AndroidBusters/comments/fh60lt/how_to_solve_a_problem_with_the_clipboard_on/
Currently this activity is bering triggered from a button in Foreground Notification.
* */
public class ClipboardFloatingActivity extends AppCompatActivity {
private Device device;
private ArrayList<Device> connectedDevices = new ArrayList<>();
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// We are now sure that clipboard can be accessed from here.
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData.Item item;
if (clipboardManager.hasPrimaryClip()) {
item = clipboardManager.getPrimaryClip().getItemAt(0);
String content = item.coerceToText(this).toString();
ClipboardPlugin plugin = (ClipboardPlugin) device.getPlugin("ClipboardPlugin");
plugin.propagateClipboard(content);
for (Device device : connectedDevices) {
ClipboardPlugin clipboardPlugin = (ClipboardPlugin) device.getPlugin("ClipboardPlugin");
if (clipboardPlugin != null) {
clipboardPlugin.propagateClipboard(content);
}
}
Toast.makeText(this, R.string.pref_plugin_clipboard_sent, Toast.LENGTH_SHORT).show();
finish();
}
finish();
}
}
@ -43,8 +82,12 @@ public class ClipboardFloatingActivity extends AppCompatActivity {
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
getWindow().setAttributes(wlp);
String deviceId = getIntent().getStringExtra("deviceId");
device = BackgroundService.getInstance().getDevice(deviceId);
ArrayList<String> connectedDeviceIds = getIntent().getStringArrayListExtra("connectedDeviceIds");
if (connectedDeviceIds != null) {
for (String deviceId : connectedDeviceIds) {
connectedDevices.add(BackgroundService.getInstance().getDevice(deviceId));
}
}
}
}