mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-29 05:07:40 +00:00
Added support for devices with more than one external storage
BUG: 336043
This commit is contained in:
parent
5912611aab
commit
5b2756b7f8
101
src/main/java/org/kde/kdeconnect/Helpers/StorageHelper.java
Normal file
101
src/main/java/org/kde/kdeconnect/Helpers/StorageHelper.java
Normal file
@ -0,0 +1,101 @@
|
||||
package org.kde.kdeconnect.Helpers;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
//Code from http://stackoverflow.com/questions/9340332/how-can-i-get-the-list-of-mounted-external-storage-of-android-device/19982338#19982338
|
||||
public class StorageHelper {
|
||||
|
||||
private static final String TAG = "StorageHelper";
|
||||
|
||||
public static class StorageInfo {
|
||||
|
||||
public final String path;
|
||||
public final boolean readonly;
|
||||
public final boolean removable;
|
||||
public final int number;
|
||||
|
||||
StorageInfo(String path, boolean readonly, boolean removable, int number) {
|
||||
this.path = path;
|
||||
this.readonly = readonly;
|
||||
this.removable = removable;
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<StorageInfo> getStorageList() {
|
||||
|
||||
List<StorageInfo> list = new ArrayList<StorageInfo>();
|
||||
String def_path = Environment.getExternalStorageDirectory().getPath();
|
||||
boolean def_path_removable = Environment.isExternalStorageRemovable();
|
||||
String def_path_state = Environment.getExternalStorageState();
|
||||
boolean def_path_available = def_path_state.equals(Environment.MEDIA_MOUNTED)
|
||||
|| def_path_state.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
|
||||
boolean def_path_readonly = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY);
|
||||
|
||||
HashSet<String> paths = new HashSet<String>();
|
||||
int cur_removable_number = 1;
|
||||
|
||||
if (def_path_available) {
|
||||
paths.add(def_path);
|
||||
list.add(0, new StorageInfo(def_path, def_path_readonly, def_path_removable, def_path_removable ? cur_removable_number++ : -1));
|
||||
}
|
||||
|
||||
BufferedReader buf_reader = null;
|
||||
try {
|
||||
buf_reader = new BufferedReader(new FileReader("/proc/mounts"));
|
||||
String line;
|
||||
Log.d(TAG, "/proc/mounts");
|
||||
while ((line = buf_reader.readLine()) != null) {
|
||||
Log.d(TAG, line);
|
||||
if (line.contains("vfat") || line.contains("/mnt")) {
|
||||
StringTokenizer tokens = new StringTokenizer(line, " ");
|
||||
String unused = tokens.nextToken(); //device
|
||||
String mount_point = tokens.nextToken(); //mount point
|
||||
if (paths.contains(mount_point)) {
|
||||
continue;
|
||||
}
|
||||
unused = tokens.nextToken(); //file system
|
||||
List<String> flags = Arrays.asList(tokens.nextToken().split(",")); //flags
|
||||
boolean readonly = flags.contains("ro");
|
||||
|
||||
if (line.contains("/dev/block/vold")) {
|
||||
if (!line.contains("/mnt/secure")
|
||||
&& !line.contains("/mnt/asec")
|
||||
&& !line.contains("/mnt/obb")
|
||||
&& !line.contains("/dev/mapper")
|
||||
&& !line.contains("tmpfs")) {
|
||||
paths.add(mount_point);
|
||||
list.add(new StorageInfo(mount_point, readonly, true, cur_removable_number++));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
if (buf_reader != null) {
|
||||
try {
|
||||
buf_reader.close();
|
||||
} catch (IOException ex) {}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
@ -7,10 +7,15 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Environment;
|
||||
import android.widget.Button;
|
||||
|
||||
import org.kde.kdeconnect.Helpers.StorageHelper;
|
||||
import org.kde.kdeconnect.NetworkPackage;
|
||||
import org.kde.kdeconnect.Plugins.Plugin;
|
||||
import org.kde.kdeconnect_tp.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SftpPlugin extends Plugin {
|
||||
|
||||
private static final SimpleSftpServer server = new SimpleSftpServer();
|
||||
@ -39,7 +44,7 @@ public class SftpPlugin extends Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledByDefault() {return true;}
|
||||
public boolean isEnabledByDefault() { return true; }
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
@ -58,13 +63,56 @@ public class SftpPlugin extends Plugin {
|
||||
|
||||
if (np.getBoolean("startBrowsing")) {
|
||||
if (server.start()) {
|
||||
|
||||
NetworkPackage np2 = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SFTP);
|
||||
|
||||
np2.set("ip", server.getLocalIpAddress());
|
||||
np2.set("port", server.port);
|
||||
np2.set("user", server.passwordAuth.getUser());
|
||||
np2.set("password", server.passwordAuth.getPassword());
|
||||
|
||||
//Kept for compatibility, but new desktop clients will read "multiPaths" instead,
|
||||
// that supports devices with more than one external storage
|
||||
np2.set("path", Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
|
||||
List<StorageHelper.StorageInfo> storageList = StorageHelper.getStorageList();
|
||||
ArrayList<String> paths = new ArrayList<String>();
|
||||
ArrayList<String> pathNames = new ArrayList<String>();
|
||||
|
||||
for (StorageHelper.StorageInfo storage : storageList) {
|
||||
paths.add(storage.path);
|
||||
StringBuilder res = new StringBuilder();
|
||||
|
||||
if (storageList.size() > 1) {
|
||||
if (!storage.removable) {
|
||||
res.append(context.getString(R.string.sftp_internal_storage));
|
||||
} else if (storage.number > 1) {
|
||||
res.append(context.getString(R.string.sftp_sdcard_num, storage.number));
|
||||
} else {
|
||||
res.append(context.getString(R.string.sftp_sdcard));
|
||||
}
|
||||
} else {
|
||||
res.append(context.getString(R.string.sftp_all_files));
|
||||
}
|
||||
if (storage.readonly) {
|
||||
res.append(" ");
|
||||
res.append(context.getString(R.string.sftp_readonly));
|
||||
}
|
||||
pathNames.add(res.toString());
|
||||
}
|
||||
|
||||
//Shortcut for users that only want to browse camera pictures
|
||||
String cameraDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera";
|
||||
if (new File(cameraDir).exists()) {
|
||||
paths.add(cameraDir);
|
||||
pathNames.add(context.getString(R.string.sftp_camera));
|
||||
}
|
||||
|
||||
np2.set("multiPaths", paths);
|
||||
np2.set("pathNames", pathNames);
|
||||
|
||||
device.sendPackage(np2);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -72,9 +120,9 @@ public class SftpPlugin extends Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlertDialog getErrorDialog(Activity deviceActivity) {return null;}
|
||||
public AlertDialog getErrorDialog(Activity deviceActivity) { return null; }
|
||||
|
||||
@Override
|
||||
public Button getInterfaceButton(Activity activity) {return null;}
|
||||
public Button getInterfaceButton(Activity activity) { return null; }
|
||||
|
||||
}
|
||||
|
@ -89,6 +89,12 @@
|
||||
<string name="shareplugin_text_saved">Received text, saved to clipboard</string>
|
||||
<string name="share_notification_preference">Noisy notifications</string>
|
||||
<string name="share_notification_preference_summary">Vibrate and play a sound when receiving a file</string>
|
||||
<string name="sftp_internal_storage">Internal storage</string>
|
||||
<string name="sftp_all_files">All files</string>
|
||||
<string name="sftp_sdcard_num">SD card %d</string>
|
||||
<string name="sftp_sdcard">SD card</string>
|
||||
<string name="sftp_readonly">(read only)</string>
|
||||
<string name="sftp_camera">Camera pictures</string>
|
||||
|
||||
<string-array name="mpris_time_entries">
|
||||
<item>10 seconds</item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user