mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-30 13:47:41 +00:00
Replace DeviceNames library
The version of the library we used stopped working in 2020 when the names database it tries to download got deleted from the master branch of their Github repo. There's a newer version, but it seems to have lost the fetch-from-the-internet functionality (it only bundles a list of names) and for some reason it crashes when I tested it (I've opened an issue on their repo). Since Google now provides a CSV with all the Android device names that exist, I've replaced the library by my own function that downloads the CSV file (~3MB) in the first run of the app and looks for the name there.
This commit is contained in:
@@ -180,7 +180,6 @@ dependencies {
|
|||||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||||
implementation 'com.google.android.material:material:1.9.0'
|
implementation 'com.google.android.material:material:1.9.0'
|
||||||
implementation 'com.jakewharton:disklrucache:2.0.2' //For caching album art bitmaps
|
implementation 'com.jakewharton:disklrucache:2.0.2' //For caching album art bitmaps
|
||||||
implementation 'com.jaredrummler:android-device-names:1.1.9' //To get a human-friendly device name
|
|
||||||
|
|
||||||
implementation 'org.apache.sshd:sshd-core:0.14.0'
|
implementation 'org.apache.sshd:sshd-core:0.14.0'
|
||||||
implementation 'org.apache.mina:mina-core:2.0.19' //For some reason, makes sshd-core:0.14.0 work without NIO, which isn't available until Android 8 (api 26)
|
implementation 'org.apache.mina:mina-core:2.0.19' //For some reason, makes sshd-core:0.14.0 work without NIO, which isn't available until Android 8 (api 26)
|
||||||
@@ -203,6 +202,8 @@ dependencies {
|
|||||||
implementation 'org.apache.commons:commons-collections4:4.4'
|
implementation 'org.apache.commons:commons-collections4:4.4'
|
||||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||||
|
|
||||||
|
implementation 'com.univocity:univocity-parsers:2.9.1'
|
||||||
|
|
||||||
// Kotlin
|
// Kotlin
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||||
|
@@ -11,14 +11,22 @@ import android.content.Context;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.os.Build;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.jaredrummler.android.device.DeviceName;
|
import com.univocity.parsers.csv.CsvParser;
|
||||||
|
import com.univocity.parsers.csv.CsvParserSettings;
|
||||||
|
|
||||||
import org.kde.kdeconnect.Device;
|
import org.kde.kdeconnect.Device;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -27,10 +35,13 @@ public class DeviceHelper {
|
|||||||
public static final int ProtocolVersion = 7;
|
public static final int ProtocolVersion = 7;
|
||||||
|
|
||||||
public static final String KEY_DEVICE_NAME_PREFERENCE = "device_name_preference";
|
public static final String KEY_DEVICE_NAME_PREFERENCE = "device_name_preference";
|
||||||
|
public static final String KEY_DEVICE_NAME_FETCHED_FROM_THE_INTERNET = "device_name_downloaded_preference";
|
||||||
public static final String KEY_DEVICE_ID_PREFERENCE = "device_id_preference";
|
public static final String KEY_DEVICE_ID_PREFERENCE = "device_id_preference";
|
||||||
|
|
||||||
private static boolean fetchingName = false;
|
private static boolean fetchingName = false;
|
||||||
|
|
||||||
|
public static final String DEVICE_DATABASE = "https://storage.googleapis.com/play_public/supported_devices.csv";
|
||||||
|
|
||||||
private static boolean isTablet() {
|
private static boolean isTablet() {
|
||||||
Configuration config = Resources.getSystem().getConfiguration();
|
Configuration config = Resources.getSystem().getConfiguration();
|
||||||
//This assumes that the values for the screen sizes are consecutive, so XXLARGE > XLARGE > LARGE
|
//This assumes that the values for the screen sizes are consecutive, so XXLARGE > XLARGE > LARGE
|
||||||
@@ -52,35 +63,55 @@ public class DeviceHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//It returns getAndroidDeviceName() if no user-defined name has been set with setDeviceName().
|
|
||||||
public static String getDeviceName(Context context) {
|
public static String getDeviceName(Context context) {
|
||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
// Could use preferences.contains but would need to check for empty String anyway.
|
if (!preferences.contains(KEY_DEVICE_NAME_PREFERENCE)
|
||||||
String deviceName = preferences.getString(KEY_DEVICE_NAME_PREFERENCE, "");
|
&& !preferences.getBoolean(KEY_DEVICE_NAME_FETCHED_FROM_THE_INTERNET, false)
|
||||||
if (deviceName.isEmpty()) {
|
&& !fetchingName) {
|
||||||
//DeviceName.init(context); // Needed in DeviceName 2.x +
|
fetchingName = true;
|
||||||
if (!fetchingName) {
|
DeviceHelper.backgroundFetchDeviceName(context);
|
||||||
fetchingName = true;
|
return Build.MODEL;
|
||||||
DeviceHelper.backgroundFetchDeviceName(context); //Starts a background thread that will eventually update the shared pref
|
|
||||||
}
|
|
||||||
return DeviceName.getDeviceName(); //Temp name while we fetch it from the internet
|
|
||||||
}
|
}
|
||||||
return deviceName;
|
return preferences.getString(KEY_DEVICE_NAME_PREFERENCE, Build.MODEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void backgroundFetchDeviceName(final Context context) {
|
private static void backgroundFetchDeviceName(final Context context) {
|
||||||
DeviceName.with(context).request((info, error) -> {
|
ThreadHelper.execute(() -> {
|
||||||
|
try {
|
||||||
|
URL url = new URL(DEVICE_DATABASE);
|
||||||
|
URLConnection connection = url.openConnection();
|
||||||
|
|
||||||
|
// If we get here we managed to download the file. Mark that as done so we don't try again even if we don't end up finding a name.
|
||||||
|
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
preferences.edit().putBoolean(KEY_DEVICE_NAME_FETCHED_FROM_THE_INTERNET, true).apply();
|
||||||
|
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_16))) {
|
||||||
|
CsvParserSettings settings = new CsvParserSettings();
|
||||||
|
settings.setHeaderExtractionEnabled(true);
|
||||||
|
CsvParser parser = new CsvParser(settings);
|
||||||
|
boolean found = false;
|
||||||
|
for (String[] records : parser.iterate(reader)) {
|
||||||
|
if (records.length < 4) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String buildModel = records[3];
|
||||||
|
if (Build.MODEL.equals(buildModel)) {
|
||||||
|
String deviceName = records[1];
|
||||||
|
Log.i("DeviceHelper", "Got device name: " + deviceName);
|
||||||
|
// Update the shared preference. Places that display the name should be listening to this change and update it
|
||||||
|
setDeviceName(context, deviceName);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
Log.e("DeviceHelper", "Didn't find a device name for " + Build.MODEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
fetchingName = false;
|
fetchingName = false;
|
||||||
if (error != null) {
|
|
||||||
Log.e("DeviceHelper", "Error fetching device name");
|
|
||||||
error.printStackTrace();
|
|
||||||
}
|
|
||||||
if (info != null) {
|
|
||||||
String deviceName = info.getName();
|
|
||||||
Log.i("DeviceHelper", "Got device name: " + deviceName);
|
|
||||||
// Update the shared preference. Places that display the name should be listening to this change and update it
|
|
||||||
setDeviceName(context, deviceName);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user