mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-22 09:58:08 +00:00
Add support for Direct Share targets
As described in https://developer.android.com/training/sharing/direct-share-targets. This makes connected devices with `SharePlugin` enabled show up in Android's Sharesheet and can be directly shared to.
This commit is contained in:
parent
f344586fb6
commit
96ecd620cf
@ -120,6 +120,9 @@ SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name="org.kde.kdeconnect.UserInterface.PluginSettingsActivity"
|
||||
|
13
res/drawable/ic_device_desktop_shortcut.xml
Normal file
13
res/drawable/ic_device_desktop_shortcut.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group android:pivotX="12" android:pivotY="12" android:scaleX="0.66" android:scaleY="0.66">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,2L3,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h7v2L8,20v2h8v-2h-2v-2h7c1.1,0 2,-0.9 2,-2L23,4c0,-1.1 -0.9,-2 -2,-2zM21,16L3,16L3,4h18v12z" />
|
||||
</group>
|
||||
</vector>
|
17
res/drawable/ic_device_laptop_shortcut.xml
Normal file
17
res/drawable/ic_device_laptop_shortcut.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group
|
||||
android:pivotX="12"
|
||||
android:pivotY="12"
|
||||
android:scaleX="0.66"
|
||||
android:scaleY="0.66">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20,18c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2H4C2.9,4 2,4.9 2,6v10c0,1.1 0.9,2 2,2H0v2h24v-2H20zM4,6h16v10H4V6z" />
|
||||
</group>
|
||||
</vector>
|
18
res/drawable/ic_device_phone_shortcut.xml
Normal file
18
res/drawable/ic_device_phone_shortcut.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group
|
||||
android:pivotX="12"
|
||||
android:pivotY="12"
|
||||
android:scaleX="0.66"
|
||||
android:scaleY="0.66">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M16,1L8,1C6.34,1 5,2.34 5,4v16c0,1.66 1.34,3 3,3h8c1.66,0 3,-1.34 3,-3L19,4c0,-1.66 -1.34,-3 -3,-3zM14,21h-4v-1h4v1zM17.25,18L6.75,18L6.75,4h10.5v14z" />
|
||||
|
||||
</group>
|
||||
</vector>
|
18
res/drawable/ic_device_tablet_shortcut.xml
Normal file
18
res/drawable/ic_device_tablet_shortcut.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group
|
||||
android:pivotX="12"
|
||||
android:pivotY="12"
|
||||
android:scaleX="0.66"
|
||||
android:scaleY="0.66">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,4L3,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h18c1.1,0 1.99,-0.9 1.99,-2L23,6c0,-1.1 -0.9,-2 -2,-2zM19,18L5,18L5,6h14v12z" />
|
||||
|
||||
</group>
|
||||
</vector>
|
17
res/drawable/ic_device_tv_shortcut.xml
Normal file
17
res/drawable/ic_device_tv_shortcut.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group
|
||||
android:pivotX="12"
|
||||
android:pivotY="12"
|
||||
android:scaleX="0.66"
|
||||
android:scaleY="0.66">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h5v2h8v-2h5c1.1,0 1.99,-0.9 1.99,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12z" />
|
||||
</group>
|
||||
</vector>
|
7
res/xml/shortcuts.xml
Normal file
7
res/xml/shortcuts.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<share-target android:targetClass="org.kde.kdeconnect.Plugins.SharePlugin.ShareActivity">
|
||||
<data android:mimeType="*/*" />
|
||||
<category android:name="org.kde.kdeconnect.category.SHARE_TARGET" />
|
||||
</share-target>
|
||||
</shortcuts>
|
@ -126,7 +126,7 @@ enum class DeviceType {
|
||||
ContextCompat.getDrawable(context, toDrawableId())!!
|
||||
|
||||
@DrawableRes
|
||||
private fun toDrawableId() =
|
||||
fun toDrawableId() =
|
||||
when (this) {
|
||||
PHONE -> R.drawable.ic_device_phone_32dp
|
||||
TABLET -> R.drawable.ic_device_tablet_32dp
|
||||
@ -135,6 +135,15 @@ enum class DeviceType {
|
||||
else -> R.drawable.ic_device_desktop_32dp
|
||||
}
|
||||
|
||||
fun toShortcutDrawableId() =
|
||||
when (this) {
|
||||
PHONE -> R.drawable.ic_device_phone_shortcut
|
||||
TABLET -> R.drawable.ic_device_tablet_shortcut
|
||||
TV -> R.drawable.ic_device_tv_shortcut
|
||||
LAPTOP -> R.drawable.ic_device_laptop_shortcut
|
||||
else -> R.drawable.ic_device_desktop_shortcut
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun fromString(s: String) =
|
||||
|
@ -8,6 +8,7 @@ package org.kde.kdeconnect.Plugins.SharePlugin;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -160,7 +161,10 @@ public class ShareActivity extends AppCompatActivity {
|
||||
super.onStart();
|
||||
|
||||
final Intent intent = getIntent();
|
||||
final String deviceId = intent.getStringExtra("deviceId");
|
||||
String deviceId = intent.getStringExtra("deviceId");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && deviceId == null) {
|
||||
deviceId = intent.getStringExtra(Intent.EXTRA_SHORTCUT_ID);
|
||||
}
|
||||
|
||||
if (deviceId != null) {
|
||||
SharePlugin plugin = KdeConnect.getInstance().getDevicePlugin(deviceId, SharePlugin.class);
|
||||
|
@ -24,6 +24,10 @@ import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.LocusIdCompat;
|
||||
import androidx.core.content.pm.ShortcutInfoCompat;
|
||||
import androidx.core.content.pm.ShortcutManagerCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
@ -33,6 +37,7 @@ import org.kde.kdeconnect.Helpers.IntentHelper;
|
||||
import org.kde.kdeconnect.NetworkPacket;
|
||||
import org.kde.kdeconnect.Plugins.Plugin;
|
||||
import org.kde.kdeconnect.Plugins.PluginFactory;
|
||||
import org.kde.kdeconnect.UserInterface.MainActivity;
|
||||
import org.kde.kdeconnect.UserInterface.PluginSettingsFragment;
|
||||
import org.kde.kdeconnect.async.BackgroundJob;
|
||||
import org.kde.kdeconnect.async.BackgroundJobHandler;
|
||||
@ -43,6 +48,7 @@ import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -84,11 +90,34 @@ public class SharePlugin extends Plugin {
|
||||
public boolean onCreate() {
|
||||
super.onCreate();
|
||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
Intent shortcutIntent = new Intent(context, MainActivity.class);
|
||||
shortcutIntent.setAction(Intent.ACTION_VIEW);
|
||||
shortcutIntent.putExtra(MainActivity.EXTRA_DEVICE_ID, device.getDeviceId());
|
||||
|
||||
IconCompat icon = IconCompat.createWithResource(context, device.getDeviceType().toShortcutDrawableId());
|
||||
|
||||
ShortcutInfoCompat shortcut = new ShortcutInfoCompat
|
||||
.Builder(context, device.getDeviceId())
|
||||
.setIntent(shortcutIntent)
|
||||
.setIcon(icon)
|
||||
.setShortLabel(device.getName())
|
||||
.setCategories(Set.of("org.kde.kdeconnect.category.SHARE_TARGET"))
|
||||
.setLocusId(new LocusIdCompat(device.getDeviceId()))
|
||||
.build();
|
||||
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut);
|
||||
|
||||
// Deliver URLs previously shared to this device now that it's connected
|
||||
deliverPreviouslySentIntents();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
ShortcutManagerCompat.removeLongLivedShortcuts(context, List.of(device.getDeviceId()));
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void deliverPreviouslySentIntents() {
|
||||
Set<String> currentUrlSet = mSharedPrefs.getStringSet(KEY_UNREACHABLE_URL_LIST + device.getDeviceId(), null);
|
||||
if (currentUrlSet != null) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user