diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java
index f5fe7a45a..476f28a49 100644
--- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java
+++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ActivityHostApiImpl.java
@@ -3,6 +3,7 @@
import android.app.Activity;
import android.app.AlarmManager;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.PowerManager;
import androidx.annotation.NonNull;
@@ -59,6 +60,8 @@ public class ActivityHostApiImpl implements
private final AlarmManagerFlutterApiImpl alarmManagerFlutterApi;
+ private final PackageManagerFlutterApiImpl packageManagerFlutterApi;
+
/**
* Callbacks to complete a pending permission request.
*
@@ -84,11 +87,13 @@ public class ActivityHostApiImpl implements
public ActivityHostApiImpl(
@NonNull PowerManagerFlutterApiImpl powerManagerFlutterApi,
@NonNull AlarmManagerFlutterApiImpl alarmManagerFlutterApi,
+ @NonNull PackageManagerFlutterApiImpl packageManagerFlutterApi,
@NonNull BinaryMessenger binaryMessenger,
@NonNull InstanceManager instanceManager
) {
- this.alarmManagerFlutterApi = alarmManagerFlutterApi;
this.powerManagerFlutterApi = powerManagerFlutterApi;
+ this.alarmManagerFlutterApi = alarmManagerFlutterApi;
+ this.packageManagerFlutterApi = packageManagerFlutterApi;
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
}
@@ -249,4 +254,19 @@ public boolean onActivityResult(
final UUID systemServiceUuid = instanceManager.getIdentifierForStrongReference(systemService);
return systemServiceUuid.toString();
}
+
+ @Override
+ @NonNull public String getPackageManager(
+ @NonNull String instanceId
+ ) {
+ final UUID instanceUuid = UUID.fromString(instanceId);
+ final Activity activity = instanceManager.getInstance(instanceUuid);
+
+ final PackageManager packageManager = activity.getPackageManager();
+
+ packageManagerFlutterApi.create(packageManager);
+
+ final UUID packageManagerUuid = instanceManager.getIdentifierForStrongReference(packageManager);
+ return packageManagerUuid.toString();
+ }
}
diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java
index a4c8df5ed..4be9cfffa 100644
--- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java
+++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/ContextHostApiImpl.java
@@ -3,6 +3,7 @@
import android.app.AlarmManager;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.PowerManager;
import androidx.annotation.NonNull;
@@ -32,6 +33,8 @@ public class ContextHostApiImpl implements ContextHostApi {
private final AlarmManagerFlutterApiImpl alarmManagerFlutterApi;
+ private final PackageManagerFlutterApiImpl packageManagerFlutterApi;
+
/**
* Constructs an {@link ContextHostApiImpl}.
*
@@ -41,11 +44,13 @@ public class ContextHostApiImpl implements ContextHostApi {
public ContextHostApiImpl(
@NonNull PowerManagerFlutterApiImpl powerManagerFlutterApi,
@NonNull AlarmManagerFlutterApiImpl alarmManagerFlutterApi,
+ @NonNull PackageManagerFlutterApiImpl packageManagerFlutterApi,
@NonNull BinaryMessenger binaryMessenger,
@NonNull InstanceManager instanceManager
) {
this.powerManagerFlutterApi = powerManagerFlutterApi;
this.alarmManagerFlutterApi = alarmManagerFlutterApi;
+ this.packageManagerFlutterApi = packageManagerFlutterApi;
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
}
@@ -104,4 +109,19 @@ public void startActivity(
final UUID systemServiceUuid = instanceManager.getIdentifierForStrongReference(systemService);
return systemServiceUuid.toString();
}
+
+ @Override
+ @NonNull public String getPackageManager(
+ @NonNull String instanceId
+ ) {
+ final UUID instanceUuid = UUID.fromString(instanceId);
+ final Context context = instanceManager.getInstance(instanceUuid);
+
+ final PackageManager packageManager = context.getPackageManager();
+
+ packageManagerFlutterApi.create(packageManager);
+
+ final UUID packageManagerUuid = instanceManager.getIdentifierForStrongReference(packageManager);
+ return packageManagerUuid.toString();
+ }
}
diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PackageManagerFlutterApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PackageManagerFlutterApiImpl.java
new file mode 100644
index 000000000..0b9b0534c
--- /dev/null
+++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PackageManagerFlutterApiImpl.java
@@ -0,0 +1,66 @@
+package com.baseflow.permissionhandler;
+
+import android.content.pm.PackageManager;
+
+import androidx.annotation.NonNull;
+
+import com.baseflow.instancemanager.InstanceManager;
+import com.baseflow.permissionhandler.PermissionHandlerPigeon.PackageManagerFlutterApi;
+
+import java.util.UUID;
+
+import io.flutter.plugin.common.BinaryMessenger;
+
+/**
+ * Flutter API implementation for `PackageManager`.
+ *
+ *
This class may handle adding native instances that are attached to a Dart instance or passing
+ * arguments of callbacks methods to a Dart instance.
+ */
+public class PackageManagerFlutterApiImpl {
+ // To ease adding additional methods, this value is added prematurely.
+ @SuppressWarnings({"unused", "FieldCanBeLocal"})
+ private final BinaryMessenger binaryMessenger;
+
+ private final InstanceManager instanceManager;
+
+ private final PackageManagerFlutterApi api;
+
+ /**
+ * Constructs a {@link PackageManagerFlutterApiImpl}.
+ *
+ * @param binaryMessenger used to communicate with Dart over asynchronous messages
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public PackageManagerFlutterApiImpl(
+ @NonNull BinaryMessenger binaryMessenger,
+ @NonNull InstanceManager instanceManager
+ ) {
+ this.binaryMessenger = binaryMessenger;
+ this.instanceManager = instanceManager;
+ api = new PackageManagerFlutterApi(binaryMessenger);
+ }
+
+ /**
+ * Stores the `PackageManager` instance and notifies Dart to create and store a new
+ * `PackageManager` instance that is attached to this one. If `instance` has already been added,
+ * this method does nothing.
+ */
+ public void create(@NonNull PackageManager instance) {
+ if (!instanceManager.containsInstance(instance)) {
+ final UUID packageManagerInstanceUuid = instanceManager.addHostCreatedInstance(instance);
+ api.create(packageManagerInstanceUuid.toString(), reply -> {});
+ }
+ }
+
+ /**
+ * Disposes of the `PackageManager` instance in the instance manager and notifies Dart to do the
+ * same. If `instance` was already disposed, this method does nothing.
+ */
+ public void dispose(PackageManager instance) {
+ final UUID packageManagerInstanceUuid = instanceManager.getIdentifierForStrongReference(instance);
+ if (packageManagerInstanceUuid != null) {
+ api.dispose(packageManagerInstanceUuid.toString(), reply -> {});
+ }
+ }
+}
diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PackageManagerHostApiImpl.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PackageManagerHostApiImpl.java
new file mode 100644
index 000000000..22f8edb4d
--- /dev/null
+++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PackageManagerHostApiImpl.java
@@ -0,0 +1,52 @@
+package com.baseflow.permissionhandler;
+
+import android.content.pm.PackageManager;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+import com.baseflow.instancemanager.InstanceManager;
+import com.baseflow.permissionhandler.PermissionHandlerPigeon.PackageManagerHostApi;
+
+import java.util.UUID;
+
+import io.flutter.plugin.common.BinaryMessenger;
+
+/**
+ * Host API implementation for `PackageManager`.
+ *
+ *
This class may handle instantiating and adding native object instances that are attached to a
+ * Dart instance or handle method calls on the associated native class or an instance of the class.
+ */
+public class PackageManagerHostApiImpl implements PackageManagerHostApi {
+ // To ease adding additional methods, this value is added prematurely.
+ @SuppressWarnings({"unused", "FieldCanBeLocal"})
+ private final BinaryMessenger binaryMessenger;
+
+ private final InstanceManager instanceManager;
+
+ /**
+ * Constructs an {@link PackageManagerHostApiImpl}.
+ *
+ * @param binaryMessenger used to communicate with Dart over asynchronous messages
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public PackageManagerHostApiImpl(
+ @NonNull BinaryMessenger binaryMessenger,
+ @NonNull InstanceManager instanceManager
+ ) {
+ this.binaryMessenger = binaryMessenger;
+ this.instanceManager = instanceManager;
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ @NonNull
+ @Override
+ public Boolean canRequestPackageInstalls(@NonNull String instanceId) {
+ final UUID instanceUuid = UUID.fromString(instanceId);
+ final PackageManager packageManager = instanceManager.getInstance(instanceUuid);
+
+ return packageManager.canRequestPackageInstalls();
+ }
+}
diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java
index 40c1597cd..bd2d28470 100644
--- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java
+++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPigeon.java
@@ -357,6 +357,13 @@ public interface ActivityHostApi {
* See https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int).
*/
void startActivityForResult(@NonNull String instanceId, @NonNull String intentInstanceId, @Nullable Long requestCode, @NonNull Result result);
+ /**
+ * Returns the instance ID of a PackageManager instance to find global package information.
+ *
+ * See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ */
+ @NonNull
+ String getPackageManager(@NonNull String instanceId);
/** The codec used by ActivityHostApi. */
static @NonNull MessageCodec getCodec() {
@@ -550,6 +557,30 @@ public void error(Throwable error) {
channel.setMessageHandler(null);
}
}
+ {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageManager", getCodec());
+ if (api != null) {
+ channel.setMessageHandler(
+ (message, reply) -> {
+ ArrayList wrapped = new ArrayList();
+ ArrayList args = (ArrayList) message;
+ String instanceIdArg = (String) args.get(0);
+ try {
+ String output = api.getPackageManager(instanceIdArg);
+ wrapped.add(0, output);
+ }
+ catch (Throwable exception) {
+ ArrayList wrappedError = wrapError(exception);
+ wrapped = wrappedError;
+ }
+ reply.reply(wrapped);
+ });
+ } else {
+ channel.setMessageHandler(null);
+ }
+ }
}
}
/**
@@ -641,6 +672,13 @@ public interface ContextHostApi {
*/
@NonNull
String getSystemService(@NonNull String instanceId, @NonNull String name);
+ /**
+ * Returns the instance ID of a PackageManager instance to find global package information.
+ *
+ * See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ */
+ @NonNull
+ String getPackageManager(@NonNull String instanceId);
/** The codec used by ContextHostApi. */
static @NonNull MessageCodec getCodec() {
@@ -737,6 +775,30 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable ContextHos
String output = api.getSystemService(instanceIdArg, nameArg);
wrapped.add(0, output);
}
+ catch (Throwable exception) {
+ ArrayList wrappedError = wrapError(exception);
+ wrapped = wrappedError;
+ }
+ reply.reply(wrapped);
+ });
+ } else {
+ channel.setMessageHandler(null);
+ }
+ }
+ {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageManager", getCodec());
+ if (api != null) {
+ channel.setMessageHandler(
+ (message, reply) -> {
+ ArrayList wrapped = new ArrayList();
+ ArrayList args = (ArrayList) message;
+ String instanceIdArg = (String) args.get(0);
+ try {
+ String output = api.getPackageManager(instanceIdArg);
+ wrapped.add(0, output);
+ }
catch (Throwable exception) {
ArrayList wrappedError = wrapError(exception);
wrapped = wrappedError;
@@ -1323,4 +1385,102 @@ public void dispose(@NonNull String instanceIdArg, @NonNull Reply callback
channelReply -> callback.reply(null));
}
}
+ /**
+ * Host API for `PackageManager`.
+ *
+ * This class may handle instantiating and adding native object instances that
+ * are attached to a Dart instance or handle method calls on the associated
+ * native class or an instance of the class.
+ *
+ * See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
+ *
+ * Generated interface from Pigeon that represents a handler of messages from Flutter.
+ */
+ public interface PackageManagerHostApi {
+ /**
+ * Checks whether the calling package is allowed to request package installs through package installer.
+ *
+ * See https://developer.android.com/reference/android/content/pm/PackageManager#canRequestPackageInstalls().
+ */
+ @NonNull
+ Boolean canRequestPackageInstalls(@NonNull String instanceId);
+
+ /** The codec used by PackageManagerHostApi. */
+ static @NonNull MessageCodec getCodec() {
+ return new StandardMessageCodec();
+ }
+ /**Sets up an instance of `PackageManagerHostApi` to handle messages through the `binaryMessenger`. */
+ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PackageManagerHostApi api) {
+ {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.permission_handler_android.PackageManagerHostApi.canRequestPackageInstalls", getCodec());
+ if (api != null) {
+ channel.setMessageHandler(
+ (message, reply) -> {
+ ArrayList wrapped = new ArrayList();
+ ArrayList args = (ArrayList) message;
+ String instanceIdArg = (String) args.get(0);
+ try {
+ Boolean output = api.canRequestPackageInstalls(instanceIdArg);
+ wrapped.add(0, output);
+ }
+ catch (Throwable exception) {
+ ArrayList wrappedError = wrapError(exception);
+ wrapped = wrappedError;
+ }
+ reply.reply(wrapped);
+ });
+ } else {
+ channel.setMessageHandler(null);
+ }
+ }
+ }
+ }
+ /**
+ * Flutter API for `PackageManager`.
+ *
+ * This class may handle instantiating and adding Dart instances that are
+ * attached to a native instance or receiving callback methods from an
+ * overridden native class.
+ *
+ * See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
+ *
+ * Generated class from Pigeon that represents Flutter messages that can be called from Java.
+ */
+ public static class PackageManagerFlutterApi {
+ private final @NonNull BinaryMessenger binaryMessenger;
+
+ public PackageManagerFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) {
+ this.binaryMessenger = argBinaryMessenger;
+ }
+
+ /** Public interface for sending reply. */
+ @SuppressWarnings("UnknownNullness")
+ public interface Reply {
+ void reply(T reply);
+ }
+ /** The codec used by PackageManagerFlutterApi. */
+ static @NonNull MessageCodec getCodec() {
+ return new StandardMessageCodec();
+ }
+ /** Create a new Dart instance and add it to the `InstanceManager`. */
+ public void create(@NonNull String instanceIdArg, @NonNull Reply callback) {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.create", getCodec());
+ channel.send(
+ new ArrayList(Collections.singletonList(instanceIdArg)),
+ channelReply -> callback.reply(null));
+ }
+ /** Dispose of the Dart instance and remove it from the `InstanceManager`. */
+ public void dispose(@NonNull String instanceIdArg, @NonNull Reply callback) {
+ BasicMessageChannel channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.dispose", getCodec());
+ channel.send(
+ new ArrayList(Collections.singletonList(instanceIdArg)),
+ channelReply -> callback.reply(null));
+ }
+ }
}
diff --git a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java
index f76c52c66..012b91b14 100644
--- a/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java
+++ b/permission_handler_android/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java
@@ -15,6 +15,7 @@
import com.baseflow.permissionhandler.PermissionHandlerPigeon.BuildVersionHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.ContextHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.IntentHostApi;
+import com.baseflow.permissionhandler.PermissionHandlerPigeon.PackageManagerHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.PowerManagerHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.UriHostApi;
@@ -67,10 +68,15 @@ private void setUp(
final AlarmManagerHostApi alarmManagerHostApi = new AlarmManagerHostApiImpl(binaryMessenger, instanceManager);
AlarmManagerHostApi.setup(binaryMessenger, alarmManagerHostApi);
+ final PackageManagerFlutterApiImpl packageManagerFlutterApi = new PackageManagerFlutterApiImpl(binaryMessenger, instanceManager);
+ final PackageManagerHostApi packageManagerHostApi = new PackageManagerHostApiImpl(binaryMessenger, instanceManager);
+ PackageManagerHostApi.setup(binaryMessenger, packageManagerHostApi);
+
activityFlutterApi = new ActivityFlutterApiImpl(binaryMessenger, instanceManager);
activityHostApi = new ActivityHostApiImpl(
powerManagerFlutterApi,
alarmManagerFlutterApi,
+ packageManagerFlutterApi,
binaryMessenger,
instanceManager
);
@@ -80,6 +86,7 @@ private void setUp(
final ContextHostApiImpl contextHostApi = new ContextHostApiImpl(
powerManagerFlutterApi,
alarmManagerFlutterApi,
+ packageManagerFlutterApi,
binaryMessenger,
instanceManager
);
diff --git a/permission_handler_android/lib/src/android_object_mirrors/activity.dart b/permission_handler_android/lib/src/android_object_mirrors/activity.dart
index 727f522cd..7c59d83db 100644
--- a/permission_handler_android/lib/src/android_object_mirrors/activity.dart
+++ b/permission_handler_android/lib/src/android_object_mirrors/activity.dart
@@ -62,7 +62,7 @@ class Activity extends JavaObject {
);
}
- /// Determine whether the application has been granted a particular permission.
+ /// Determines whether the application has been granted a particular permission.
///
/// See https://developer.android.com/reference/android/content/ContextWrapper#checkSelfPermission(java.lang.String).
Future checkSelfPermission(
@@ -81,9 +81,9 @@ class Activity extends JavaObject {
/// and
/// https://developer.android.com/reference/androidx/core/app/ActivityCompat.OnRequestPermissionsResultCallback.
Future requestPermissions(
- List permissions,
+ List permissions, {
int? requestCode,
- ) {
+ }) {
return _hostApi.requestPermissionsFromInstance(
this,
permissions,
@@ -91,7 +91,7 @@ class Activity extends JavaObject {
);
}
- /// Launch a new activity.
+ /// Launches a new activity.
///
/// See https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent).
Future startActivity(
@@ -116,9 +116,9 @@ class Activity extends JavaObject {
///
/// See https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int).
Future startActivityForResult(
- Intent intent,
+ Intent intent, {
int? requestCode,
- ) {
+ }) {
return _hostApi.startActivityForResultFromInstance(
this,
intent,
@@ -126,7 +126,7 @@ class Activity extends JavaObject {
);
}
- /// Return the handle to a system-level service by name.
+ /// Returns the handle to a system-level service by name.
///
/// The class of the returned object varies by the requested name.
///
@@ -141,6 +141,15 @@ class Activity extends JavaObject {
name,
);
}
+
+ /// Returns a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ Future getPackageManager() {
+ return _hostApi.getPackageManagerFromInstance(
+ this,
+ );
+ }
}
/// Result of an activity-for-result request.
diff --git a/permission_handler_android/lib/src/android_object_mirrors/context.dart b/permission_handler_android/lib/src/android_object_mirrors/context.dart
index 2f54ba902..445cf2782 100644
--- a/permission_handler_android/lib/src/android_object_mirrors/context.dart
+++ b/permission_handler_android/lib/src/android_object_mirrors/context.dart
@@ -38,7 +38,7 @@ class Context extends JavaObject {
/// receiving intents at a time of your choosing.
static const String alarmService = 'alarm';
- /// Determine whether the application has been granted a particular permission.
+ /// Determines whether the application has been granted a particular permission.
///
/// See https://developer.android.com/reference/android/content/Context#checkSelfPermission(java.lang.String).
Future checkSelfPermission(
@@ -50,7 +50,7 @@ class Context extends JavaObject {
);
}
- /// Launch a new activity.
+ /// Launches a new activity.
///
/// See https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent).
Future startActivity(
@@ -71,7 +71,7 @@ class Context extends JavaObject {
);
}
- /// Return the handle to a system-level service by name.
+ /// Returns the handle to a system-level service by name.
///
/// The class of the returned object varies by the requested name.
///
@@ -84,4 +84,13 @@ class Context extends JavaObject {
name,
);
}
+
+ /// Returns a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ Future getPackageManager() {
+ return _hostApi.getPackageManagerFromInstance(
+ this,
+ );
+ }
}
diff --git a/permission_handler_android/lib/src/android_object_mirrors/package_manager.dart b/permission_handler_android/lib/src/android_object_mirrors/package_manager.dart
index c0e6e5895..56c466c33 100644
--- a/permission_handler_android/lib/src/android_object_mirrors/package_manager.dart
+++ b/permission_handler_android/lib/src/android_object_mirrors/package_manager.dart
@@ -1,10 +1,26 @@
+import 'package:flutter/services.dart';
+import 'package:flutter_instance_manager/flutter_instance_manager.dart';
+
+import '../android_permission_handler_api_impls.dart';
+
/// Class for retrieving various kinds of information related to the application
/// packages that are currently installed on the device. You can find this class
/// through Context#getPackageManager.
///
/// See https://developer.android.com/reference/android/content/pm/PackageManager.
-class PackageManager {
- const PackageManager._();
+class PackageManager extends JavaObject {
+ /// Instantiates an [PackageManager] without creating and attaching to an
+ /// instance of the associated native class.
+ PackageManager.detached({
+ BinaryMessenger? binaryMessenger,
+ InstanceManager? instanceManager,
+ }) : _hostApi = PackageManagerHostApiImpl(
+ binaryMessenger: binaryMessenger,
+ instanceManager: instanceManager,
+ ),
+ super.detached();
+
+ final PackageManagerHostApiImpl _hostApi;
/// Permission check result: this is returned by checkPermission(String, String) if the permission has not been granted to the given package.
///
@@ -15,4 +31,11 @@ class PackageManager {
///
/// Constant Value: 0 (0x00000000)
static const int permissionGranted = 0;
+
+ /// Checks whether the calling package is allowed to request package installs through package installer.
+ ///
+ /// See https://developer.android.com/reference/android/content/pm/PackageManager#canRequestPackageInstalls().
+ Future canRequestPackageInstalls() {
+ return _hostApi.canRequestPackageInstallsFromInstance(this);
+ }
}
diff --git a/permission_handler_android/lib/src/android_permission_handler_api_impls.dart b/permission_handler_android/lib/src/android_permission_handler_api_impls.dart
index 7139d1dc3..23f901a40 100644
--- a/permission_handler_android/lib/src/android_permission_handler_api_impls.dart
+++ b/permission_handler_android/lib/src/android_permission_handler_api_impls.dart
@@ -12,6 +12,7 @@ class AndroidPermissionHandlerFlutterApis {
ContextFlutterApiImpl? contextFlutterApi,
PowerManagerFlutterApiImpl? powerManagerFlutterApi,
AlarmManagerFlutterApiImpl? alarmManagerFlutterApi,
+ PackageManagerFlutterApiImpl? packageManagerFlutterApi,
}) {
this.activityFlutterApi = activityFlutterApi ?? ActivityFlutterApiImpl();
this.contextFlutterApi = contextFlutterApi ?? ContextFlutterApiImpl();
@@ -19,6 +20,8 @@ class AndroidPermissionHandlerFlutterApis {
powerManagerFlutterApi ?? PowerManagerFlutterApiImpl();
this.alarmManagerFlutterApi =
alarmManagerFlutterApi ?? AlarmManagerFlutterApiImpl();
+ this.packageManagerFlutterApi =
+ packageManagerFlutterApi ?? PackageManagerFlutterApiImpl();
}
static bool _haveBeenSetUp = false;
@@ -44,6 +47,9 @@ class AndroidPermissionHandlerFlutterApis {
/// Flutter API for [AlarmManager].
late final AlarmManagerFlutterApiImpl alarmManagerFlutterApi;
+ /// Flutter API for [PackageManager].
+ late final PackageManagerFlutterApiImpl packageManagerFlutterApi;
+
/// Ensures all the Flutter APIs have been setup to receive calls from native code.
void ensureSetUp() {
if (!_haveBeenSetUp) {
@@ -51,6 +57,7 @@ class AndroidPermissionHandlerFlutterApis {
ContextFlutterApi.setup(contextFlutterApi);
PowerManagerFlutterApi.setup(powerManagerFlutterApi);
AlarmManagerFlutterApi.setup(alarmManagerFlutterApi);
+ PackageManagerFlutterApi.setup(packageManagerFlutterApi);
_haveBeenSetUp = true;
}
@@ -202,6 +209,20 @@ class ActivityHostApiImpl extends ActivityHostApi {
return instanceManager.getInstanceWithWeakReference(systemServiceId);
}
+
+ /// Return PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ Future getPackageManagerFromInstance(
+ Activity activity,
+ ) async {
+ final String packageManagerId = await getPackageManager(
+ instanceManager.getIdentifier(activity)!,
+ );
+
+ return instanceManager.getInstanceWithWeakReference(packageManagerId)
+ as PackageManager;
+ }
}
/// Flutter API implementation of Activity.
@@ -299,6 +320,20 @@ class ContextHostApiImpl extends ContextHostApi {
return instanceManager.getInstanceWithWeakReference(systemServiceId);
}
+
+ /// Return PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ Future getPackageManagerFromInstance(
+ Context context,
+ ) async {
+ final String packageManagerId = await getPackageManager(
+ instanceManager.getIdentifier(context)!,
+ );
+
+ return instanceManager.getInstanceWithWeakReference(packageManagerId)
+ as PackageManager;
+ }
}
/// Flutter API implementation of Context.
@@ -593,3 +628,58 @@ class AlarmManagerFlutterApiImpl extends AlarmManagerFlutterApi {
_instanceManager.remove(instanceId);
}
}
+
+/// Host API implementation of PackageManager.
+class PackageManagerHostApiImpl extends PackageManagerHostApi {
+ /// Creates a new instance of [PackageManagerHostApiImpl].
+ PackageManagerHostApiImpl({
+ this.binaryMessenger,
+ InstanceManager? instanceManager,
+ }) : instanceManager = instanceManager ?? JavaObject.globalInstanceManager,
+ super(binaryMessenger: binaryMessenger);
+
+ /// Sends binary data across the Flutter platform barrier.
+ ///
+ /// If it is null, the default BinaryMessenger will be used which routes to
+ /// the host platform.
+ final BinaryMessenger? binaryMessenger;
+
+ /// Maintains instances stored to communicate with native language objects.
+ final InstanceManager instanceManager;
+
+ /// Checks whether the calling package is allowed to request package installs through package installer.
+ ///
+ /// See https://developer.android.com/reference/android/content/pm/PackageManager#canRequestPackageInstalls().
+ Future canRequestPackageInstallsFromInstance(
+ PackageManager packageManager,
+ ) {
+ return canRequestPackageInstalls(
+ instanceManager.getIdentifier(packageManager)!,
+ );
+ }
+}
+
+/// Flutter API implementation of PackageManager.
+class PackageManagerFlutterApiImpl extends PackageManagerFlutterApi {
+ /// Constructs a new instance of [PackageManagerFlutterApiImpl].
+ PackageManagerFlutterApiImpl({
+ InstanceManager? instanceManager,
+ }) : _instanceManager = instanceManager ?? JavaObject.globalInstanceManager;
+
+ /// Maintains instances stored to communicate with native language objects.
+ final InstanceManager _instanceManager;
+
+ @override
+ void create(String instanceId) {
+ final PackageManager packageManager = PackageManager.detached();
+ _instanceManager.addHostCreatedInstance(
+ packageManager,
+ instanceId,
+ );
+ }
+
+ @override
+ void dispose(String instanceId) {
+ _instanceManager.remove(instanceId);
+ }
+}
diff --git a/permission_handler_android/lib/src/permission_handler.pigeon.dart b/permission_handler_android/lib/src/permission_handler.pigeon.dart
index fdf6d0f19..c7b067120 100644
--- a/permission_handler_android/lib/src/permission_handler.pigeon.dart
+++ b/permission_handler_android/lib/src/permission_handler.pigeon.dart
@@ -348,6 +348,37 @@ class ActivityHostApi {
return (replyList[0] as ActivityResultPigeon?)!;
}
}
+
+ /// Returns the instance ID of a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ Future getPackageManager(String arg_instanceId) async {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageManager',
+ codec,
+ binaryMessenger: _binaryMessenger);
+ final List? replyList =
+ await channel.send([arg_instanceId]) as List?;
+ if (replyList == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ );
+ } else if (replyList.length > 1) {
+ throw PlatformException(
+ code: replyList[0]! as String,
+ message: replyList[1] as String?,
+ details: replyList[2],
+ );
+ } else if (replyList[0] == null) {
+ throw PlatformException(
+ code: 'null-error',
+ message: 'Host platform returned null value for non-null return value.',
+ );
+ } else {
+ return (replyList[0] as String?)!;
+ }
+ }
}
/// Flutter API for `Activity`.
@@ -554,6 +585,37 @@ class ContextHostApi {
return (replyList[0] as String?)!;
}
}
+
+ /// Returns the instance ID of a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ Future getPackageManager(String arg_instanceId) async {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageManager',
+ codec,
+ binaryMessenger: _binaryMessenger);
+ final List? replyList =
+ await channel.send([arg_instanceId]) as List?;
+ if (replyList == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ );
+ } else if (replyList.length > 1) {
+ throw PlatformException(
+ code: replyList[0]! as String,
+ message: replyList[1] as String?,
+ details: replyList[2],
+ );
+ } else if (replyList[0] == null) {
+ throw PlatformException(
+ code: 'null-error',
+ message: 'Host platform returned null value for non-null return value.',
+ );
+ } else {
+ return (replyList[0] as String?)!;
+ }
+ }
}
/// Flutter API for `Context`.
@@ -1130,3 +1192,113 @@ abstract class AlarmManagerFlutterApi {
}
}
}
+
+/// Host API for `PackageManager`.
+///
+/// This class may handle instantiating and adding native object instances that
+/// are attached to a Dart instance or handle method calls on the associated
+/// native class or an instance of the class.
+///
+/// See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
+class PackageManagerHostApi {
+ /// Constructor for [PackageManagerHostApi]. The [binaryMessenger] named argument is
+ /// available for dependency injection. If it is left null, the default
+ /// BinaryMessenger will be used which routes to the host platform.
+ PackageManagerHostApi({BinaryMessenger? binaryMessenger})
+ : _binaryMessenger = binaryMessenger;
+ final BinaryMessenger? _binaryMessenger;
+
+ static const MessageCodec codec = StandardMessageCodec();
+
+ /// Checks whether the calling package is allowed to request package installs through package installer.
+ ///
+ /// See https://developer.android.com/reference/android/content/pm/PackageManager#canRequestPackageInstalls().
+ Future canRequestPackageInstalls(String arg_instanceId) async {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.PackageManagerHostApi.canRequestPackageInstalls',
+ codec,
+ binaryMessenger: _binaryMessenger);
+ final List? replyList =
+ await channel.send([arg_instanceId]) as List?;
+ if (replyList == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ );
+ } else if (replyList.length > 1) {
+ throw PlatformException(
+ code: replyList[0]! as String,
+ message: replyList[1] as String?,
+ details: replyList[2],
+ );
+ } else if (replyList[0] == null) {
+ throw PlatformException(
+ code: 'null-error',
+ message: 'Host platform returned null value for non-null return value.',
+ );
+ } else {
+ return (replyList[0] as bool?)!;
+ }
+ }
+}
+
+/// Flutter API for `PackageManager`.
+///
+/// This class may handle instantiating and adding Dart instances that are
+/// attached to a native instance or receiving callback methods from an
+/// overridden native class.
+///
+/// See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
+abstract class PackageManagerFlutterApi {
+ static const MessageCodec codec = StandardMessageCodec();
+
+ /// Create a new Dart instance and add it to the `InstanceManager`.
+ void create(String instanceId);
+
+ /// Dispose of the Dart instance and remove it from the `InstanceManager`.
+ void dispose(String instanceId);
+
+ static void setup(PackageManagerFlutterApi? api,
+ {BinaryMessenger? binaryMessenger}) {
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.create',
+ codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMessageHandler(null);
+ } else {
+ channel.setMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.create was null.');
+ final List args = (message as List?)!;
+ final String? arg_instanceId = (args[0] as String?);
+ assert(arg_instanceId != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.create was null, expected non-null String.');
+ api.create(arg_instanceId!);
+ return;
+ });
+ }
+ }
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.dispose',
+ codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMessageHandler(null);
+ } else {
+ channel.setMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.dispose was null.');
+ final List args = (message as List?)!;
+ final String? arg_instanceId = (args[0] as String?);
+ assert(arg_instanceId != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.PackageManagerFlutterApi.dispose was null, expected non-null String.');
+ api.dispose(arg_instanceId!);
+ return;
+ });
+ }
+ }
+ }
+}
diff --git a/permission_handler_android/lib/src/permission_handler_android.dart b/permission_handler_android/lib/src/permission_handler_android.dart
index b1d5bee7b..cbc15fade 100644
--- a/permission_handler_android/lib/src/permission_handler_android.dart
+++ b/permission_handler_android/lib/src/permission_handler_android.dart
@@ -109,7 +109,7 @@ class PermissionHandlerAndroid extends PermissionHandlerPlatform {
}) async {
final PermissionRequestResult result = await activity.requestPermissions(
permission.manifestStrings,
- requestCode,
+ requestCode: requestCode,
);
final List permissions =
@@ -143,7 +143,7 @@ class PermissionHandlerAndroid extends PermissionHandlerPlatform {
'package:${await _activityManager.applicationContext.getPackageName()}',
),
),
- requestCode,
+ requestCode: requestCode,
);
}
diff --git a/permission_handler_android/pigeons/android_permission_handler.dart b/permission_handler_android/pigeons/android_permission_handler.dart
index ee38f13ec..5cca51b79 100644
--- a/permission_handler_android/pigeons/android_permission_handler.dart
+++ b/permission_handler_android/pigeons/android_permission_handler.dart
@@ -121,6 +121,13 @@ abstract class ActivityHostApi {
String intentInstanceId,
int? requestCode,
);
+
+ /// Returns the instance ID of a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ String getPackageManager(
+ String instanceId,
+ );
}
/// Flutter API for `Activity`.
@@ -182,6 +189,13 @@ abstract class ContextHostApi {
String instanceId,
String name,
);
+
+ /// Returns the instance ID of a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ String getPackageManager(
+ String instanceId,
+ );
}
/// Flutter API for `Context`.
@@ -376,3 +390,34 @@ abstract class AlarmManagerFlutterApi {
/// Dispose of the Dart instance and remove it from the `InstanceManager`.
void dispose(String instanceId);
}
+
+/// Host API for `PackageManager`.
+///
+/// This class may handle instantiating and adding native object instances that
+/// are attached to a Dart instance or handle method calls on the associated
+/// native class or an instance of the class.
+///
+/// See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
+@HostApi(dartHostTestHandler: 'PackageManagerTestHostApi')
+abstract class PackageManagerHostApi {
+ /// Checks whether the calling package is allowed to request package installs through package installer.
+ ///
+ /// See https://developer.android.com/reference/android/content/pm/PackageManager#canRequestPackageInstalls().
+ bool canRequestPackageInstalls(String instanceId);
+}
+
+/// Flutter API for `PackageManager`.
+///
+/// This class may handle instantiating and adding Dart instances that are
+/// attached to a native instance or receiving callback methods from an
+/// overridden native class.
+///
+/// See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
+@FlutterApi()
+abstract class PackageManagerFlutterApi {
+ /// Create a new Dart instance and add it to the `InstanceManager`.
+ void create(String instanceId);
+
+ /// Dispose of the Dart instance and remove it from the `InstanceManager`.
+ void dispose(String instanceId);
+}
diff --git a/permission_handler_android/test/test_permission_handler.pigeon.dart b/permission_handler_android/test/test_permission_handler.pigeon.dart
index 451e85149..a260759d7 100644
--- a/permission_handler_android/test/test_permission_handler.pigeon.dart
+++ b/permission_handler_android/test/test_permission_handler.pigeon.dart
@@ -95,6 +95,11 @@ abstract class ActivityTestHostApi {
Future startActivityForResult(
String instanceId, String intentInstanceId, int? requestCode);
+ /// Returns the instance ID of a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ String getPackageManager(String instanceId);
+
static void setup(ActivityTestHostApi? api,
{BinaryMessenger? binaryMessenger}) {
{
@@ -284,6 +289,29 @@ abstract class ActivityTestHostApi {
});
}
}
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageManager',
+ codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ _testBinaryMessengerBinding!.defaultBinaryMessenger
+ .setMockDecodedMessageHandler(channel, null);
+ } else {
+ _testBinaryMessengerBinding!.defaultBinaryMessenger
+ .setMockDecodedMessageHandler(channel,
+ (Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageManager was null.');
+ final List args = (message as List?)!;
+ final String? arg_instanceId = (args[0] as String?);
+ assert(arg_instanceId != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.ActivityHostApi.getPackageManager was null, expected non-null String.');
+ final String output = api.getPackageManager(arg_instanceId!);
+ return [output];
+ });
+ }
+ }
}
}
@@ -323,6 +351,11 @@ abstract class ContextTestHostApi {
/// See https://developer.android.com/reference/android/content/Context#getSystemService(java.lang.String).
String getSystemService(String instanceId, String name);
+ /// Returns the instance ID of a PackageManager instance to find global package information.
+ ///
+ /// See https://developer.android.com/reference/android/content/Context#getPackageManager().
+ String getPackageManager(String instanceId);
+
static void setup(ContextTestHostApi? api,
{BinaryMessenger? binaryMessenger}) {
{
@@ -428,6 +461,29 @@ abstract class ContextTestHostApi {
});
}
}
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageManager',
+ codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ _testBinaryMessengerBinding!.defaultBinaryMessenger
+ .setMockDecodedMessageHandler(channel, null);
+ } else {
+ _testBinaryMessengerBinding!.defaultBinaryMessenger
+ .setMockDecodedMessageHandler(channel,
+ (Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageManager was null.');
+ final List args = (message as List?)!;
+ final String? arg_instanceId = (args[0] as String?);
+ assert(arg_instanceId != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.ContextHostApi.getPackageManager was null, expected non-null String.');
+ final String output = api.getPackageManager(arg_instanceId!);
+ return [output];
+ });
+ }
+ }
}
}
@@ -831,3 +887,48 @@ abstract class AlarmManagerTestHostApi {
}
}
}
+
+/// Host API for `PackageManager`.
+///
+/// This class may handle instantiating and adding native object instances that
+/// are attached to a Dart instance or handle method calls on the associated
+/// native class or an instance of the class.
+///
+/// See https://developer.android.com/reference/kotlin/android/content/pm/PackageManager.
+abstract class PackageManagerTestHostApi {
+ static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
+ TestDefaultBinaryMessengerBinding.instance;
+ static const MessageCodec codec = StandardMessageCodec();
+
+ /// Checks whether the calling package is allowed to request package installs through package installer.
+ ///
+ /// See https://developer.android.com/reference/android/content/pm/PackageManager#canRequestPackageInstalls().
+ bool canRequestPackageInstalls(String instanceId);
+
+ static void setup(PackageManagerTestHostApi? api,
+ {BinaryMessenger? binaryMessenger}) {
+ {
+ final BasicMessageChannel channel = BasicMessageChannel(
+ 'dev.flutter.pigeon.permission_handler_android.PackageManagerHostApi.canRequestPackageInstalls',
+ codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ _testBinaryMessengerBinding!.defaultBinaryMessenger
+ .setMockDecodedMessageHandler(channel, null);
+ } else {
+ _testBinaryMessengerBinding!.defaultBinaryMessenger
+ .setMockDecodedMessageHandler(channel,
+ (Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.PackageManagerHostApi.canRequestPackageInstalls was null.');
+ final List args = (message as List?)!;
+ final String? arg_instanceId = (args[0] as String?);
+ assert(arg_instanceId != null,
+ 'Argument for dev.flutter.pigeon.permission_handler_android.PackageManagerHostApi.canRequestPackageInstalls was null, expected non-null String.');
+ final bool output = api.canRequestPackageInstalls(arg_instanceId!);
+ return [output];
+ });
+ }
+ }
+ }
+}