diff --git a/packages/device_info/CHANGELOG.md b/packages/device_info/CHANGELOG.md index 00dcd2988bba..68aeed8c2cbf 100644 --- a/packages/device_info/CHANGELOG.md +++ b/packages/device_info/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.2 + +* Add systemFeatures to AndroidDeviceInfo. + ## 0.4.1+5 * Make the pedantic dev_dependency explicit. diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java index 8ad0f5db1851..a0435a46e837 100644 --- a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java +++ b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/DeviceInfoPlugin.java @@ -4,7 +4,7 @@ package io.flutter.plugins.deviceinfo; -import android.content.ContentResolver; +import android.content.Context; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; @@ -18,14 +18,13 @@ public class DeviceInfoPlugin implements FlutterPlugin { /** Plugin registration. */ public static void registerWith(Registrar registrar) { DeviceInfoPlugin plugin = new DeviceInfoPlugin(); - plugin.setupMethodChannel(registrar.messenger(), registrar.context().getContentResolver()); + plugin.setupMethodChannel(registrar.messenger(), registrar.context()); } @Override public void onAttachedToEngine(FlutterPlugin.FlutterPluginBinding binding) { setupMethodChannel( - binding.getFlutterEngine().getDartExecutor(), - binding.getApplicationContext().getContentResolver()); + binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); } @Override @@ -33,9 +32,10 @@ public void onDetachedFromEngine(FlutterPlugin.FlutterPluginBinding binding) { tearDownChannel(); } - private void setupMethodChannel(BinaryMessenger messenger, ContentResolver contentResolver) { + private void setupMethodChannel(BinaryMessenger messenger, Context context) { channel = new MethodChannel(messenger, "plugins.flutter.io/device_info"); - final MethodCallHandlerImpl handler = new MethodCallHandlerImpl(contentResolver); + final MethodCallHandlerImpl handler = + new MethodCallHandlerImpl(context.getContentResolver(), context.getPackageManager()); channel.setMethodCallHandler(handler); } diff --git a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java index 22ea1f0ec85e..800ca6dcddb7 100644 --- a/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java +++ b/packages/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java @@ -6,6 +6,8 @@ import android.annotation.SuppressLint; import android.content.ContentResolver; +import android.content.pm.FeatureInfo; +import android.content.pm.PackageManager; import android.os.Build; import android.provider.Settings; import io.flutter.plugin.common.MethodCall; @@ -20,14 +22,16 @@ */ class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { - private ContentResolver contentResolver; + private final ContentResolver contentResolver; + private final PackageManager packageManager; /** Substitute for missing values. */ private static final String[] EMPTY_STRING_LIST = new String[] {}; - /** Constructs DeviceInfo. The {@code contentResolver} must not be null. */ - MethodCallHandlerImpl(ContentResolver contentResolver) { + /** Constructs DeviceInfo. {@code contentResolver} and {@code packageManager} must not be null. */ + MethodCallHandlerImpl(ContentResolver contentResolver, PackageManager packageManager) { this.contentResolver = contentResolver; + this.packageManager = packageManager; } @Override @@ -60,6 +64,8 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { build.put("isPhysicalDevice", !isEmulator()); build.put("androidId", getAndroidId()); + build.put("systemFeatures", Arrays.asList(getSystemFeatures())); + Map version = new HashMap<>(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { version.put("baseOS", Build.VERSION.BASE_OS); @@ -78,6 +84,18 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { } } + private String[] getSystemFeatures() { + FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures(); + if (featureInfos == null) { + return EMPTY_STRING_LIST; + } + String[] features = new String[featureInfos.length]; + for (int i = 0; i < featureInfos.length; i++) { + features[i] = featureInfos[i].name; + } + return features; + } + /** * Returns the Android hardware device ID that is unique between the device + user and app * signing. This key will change if the app is uninstalled or its data is cleared. Device factory diff --git a/packages/device_info/example/lib/main.dart b/packages/device_info/example/lib/main.dart index 528604b661b0..1c1064aa09ee 100644 --- a/packages/device_info/example/lib/main.dart +++ b/packages/device_info/example/lib/main.dart @@ -85,6 +85,7 @@ class _MyAppState extends State { 'type': build.type, 'isPhysicalDevice': build.isPhysicalDevice, 'androidId': build.androidId, + 'systemFeatures': build.systemFeatures, }; } @@ -114,7 +115,6 @@ class _MyAppState extends State { Platform.isAndroid ? 'Android Device Info' : 'iOS Device Info'), ), body: ListView( - shrinkWrap: true, children: _deviceData.keys.map((String property) { return Row( children: [ @@ -132,6 +132,7 @@ class _MyAppState extends State { padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), child: Text( '${_deviceData[property]}', + maxLines: 10, overflow: TextOverflow.ellipsis, ), )), diff --git a/packages/device_info/lib/device_info.dart b/packages/device_info/lib/device_info.dart index e775227d96d1..25b7d46cdb11 100644 --- a/packages/device_info/lib/device_info.dart +++ b/packages/device_info/lib/device_info.dart @@ -62,9 +62,11 @@ class AndroidDeviceInfo { this.type, this.isPhysicalDevice, this.androidId, + List systemFeatures, }) : supported32BitAbis = List.unmodifiable(supported32BitAbis), supported64BitAbis = List.unmodifiable(supported64BitAbis), - supportedAbis = List.unmodifiable(supportedAbis); + supportedAbis = List.unmodifiable(supportedAbis), + systemFeatures = List.unmodifiable(systemFeatures); /// Android operating system version values derived from `android.os.Build.VERSION`. final AndroidBuildVersion version; @@ -126,6 +128,22 @@ class AndroidDeviceInfo { /// The Android hardware device ID that is unique between the device + user and app signing. final String androidId; + /// Describes what features are available on the current device. + /// + /// This can be used to check if the device has, for example, a front-facing + /// camera, or a touchscreen. However, in many cases this is not the best + /// API to use. For example, if you are interested in bluetooth, this API + /// can tell you if the device has a bluetooth radio, but it cannot tell you + /// if bluetooth is currently enabled, or if you have been granted the + /// necessary permissions to use it. Please *only* use this if there is no + /// other way to determine if a feature is supported. + /// + /// This data comes from Android's PackageManager.getSystemAvailableFeatures, + /// and many of the common feature strings to look for are available in + /// PackageManager's public documentation: + /// https://developer.android.com/reference/android/content/pm/PackageManager + final List systemFeatures; + /// Deserializes from the message received from [_kChannel]. static AndroidDeviceInfo _fromMap(Map map) { return AndroidDeviceInfo._( @@ -150,6 +168,7 @@ class AndroidDeviceInfo { type: map['type'], isPhysicalDevice: map['isPhysicalDevice'], androidId: map['androidId'], + systemFeatures: _fromList(map['systemFeatures']), ); } diff --git a/packages/device_info/pubspec.yaml b/packages/device_info/pubspec.yaml index b862a7de4452..06a530bcaab7 100644 --- a/packages/device_info/pubspec.yaml +++ b/packages/device_info/pubspec.yaml @@ -2,7 +2,7 @@ name: device_info description: Flutter plugin providing detailed information about the device (make, model, etc.), and Android or iOS version the app is running on. homepage: https://github.com/flutter/plugins/tree/master/packages/device_info -version: 0.4.1+5 +version: 0.4.2 flutter: plugin: