Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/device_info/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.4.2

* Add systemFeatures to AndroidDeviceInfo.

## 0.4.1+5

* Make the pedantic dev_dependency explicit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -18,24 +18,24 @@ 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
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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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<String, Object> version = new HashMap<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
version.put("baseOS", Build.VERSION.BASE_OS);
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion packages/device_info/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _MyAppState extends State<MyApp> {
'type': build.type,
'isPhysicalDevice': build.isPhysicalDevice,
'androidId': build.androidId,
'systemFeatures': build.systemFeatures,
};
}

Expand Down Expand Up @@ -114,7 +115,6 @@ class _MyAppState extends State<MyApp> {
Platform.isAndroid ? 'Android Device Info' : 'iOS Device Info'),
),
body: ListView(
shrinkWrap: true,
children: _deviceData.keys.map((String property) {
return Row(
children: <Widget>[
Expand All @@ -132,6 +132,7 @@ class _MyAppState extends State<MyApp> {
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
child: Text(
'${_deviceData[property]}',
maxLines: 10,
overflow: TextOverflow.ellipsis,
),
)),
Expand Down
21 changes: 20 additions & 1 deletion packages/device_info/lib/device_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ class AndroidDeviceInfo {
this.type,
this.isPhysicalDevice,
this.androidId,
List<String> systemFeatures,
}) : supported32BitAbis = List<String>.unmodifiable(supported32BitAbis),
supported64BitAbis = List<String>.unmodifiable(supported64BitAbis),
supportedAbis = List<String>.unmodifiable(supportedAbis);
supportedAbis = List<String>.unmodifiable(supportedAbis),
systemFeatures = List<String>.unmodifiable(systemFeatures);

/// Android operating system version values derived from `android.os.Build.VERSION`.
final AndroidBuildVersion version;
Expand Down Expand Up @@ -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<String> systemFeatures;

/// Deserializes from the message received from [_kChannel].
static AndroidDeviceInfo _fromMap(Map<String, dynamic> map) {
return AndroidDeviceInfo._(
Expand All @@ -150,6 +168,7 @@ class AndroidDeviceInfo {
type: map['type'],
isPhysicalDevice: map['isPhysicalDevice'],
androidId: map['androidId'],
systemFeatures: _fromList(map['systemFeatures']),
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/device_info/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down