2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-22 09:58:08 +00:00

This reverts commit 0fc5d0907827451092afed17fb04dc1b3417e316.

This commit is contained in:
Anjani Kumar 2020-04-18 03:09:30 +05:30
parent 7ddb647aa1
commit 34c80314ed
8 changed files with 126 additions and 104 deletions

View File

@ -135,6 +135,11 @@
<!-- Plugin-related activities and services -->
<activity
android:name="org.kde.kdeconnect.Plugins.ClibpoardPlugin.ClipboardFloatingActivity"
android:theme="@style/Theme.Transparent"
android:excludeFromRecents="true"/>
<activity
android:name="org.kde.kdeconnect.Plugins.MprisPlugin.MprisActivity"
android:label="@string/open_mpris_controls"

View File

@ -9,6 +9,7 @@
<string name="kde_connect">KDE Connect</string>
<string name="foreground_notification_no_devices">Not connected to any device</string>
<string name="foreground_notification_devices">Connected to: %s</string>
<string name="foreground_notification_send_clipboard">Send Clipboard</string>
<string name="pref_plugin_telephony">Telephony notifier</string>
<string name="pref_plugin_telephony_desc">Send notifications for incoming calls</string>
<string name="pref_plugin_battery">Battery report</string>
@ -17,6 +18,7 @@
<string name="pref_plugin_sftp_desc">Allows to browse this device\'s filesystem remotely</string>
<string name="pref_plugin_clipboard">Clipboard sync</string>
<string name="pref_plugin_clipboard_desc">Share the clipboard content</string>
<string name="pref_plugin_clipboard_sent">Clipboard Sent</string>
<string name="pref_plugin_mousepad">Remote input</string>
<string name="pref_plugin_mousepad_desc">Use your phone or tablet as a touchpad and keyboard</string>
<string name="pref_plugin_presenter">Slideshow remote</string>

View File

@ -49,4 +49,12 @@
<style name="ActionModeStyle" parent="Widget.AppCompat.ActionMode">
<item name="background">@color/primaryDark</item>
</style>
<style name="Theme.Transparent" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>

View File

@ -44,6 +44,7 @@ import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
import org.kde.kdeconnect.Helpers.NotificationHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import org.kde.kdeconnect.Plugins.ClibpoardPlugin.ClipboardFloatingActivity;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandActivity;
@ -346,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());
}
}
@ -358,20 +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);
// 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

@ -0,0 +1,93 @@
/*
* 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;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.Toast;
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 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();
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();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowManager.LayoutParams wlp = getWindow().getAttributes();
wlp.dimAmount = 0;
wlp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
getWindow().setAttributes(wlp);
ArrayList<String> connectedDeviceIds = getIntent().getStringArrayListExtra("connectedDeviceIds");
if (connectedDeviceIds != null) {
for (String deviceId : connectedDeviceIds) {
connectedDevices.add(BackgroundService.getInstance().getDevice(deviceId));
}
}
}
}

View File

@ -20,15 +20,11 @@
package org.kde.kdeconnect.Plugins.ClibpoardPlugin;
import android.os.Build;
import androidx.fragment.app.DialogFragment;
import androidx.preference.PreferenceManager;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.UserInterface.NoticeAlertDialogFragment;
import org.kde.kdeconnect_tp.R;
@PluginFactory.LoadablePlugin
@ -59,8 +55,6 @@ public class ClipboardPlugin extends Plugin {
*/
private final static String PACKET_TYPE_CLIPBOARD_CONNECT = "kdeconnect.clipboard.connect";
private final static String ANDROID_10_INCOMPAT_DIALOG_SHOWN_PREFERENCE = "android10IncompatDialogShown";
@Override
public String getDisplayName() {
return context.getResources().getString(R.string.pref_plugin_clipboard);
@ -93,7 +87,7 @@ public class ClipboardPlugin extends Plugin {
private final ClipboardListener.ClipboardObserver observer = this::propagateClipboard;
private void propagateClipboard(String content) {
void propagateClipboard(String content) {
NetworkPacket np = new NetworkPacket(ClipboardPlugin.PACKET_TYPE_CLIPBOARD);
np.set("content", content);
device.sendPacket(np);
@ -108,26 +102,9 @@ public class ClipboardPlugin extends Plugin {
device.sendPacket(np);
}
@Override
public boolean checkRequiredPermissions() {
return Build.VERSION.SDK_INT <= Build.VERSION_CODES.P || PreferenceManager.getDefaultSharedPreferences(context).getBoolean(ANDROID_10_INCOMPAT_DIALOG_SHOWN_PREFERENCE, false);
}
@Override
public DialogFragment getPermissionExplanationDialog() {
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(ANDROID_10_INCOMPAT_DIALOG_SHOWN_PREFERENCE, true).apply();
return new NoticeAlertDialogFragment.Builder()
.setTitle(R.string.pref_plugin_clipboard)
.setMessage(R.string.clipboard_android_x_incompat)
.setPositiveButton(R.string.sad_ok)
.create();
}
@Override
public boolean onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return false;
}
ClipboardListener.instance(context).registerObserver(observer);
sendConnectPacket();
return true;

View File

@ -378,12 +378,6 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
}
}
public void reloadCurrentDevicePlugins() {
BackgroundService.RunCommand(this, service -> {
Device device = service.getDevice(mCurrentDevice);
device.reloadPluginsFromSettings();
});
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

View File

@ -1,68 +0,0 @@
/*
* Copyright 2019 Erik Duisters <e.duisters1@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.UserInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import org.kde.kdeconnect_tp.R;
public class NoticeAlertDialogFragment extends AlertDialogFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCallback(new Callback() {
@Override
public void onPositiveButtonClicked() {
//TODO: Find a way to pass this callback from the Builder. For now, this is only used in one place and this is the callback needed.
MainActivity mainActivity = (MainActivity)requireActivity();
mainActivity.reloadCurrentDevicePlugins();
}
});
}
public static class Builder extends AbstractBuilder<Builder, NoticeAlertDialogFragment> {
public Builder() {
super();
setTitle(R.string.pref_plugin_clipboard);
setMessage(R.string.clipboard_android_x_incompat);
setPositiveButton(R.string.sad_ok);
}
@Override
public Builder getThis() {
return this;
}
@Override
protected NoticeAlertDialogFragment createFragment() {
return new NoticeAlertDialogFragment();
}
}
}