Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
permission_handler
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
songyanzhi
permission_handler
Commits
49acc864
Commit
49acc864
authored
Apr 21, 2021
by
Jan-Derk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added MANAGE_EXTERNAL_STORAGE permission
Registered Listeners on plugin level
parent
14368466
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
226 additions
and
203 deletions
+226
-203
permission_handler/CHANGELOG.md
+7
-0
permission_handler/android/build.gradle
+1
-1
permission_handler/android/src/main/java/com/baseflow/permissionhandler/MethodCallHandlerImpl.java
+0
-21
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionConstants.java
+5
-2
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java
+40
-16
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionManager.java
+147
-156
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionUtils.java
+17
-3
permission_handler/example/android/app/build.gradle
+1
-1
permission_handler/example/android/app/src/main/AndroidManifest.xml
+3
-0
permission_handler/example/lib/plugin_example/permission_list.dart
+2
-1
permission_handler/ios/Classes/PermissionHandlerEnums.h
+1
-0
permission_handler/pubspec.yaml
+2
-2
No files found.
permission_handler/CHANGELOG.md
View file @
49acc864
## 7.0.0
This release contains the following
**breaking changes**
:
*
Updated compile SDK version to 30 in the build.gradle for handling the MANAGE_EXTERNAL_STORAGE permission;
*
Added the MANAGE_EXTERNAL_STORAGE permission for Android R and up;
*
Registered listeners on the plugin level to prevent memory leaks or unwanted behaviour.
## 6.1.3
## 6.1.3
*
Implement equality operator on the
`Permission`
class;
*
Implement equality operator on the
`Permission`
class;
...
...
permission_handler/android/build.gradle
View file @
49acc864
...
@@ -28,7 +28,7 @@ project.getTasks().withType(JavaCompile){
...
@@ -28,7 +28,7 @@ project.getTasks().withType(JavaCompile){
apply
plugin:
'com.android.library'
apply
plugin:
'com.android.library'
android
{
android
{
compileSdkVersion
29
compileSdkVersion
30
defaultConfig
{
defaultConfig
{
minSdkVersion
16
minSdkVersion
16
...
...
permission_handler/android/src/main/java/com/baseflow/permissionhandler/MethodCallHandlerImpl.java
View file @
49acc864
...
@@ -6,12 +6,9 @@ import android.content.Context;
...
@@ -6,12 +6,9 @@ import android.content.Context;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
io.flutter.plugin.common.BinaryMessenger
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.plugin.common.MethodChannel.Result
;
import
io.flutter.plugin.common.MethodChannel.Result
;
import
com.baseflow.permissionhandler.PermissionManager.ActivityRegistry
;
import
com.baseflow.permissionhandler.PermissionManager.PermissionRegistry
;
import
java.util.List
;
import
java.util.List
;
...
@@ -35,26 +32,10 @@ final class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
...
@@ -35,26 +32,10 @@ final class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
@Nullable
@Nullable
private
Activity
activity
;
private
Activity
activity
;
@Nullable
private
ActivityRegistry
activityRegistry
;
@Nullable
private
PermissionRegistry
permissionRegistry
;
public
void
setActivity
(
@Nullable
Activity
activity
)
{
public
void
setActivity
(
@Nullable
Activity
activity
)
{
this
.
activity
=
activity
;
this
.
activity
=
activity
;
}
}
public
void
setActivityRegistry
(
@Nullable
ActivityRegistry
activityRegistry
)
{
this
.
activityRegistry
=
activityRegistry
;
}
public
void
setPermissionRegistry
(
@Nullable
PermissionRegistry
permissionRegistry
)
{
this
.
permissionRegistry
=
permissionRegistry
;
}
@Override
@Override
public
void
onMethodCall
(
@NonNull
MethodCall
call
,
@NonNull
final
Result
result
)
public
void
onMethodCall
(
@NonNull
MethodCall
call
,
@NonNull
final
Result
result
)
{
{
...
@@ -91,8 +72,6 @@ final class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
...
@@ -91,8 +72,6 @@ final class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
permissionManager
.
requestPermissions
(
permissionManager
.
requestPermissions
(
permissions
,
permissions
,
activity
,
activity
,
activityRegistry
,
permissionRegistry
,
result:
:
success
,
result:
:
success
,
(
String
errorCode
,
String
errorDescription
)
->
result
.
error
(
(
String
errorCode
,
String
errorDescription
)
->
result
.
error
(
errorCode
,
errorCode
,
...
...
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionConstants.java
View file @
49acc864
...
@@ -8,7 +8,8 @@ import java.lang.annotation.RetentionPolicy;
...
@@ -8,7 +8,8 @@ import java.lang.annotation.RetentionPolicy;
final
class
PermissionConstants
{
final
class
PermissionConstants
{
static
final
String
LOG_TAG
=
"permissions_handler"
;
static
final
String
LOG_TAG
=
"permissions_handler"
;
static
final
int
PERMISSION_CODE
=
24
;
static
final
int
PERMISSION_CODE
=
24
;
static
final
int
PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS
=
5672353
;
static
final
int
PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS
=
209
;
static
final
int
PERMISSION_CODE_MANAGE_EXTERNAL_STORAGE
=
210
;
//PERMISSION_GROUP
//PERMISSION_GROUP
static
final
int
PERMISSION_GROUP_CALENDAR
=
0
;
static
final
int
PERMISSION_GROUP_CALENDAR
=
0
;
...
@@ -33,6 +34,7 @@ final class PermissionConstants {
...
@@ -33,6 +34,7 @@ final class PermissionConstants {
static
final
int
PERMISSION_GROUP_ACTIVITY_RECOGNITION
=
19
;
static
final
int
PERMISSION_GROUP_ACTIVITY_RECOGNITION
=
19
;
static
final
int
PERMISSION_GROUP_UNKNOWN
=
20
;
static
final
int
PERMISSION_GROUP_UNKNOWN
=
20
;
static
final
int
PERMISSION_GROUP_BLUETOOTH
=
21
;
static
final
int
PERMISSION_GROUP_BLUETOOTH
=
21
;
static
final
int
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
=
22
;
@Retention
(
RetentionPolicy
.
SOURCE
)
@Retention
(
RetentionPolicy
.
SOURCE
)
@IntDef
({
@IntDef
({
...
@@ -57,6 +59,7 @@ final class PermissionConstants {
...
@@ -57,6 +59,7 @@ final class PermissionConstants {
PERMISSION_GROUP_ACTIVITY_RECOGNITION
,
PERMISSION_GROUP_ACTIVITY_RECOGNITION
,
PERMISSION_GROUP_UNKNOWN
,
PERMISSION_GROUP_UNKNOWN
,
PERMISSION_GROUP_BLUETOOTH
,
PERMISSION_GROUP_BLUETOOTH
,
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
})
})
@interface
PermissionGroup
{
@interface
PermissionGroup
{
}
}
...
@@ -74,7 +77,7 @@ final class PermissionConstants {
...
@@ -74,7 +77,7 @@ final class PermissionConstants {
PERMISSION_STATUS_GRANTED
,
PERMISSION_STATUS_GRANTED
,
PERMISSION_STATUS_RESTRICTED
,
PERMISSION_STATUS_RESTRICTED
,
PERMISSION_STATUS_LIMITED
,
PERMISSION_STATUS_LIMITED
,
PERMISSION_STATUS_NEVER_ASK_AGAIN
,
PERMISSION_STATUS_NEVER_ASK_AGAIN
})
})
@interface
PermissionStatus
{
@interface
PermissionStatus
{
}
}
...
...
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionHandlerPlugin.java
View file @
49acc864
...
@@ -4,8 +4,6 @@ import android.app.Activity;
...
@@ -4,8 +4,6 @@ import android.app.Activity;
import
android.content.Context
;
import
android.content.Context
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
com.baseflow.permissionhandler.PermissionManager.ActivityRegistry
;
import
com.baseflow.permissionhandler.PermissionManager.PermissionRegistry
;
import
io.flutter.embedding.engine.plugins.FlutterPlugin
;
import
io.flutter.embedding.engine.plugins.FlutterPlugin
;
import
io.flutter.embedding.engine.plugins.activity.ActivityAware
;
import
io.flutter.embedding.engine.plugins.activity.ActivityAware
;
import
io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
;
import
io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
;
...
@@ -23,11 +21,21 @@ import io.flutter.plugin.common.MethodChannel;
...
@@ -23,11 +21,21 @@ import io.flutter.plugin.common.MethodChannel;
*/
*/
public
final
class
PermissionHandlerPlugin
implements
FlutterPlugin
,
ActivityAware
{
public
final
class
PermissionHandlerPlugin
implements
FlutterPlugin
,
ActivityAware
{
private
final
PermissionManager
permissionManager
;
private
MethodChannel
methodChannel
;
private
MethodChannel
methodChannel
;
@SuppressWarnings
(
"deprecation"
)
@Nullable
private
io
.
flutter
.
plugin
.
common
.
PluginRegistry
.
Registrar
pluginRegistrar
;
@Nullable
private
ActivityPluginBinding
pluginBinding
;
@Nullable
@Nullable
private
MethodCallHandlerImpl
methodCallHandler
;
private
MethodCallHandlerImpl
methodCallHandler
;
public
PermissionHandlerPlugin
()
{
this
.
permissionManager
=
new
PermissionManager
();
}
/**
/**
* Registers a plugin implementation that uses the stable {@code io.flutter.plugin.common}
* Registers a plugin implementation that uses the stable {@code io.flutter.plugin.common}
* package.
* package.
...
@@ -38,13 +46,15 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
...
@@ -38,13 +46,15 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
@SuppressWarnings
(
"deprecation"
)
@SuppressWarnings
(
"deprecation"
)
public
static
void
registerWith
(
io
.
flutter
.
plugin
.
common
.
PluginRegistry
.
Registrar
registrar
)
{
public
static
void
registerWith
(
io
.
flutter
.
plugin
.
common
.
PluginRegistry
.
Registrar
registrar
)
{
final
PermissionHandlerPlugin
plugin
=
new
PermissionHandlerPlugin
();
final
PermissionHandlerPlugin
plugin
=
new
PermissionHandlerPlugin
();
plugin
.
pluginRegistrar
=
registrar
;
plugin
.
registerListeners
();
plugin
.
startListening
(
registrar
.
context
(),
registrar
.
messenger
());
plugin
.
startListening
(
registrar
.
context
(),
registrar
.
messenger
());
if
(
registrar
.
activeContext
()
instanceof
Activity
)
{
if
(
registrar
.
activeContext
()
instanceof
Activity
)
{
plugin
.
startListeningToActivity
(
plugin
.
startListeningToActivity
(
registrar
.
activity
(),
registrar
.
activity
()
registrar:
:
addActivityResultListener
,
registrar:
:
addRequestPermissionsResultListener
);
);
}
}
}
}
...
@@ -65,10 +75,11 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
...
@@ -65,10 +75,11 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
@Override
@Override
public
void
onAttachedToActivity
(
@NonNull
ActivityPluginBinding
binding
)
{
public
void
onAttachedToActivity
(
@NonNull
ActivityPluginBinding
binding
)
{
startListeningToActivity
(
startListeningToActivity
(
binding
.
getActivity
(),
binding
.
getActivity
()
binding:
:
addActivityResultListener
,
binding:
:
addRequestPermissionsResultListener
);
);
this
.
pluginBinding
=
binding
;
registerListeners
();
}
}
@Override
@Override
...
@@ -79,6 +90,8 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
...
@@ -79,6 +90,8 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
@Override
@Override
public
void
onDetachedFromActivity
()
{
public
void
onDetachedFromActivity
()
{
stopListeningToActivity
();
stopListeningToActivity
();
deregisterListeners
();
}
}
@Override
@Override
...
@@ -95,7 +108,7 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
...
@@ -95,7 +108,7 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
methodCallHandler
=
new
MethodCallHandlerImpl
(
methodCallHandler
=
new
MethodCallHandlerImpl
(
applicationContext
,
applicationContext
,
new
AppSettingsManager
(),
new
AppSettingsManager
(),
new
PermissionManager
()
,
this
.
permissionManager
,
new
ServiceManager
()
new
ServiceManager
()
);
);
...
@@ -109,22 +122,33 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
...
@@ -109,22 +122,33 @@ public final class PermissionHandlerPlugin implements FlutterPlugin, ActivityAwa
}
}
private
void
startListeningToActivity
(
private
void
startListeningToActivity
(
Activity
activity
,
Activity
activity
ActivityRegistry
activityRegistry
,
PermissionRegistry
permissionRegistry
)
{
)
{
if
(
methodCallHandler
!=
null
)
{
if
(
methodCallHandler
!=
null
)
{
methodCallHandler
.
setActivity
(
activity
);
methodCallHandler
.
setActivity
(
activity
);
methodCallHandler
.
setActivityRegistry
(
activityRegistry
);
methodCallHandler
.
setPermissionRegistry
(
permissionRegistry
);
}
}
}
}
private
void
stopListeningToActivity
()
{
private
void
stopListeningToActivity
()
{
if
(
methodCallHandler
!=
null
)
{
if
(
methodCallHandler
!=
null
)
{
methodCallHandler
.
setActivity
(
null
);
methodCallHandler
.
setActivity
(
null
);
methodCallHandler
.
setActivityRegistry
(
null
);
}
methodCallHandler
.
setPermissionRegistry
(
null
);
}
private
void
registerListeners
()
{
if
(
this
.
pluginRegistrar
!=
null
)
{
this
.
pluginRegistrar
.
addActivityResultListener
(
this
.
permissionManager
);
this
.
pluginRegistrar
.
addRequestPermissionsResultListener
(
this
.
permissionManager
);
}
else
if
(
pluginBinding
!=
null
)
{
this
.
pluginBinding
.
addActivityResultListener
(
this
.
permissionManager
);
this
.
pluginBinding
.
addRequestPermissionsResultListener
(
this
.
permissionManager
);
}
}
private
void
deregisterListeners
()
{
if
(
this
.
pluginBinding
!=
null
)
{
this
.
pluginBinding
.
removeActivityResultListener
(
this
.
permissionManager
);
this
.
pluginBinding
.
removeRequestPermissionsResultListener
(
this
.
permissionManager
);
}
}
}
}
}
}
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionManager.java
View file @
49acc864
...
@@ -6,12 +6,12 @@ import android.content.Intent;
...
@@ -6,12 +6,12 @@ import android.content.Intent;
import
android.content.pm.PackageManager
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.os.Build
;
import
android.os.Environment
;
import
android.os.PowerManager
;
import
android.os.PowerManager
;
import
android.provider.Settings
;
import
android.provider.Settings
;
import
android.util.Log
;
import
android.util.Log
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.VisibleForTesting
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.app.NotificationManagerCompat
;
import
androidx.core.app.NotificationManagerCompat
;
import
androidx.core.content.ContextCompat
;
import
androidx.core.content.ContextCompat
;
...
@@ -23,15 +23,115 @@ import java.util.Map;
...
@@ -23,15 +23,115 @@ import java.util.Map;
import
io.flutter.plugin.common.PluginRegistry
;
import
io.flutter.plugin.common.PluginRegistry
;
final
class
PermissionManager
{
final
class
PermissionManager
implements
PluginRegistry
.
ActivityResultListener
,
PluginRegistry
.
RequestPermissionsResultListener
{
@FunctionalInterface
interface
ActivityRegistry
{
@Nullable
void
addListener
(
PluginRegistry
.
ActivityResultListener
handler
);
private
ErrorCallback
errorCallback
;
@Nullable
private
RequestPermissionsSuccessCallback
successCallback
;
@Nullable
private
Activity
activity
;
private
Map
<
Integer
,
Integer
>
requestResults
;
@Override
public
boolean
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
if
(
requestCode
!=
PermissionConstants
.
PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS
&&
requestCode
!=
PermissionConstants
.
PERMISSION_CODE_MANAGE_EXTERNAL_STORAGE
)
{
return
false
;
}
int
status
=
resultCode
==
Activity
.
RESULT_OK
?
PermissionConstants
.
PERMISSION_STATUS_GRANTED
:
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
int
permission
;
if
(
requestCode
==
PermissionConstants
.
PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS
)
{
permission
=
PermissionConstants
.
PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS
;
}
else
if
(
requestCode
==
PermissionConstants
.
PERMISSION_CODE_MANAGE_EXTERNAL_STORAGE
)
{
status
=
Environment
.
isExternalStorageManager
()
?
PermissionConstants
.
PERMISSION_STATUS_GRANTED
:
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
permission
=
PermissionConstants
.
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
;
}
else
{
return
false
;
}
HashMap
<
Integer
,
Integer
>
results
=
new
HashMap
<>();
results
.
put
(
permission
,
status
);
successCallback
.
onSuccess
(
results
);
return
true
;
}
}
@FunctionalInterface
@Override
interface
PermissionRegistry
{
public
boolean
onRequestPermissionsResult
(
int
requestCode
,
String
[]
permissions
,
int
[]
grantResults
)
{
void
addListener
(
PluginRegistry
.
RequestPermissionsResultListener
handler
);
if
(
requestCode
!=
PermissionConstants
.
PERMISSION_CODE
)
{
ongoing
=
false
;
return
false
;
}
for
(
int
i
=
0
;
i
<
permissions
.
length
;
i
++)
{
final
String
permissionName
=
permissions
[
i
];
@PermissionConstants
.
PermissionGroup
final
int
permission
=
PermissionUtils
.
parseManifestName
(
permissionName
);
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_UNKNOWN
)
continue
;
final
int
result
=
grantResults
[
i
];
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_MICROPHONE
)
{
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_MICROPHONE
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_MICROPHONE
,
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
));
}
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_SPEECH
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_SPEECH
,
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
));
}
}
else
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
)
{
@PermissionConstants
.
PermissionStatus
int
permissionStatus
=
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
);
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
,
permissionStatus
);
}
}
else
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_LOCATION
)
{
@PermissionConstants
.
PermissionStatus
int
permissionStatus
=
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
);
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
Q
)
{
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
,
permissionStatus
);
}
}
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_WHEN_IN_USE
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_WHEN_IN_USE
,
permissionStatus
);
}
requestResults
.
put
(
permission
,
permissionStatus
);
}
else
if
(!
requestResults
.
containsKey
(
permission
))
{
requestResults
.
put
(
permission
,
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
));
}
PermissionUtils
.
updatePermissionShouldShowStatus
(
this
.
activity
,
permission
);
}
this
.
successCallback
.
onSuccess
(
requestResults
);
ongoing
=
false
;
return
true
;
}
}
@FunctionalInterface
@FunctionalInterface
...
@@ -67,8 +167,6 @@ final class PermissionManager {
...
@@ -67,8 +167,6 @@ final class PermissionManager {
void
requestPermissions
(
void
requestPermissions
(
List
<
Integer
>
permissions
,
List
<
Integer
>
permissions
,
Activity
activity
,
Activity
activity
,
ActivityRegistry
activityRegistry
,
PermissionRegistry
permissionRegistry
,
RequestPermissionsSuccessCallback
successCallback
,
RequestPermissionsSuccessCallback
successCallback
,
ErrorCallback
errorCallback
)
{
ErrorCallback
errorCallback
)
{
if
(
ongoing
)
{
if
(
ongoing
)
{
...
@@ -87,7 +185,11 @@ final class PermissionManager {
...
@@ -87,7 +185,11 @@ final class PermissionManager {
return
;
return
;
}
}
Map
<
Integer
,
Integer
>
requestResults
=
new
HashMap
<>();
this
.
errorCallback
=
errorCallback
;
this
.
successCallback
=
successCallback
;
this
.
activity
=
activity
;
this
.
requestResults
=
new
HashMap
<>();
ArrayList
<
String
>
permissionsToRequest
=
new
ArrayList
<>();
ArrayList
<
String
>
permissionsToRequest
=
new
ArrayList
<>();
for
(
Integer
permission
:
permissions
)
{
for
(
Integer
permission
:
permissions
)
{
@PermissionConstants
.
PermissionStatus
final
int
permissionStatus
=
determinePermissionStatus
(
permission
,
activity
,
activity
);
@PermissionConstants
.
PermissionStatus
final
int
permissionStatus
=
determinePermissionStatus
(
permission
,
activity
,
activity
);
...
@@ -111,21 +213,30 @@ final class PermissionManager {
...
@@ -111,21 +213,30 @@ final class PermissionManager {
}
else
{
}
else
{
requestResults
.
put
(
permission
,
PermissionConstants
.
PERMISSION_STATUS_DENIED
);
requestResults
.
put
(
permission
,
PermissionConstants
.
PERMISSION_STATUS_DENIED
);
}
}
// On Android below R, the android.permission.MANAGE_EXTERNAL_STORAGE flag in AndroidManifest.xml
// may be ignored and not visible to the App as it's a new permission setting as a whole.
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
&&
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
R
)
{
requestResults
.
put
(
permission
,
PermissionConstants
.
PERMISSION_STATUS_RESTRICTED
);
}
else
{
requestResults
.
put
(
permission
,
PermissionConstants
.
PERMISSION_STATUS_DENIED
);
}
}
}
continue
;
continue
;
}
}
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
M
&&
permission
==
PermissionConstants
.
PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
M
&&
permission
==
PermissionConstants
.
PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS
)
{
activityRegistry
.
addListener
(
new
ActivityResultListener
(
successCallback
)
);
String
packageName
=
activity
.
getPackageName
();
String
packageName
=
activity
.
getPackageName
();
Intent
intent
=
new
Intent
();
Intent
intent
=
new
Intent
();
intent
.
setAction
(
Settings
.
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
);
intent
.
setAction
(
Settings
.
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
);
intent
.
setData
(
Uri
.
parse
(
"package:"
+
packageName
));
intent
.
setData
(
Uri
.
parse
(
"package:"
+
packageName
));
activity
.
startActivityForResult
(
intent
,
PermissionConstants
.
PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS
);
activity
.
startActivityForResult
(
intent
,
PermissionConstants
.
PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS
);
}
else
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
R
&&
permission
==
PermissionConstants
.
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
)
{
String
packageName
=
activity
.
getPackageName
();
Intent
intent
=
new
Intent
();
intent
.
setAction
(
Settings
.
ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
);
intent
.
setData
(
Uri
.
parse
(
"package:"
+
packageName
));
activity
.
startActivityForResult
(
intent
,
PermissionConstants
.
PERMISSION_CODE_MANAGE_EXTERNAL_STORAGE
);
}
else
{
}
else
{
permissionsToRequest
.
addAll
(
names
);
permissionsToRequest
.
addAll
(
names
);
}
}
...
@@ -133,16 +244,6 @@ final class PermissionManager {
...
@@ -133,16 +244,6 @@ final class PermissionManager {
final
String
[]
requestPermissions
=
permissionsToRequest
.
toArray
(
new
String
[
0
]);
final
String
[]
requestPermissions
=
permissionsToRequest
.
toArray
(
new
String
[
0
]);
if
(
permissionsToRequest
.
size
()
>
0
)
{
if
(
permissionsToRequest
.
size
()
>
0
)
{
permissionRegistry
.
addListener
(
new
RequestPermissionsListener
(
activity
,
requestResults
,
(
Map
<
Integer
,
Integer
>
results
)
->
{
ongoing
=
false
;
successCallback
.
onSuccess
(
results
);
})
);
ongoing
=
true
;
ongoing
=
true
;
ActivityCompat
.
requestPermissions
(
ActivityCompat
.
requestPermissions
(
...
@@ -166,7 +267,7 @@ final class PermissionManager {
...
@@ -166,7 +267,7 @@ final class PermissionManager {
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_NOTIFICATION
)
{
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_NOTIFICATION
)
{
return
checkNotificationPermissionStatus
(
context
);
return
checkNotificationPermissionStatus
(
context
);
}
}
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_BLUETOOTH
)
{
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_BLUETOOTH
)
{
return
checkBluetoothPermissionStatus
(
context
);
return
checkBluetoothPermissionStatus
(
context
);
}
}
...
@@ -190,6 +291,14 @@ final class PermissionManager {
...
@@ -190,6 +291,14 @@ final class PermissionManager {
}
}
}
}
// On Android below R, the android.permission.MANAGE_EXTERNAL_STORAGE flag in AndroidManifest.xml
// may be ignored and not visible to the App as it's a new permission setting as a whole.
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
)
{
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
R
)
{
return
PermissionConstants
.
PERMISSION_STATUS_RESTRICTED
;
}
}
return
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
return
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
}
}
...
@@ -212,6 +321,17 @@ final class PermissionManager {
...
@@ -212,6 +321,17 @@ final class PermissionManager {
return
PermissionConstants
.
PERMISSION_STATUS_RESTRICTED
;
return
PermissionConstants
.
PERMISSION_STATUS_RESTRICTED
;
}
}
}
}
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
)
{
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
R
)
{
return
PermissionConstants
.
PERMISSION_STATUS_RESTRICTED
;
}
return
Environment
.
isExternalStorageManager
()
?
PermissionConstants
.
PERMISSION_STATUS_GRANTED
:
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
}
final
int
permissionStatus
=
ContextCompat
.
checkSelfPermission
(
context
,
name
);
final
int
permissionStatus
=
ContextCompat
.
checkSelfPermission
(
context
,
name
);
if
(
permissionStatus
!=
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
permissionStatus
!=
PackageManager
.
PERMISSION_GRANTED
)
{
return
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
return
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
...
@@ -265,139 +385,10 @@ final class PermissionManager {
...
@@ -265,139 +385,10 @@ final class PermissionManager {
private
int
checkBluetoothPermissionStatus
(
Context
context
)
{
private
int
checkBluetoothPermissionStatus
(
Context
context
)
{
List
<
String
>
names
=
PermissionUtils
.
getManifestNames
(
context
,
PermissionConstants
.
PERMISSION_GROUP_BLUETOOTH
);
List
<
String
>
names
=
PermissionUtils
.
getManifestNames
(
context
,
PermissionConstants
.
PERMISSION_GROUP_BLUETOOTH
);
boolean
missingInManifest
=
names
==
null
||
names
.
isEmpty
();
boolean
missingInManifest
=
names
==
null
||
names
.
isEmpty
();
if
(
missingInManifest
)
{
if
(
missingInManifest
)
{
Log
.
d
(
PermissionConstants
.
LOG_TAG
,
"Bluetooth permission missing in manifest"
);
Log
.
d
(
PermissionConstants
.
LOG_TAG
,
"Bluetooth permission missing in manifest"
);
return
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
return
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
}
}
return
PermissionConstants
.
PERMISSION_STATUS_GRANTED
;
return
PermissionConstants
.
PERMISSION_STATUS_GRANTED
;
}
}
@VisibleForTesting
static
final
class
ActivityResultListener
implements
PluginRegistry
.
ActivityResultListener
{
// There's no way to unregister permission listeners in the v1 embedding, so we'll be called
// duplicate times in cases where the user denies and then grants a permission. Keep track of if
// we've responded before and bail out of handling the callback manually if this is a repeat
// call.
boolean
alreadyCalled
=
false
;
final
RequestPermissionsSuccessCallback
callback
;
@VisibleForTesting
ActivityResultListener
(
RequestPermissionsSuccessCallback
callback
)
{
this
.
callback
=
callback
;
}
@Override
public
boolean
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
if
(
alreadyCalled
||
requestCode
!=
PermissionConstants
.
PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS
)
{
return
false
;
}
alreadyCalled
=
true
;
final
int
status
=
resultCode
==
Activity
.
RESULT_OK
?
PermissionConstants
.
PERMISSION_STATUS_GRANTED
:
PermissionConstants
.
PERMISSION_STATUS_DENIED
;
HashMap
<
Integer
,
Integer
>
results
=
new
HashMap
<>();
results
.
put
(
PermissionConstants
.
PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS
,
status
);
callback
.
onSuccess
(
results
);
return
true
;
}
}
@VisibleForTesting
static
final
class
RequestPermissionsListener
implements
PluginRegistry
.
RequestPermissionsResultListener
{
// There's no way to unregister permission listeners in the v1 embedding, so we'll be called
// duplicate times in cases where the user denies and then grants a permission. Keep track of if
// we've responded before and bail out of handling the callback manually if this is a repeat
// call.
boolean
alreadyCalled
=
false
;
final
Activity
activity
;
final
RequestPermissionsSuccessCallback
callback
;
final
Map
<
Integer
,
Integer
>
requestResults
;
@VisibleForTesting
RequestPermissionsListener
(
Activity
activity
,
Map
<
Integer
,
Integer
>
requestResults
,
RequestPermissionsSuccessCallback
callback
)
{
this
.
activity
=
activity
;
this
.
callback
=
callback
;
this
.
requestResults
=
requestResults
;
}
@Override
public
boolean
onRequestPermissionsResult
(
int
id
,
String
[]
permissions
,
int
[]
grantResults
)
{
if
(
alreadyCalled
||
id
!=
PermissionConstants
.
PERMISSION_CODE
)
{
return
false
;
}
alreadyCalled
=
true
;
for
(
int
i
=
0
;
i
<
permissions
.
length
;
i
++)
{
final
String
permissionName
=
permissions
[
i
];
@PermissionConstants
.
PermissionGroup
final
int
permission
=
PermissionUtils
.
parseManifestName
(
permissionName
);
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_UNKNOWN
)
continue
;
final
int
result
=
grantResults
[
i
];
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_MICROPHONE
)
{
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_MICROPHONE
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_MICROPHONE
,
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
));
}
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_SPEECH
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_SPEECH
,
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
));
}
}
else
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
)
{
@PermissionConstants
.
PermissionStatus
int
permissionStatus
=
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
);
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
,
permissionStatus
);
}
}
else
if
(
permission
==
PermissionConstants
.
PERMISSION_GROUP_LOCATION
)
{
@PermissionConstants
.
PermissionStatus
int
permissionStatus
=
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
);
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
Q
)
{
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_ALWAYS
,
permissionStatus
);
}
}
if
(!
requestResults
.
containsKey
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_WHEN_IN_USE
))
{
requestResults
.
put
(
PermissionConstants
.
PERMISSION_GROUP_LOCATION_WHEN_IN_USE
,
permissionStatus
);
}
requestResults
.
put
(
permission
,
permissionStatus
);
}
else
if
(!
requestResults
.
containsKey
(
permission
))
{
requestResults
.
put
(
permission
,
PermissionUtils
.
toPermissionStatus
(
this
.
activity
,
permissionName
,
result
));
}
PermissionUtils
.
updatePermissionShouldShowStatus
(
this
.
activity
,
permission
);
}
this
.
callback
.
onSuccess
(
requestResults
);
return
true
;
}
}
}
}
permission_handler/android/src/main/java/com/baseflow/permissionhandler/PermissionUtils.java
View file @
49acc864
...
@@ -6,6 +6,7 @@ import android.content.Context;
...
@@ -6,6 +6,7 @@ import android.content.Context;
import
android.content.pm.PackageInfo
;
import
android.content.pm.PackageInfo
;
import
android.content.pm.PackageManager
;
import
android.content.pm.PackageManager
;
import
android.os.Build
;
import
android.os.Build
;
import
android.os.Environment
;
import
android.util.Log
;
import
android.util.Log
;
import
androidx.annotation.RequiresApi
;
import
androidx.annotation.RequiresApi
;
...
@@ -60,6 +61,8 @@ public class PermissionUtils {
...
@@ -60,6 +61,8 @@ public class PermissionUtils {
return
PermissionConstants
.
PERMISSION_GROUP_ACCESS_MEDIA_LOCATION
;
return
PermissionConstants
.
PERMISSION_GROUP_ACCESS_MEDIA_LOCATION
;
case
Manifest
.
permission
.
ACTIVITY_RECOGNITION
:
case
Manifest
.
permission
.
ACTIVITY_RECOGNITION
:
return
PermissionConstants
.
PERMISSION_GROUP_ACTIVITY_RECOGNITION
;
return
PermissionConstants
.
PERMISSION_GROUP_ACTIVITY_RECOGNITION
;
case
Manifest
.
permission
.
MANAGE_EXTERNAL_STORAGE
:
return
PermissionConstants
.
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
;
default
:
default
:
return
PermissionConstants
.
PERMISSION_GROUP_UNKNOWN
;
return
PermissionConstants
.
PERMISSION_GROUP_UNKNOWN
;
}
}
...
@@ -177,8 +180,11 @@ public class PermissionUtils {
...
@@ -177,8 +180,11 @@ public class PermissionUtils {
if
(
hasPermissionInManifest
(
context
,
permissionNames
,
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
))
if
(
hasPermissionInManifest
(
context
,
permissionNames
,
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
))
permissionNames
.
add
(
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
);
permissionNames
.
add
(
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
);
if
(
hasPermissionInManifest
(
context
,
permissionNames
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
))
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
Q
||
(
Build
.
VERSION
.
SDK_INT
==
Build
.
VERSION_CODES
.
Q
&&
Environment
.
isExternalStorageLegacy
()))
{
permissionNames
.
add
(
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
);
if
(
hasPermissionInManifest
(
context
,
permissionNames
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
))
permissionNames
.
add
(
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
);
break
;
}
break
;
break
;
case
PermissionConstants
.
PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS
:
case
PermissionConstants
.
PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS
:
...
@@ -197,7 +203,7 @@ public class PermissionUtils {
...
@@ -197,7 +203,7 @@ public class PermissionUtils {
break
;
break
;
case
PermissionConstants
.
PERMISSION_GROUP_ACTIVITY_RECOGNITION
:
case
PermissionConstants
.
PERMISSION_GROUP_ACTIVITY_RECOGNITION
:
// The AC
CESS_MEDIA_LOCA
TION permission is introduced in Android Q, meaning we should
// The AC
TIVITY_RECOGNI
TION permission is introduced in Android Q, meaning we should
// not handle permissions on pre Android Q devices.
// not handle permissions on pre Android Q devices.
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
Q
)
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
Q
)
return
null
;
return
null
;
...
@@ -210,6 +216,14 @@ public class PermissionUtils {
...
@@ -210,6 +216,14 @@ public class PermissionUtils {
if
(
hasPermissionInManifest
(
context
,
permissionNames
,
Manifest
.
permission
.
BLUETOOTH
))
if
(
hasPermissionInManifest
(
context
,
permissionNames
,
Manifest
.
permission
.
BLUETOOTH
))
permissionNames
.
add
(
Manifest
.
permission
.
BLUETOOTH
);
permissionNames
.
add
(
Manifest
.
permission
.
BLUETOOTH
);
break
;
break
;
case
PermissionConstants
.
PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE
:
// The MANAGE_EXTERNAL_STORAGE permission is introduced in Android R, meaning we should
// not handle permissions on pre Android R devices.
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
R
&&
hasPermissionInManifest
(
context
,
permissionNames
,
Manifest
.
permission
.
MANAGE_EXTERNAL_STORAGE
))
permissionNames
.
add
(
Manifest
.
permission
.
MANAGE_EXTERNAL_STORAGE
);
break
;
case
PermissionConstants
.
PERMISSION_GROUP_NOTIFICATION
:
case
PermissionConstants
.
PERMISSION_GROUP_NOTIFICATION
:
case
PermissionConstants
.
PERMISSION_GROUP_MEDIA_LIBRARY
:
case
PermissionConstants
.
PERMISSION_GROUP_MEDIA_LIBRARY
:
case
PermissionConstants
.
PERMISSION_GROUP_PHOTOS
:
case
PermissionConstants
.
PERMISSION_GROUP_PHOTOS
:
...
...
permission_handler/example/android/app/build.gradle
View file @
49acc864
...
@@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
...
@@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply
from:
"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply
from:
"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android
{
android
{
compileSdkVersion
29
compileSdkVersion
30
lintOptions
{
lintOptions
{
disable
'InvalidPackage'
disable
'InvalidPackage'
...
...
permission_handler/example/android/app/src/main/AndroidManifest.xml
View file @
49acc864
...
@@ -63,6 +63,9 @@
...
@@ -63,6 +63,9 @@
<!-- Permissions options for the `bluetooth` group -->
<!-- Permissions options for the `bluetooth` group -->
<uses-permission
android:name=
"android.permission.BLUETOOTH"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH"
/>
<!-- Permissions options for the `manage external storage` group -->
<uses-permission
android:name=
"android.permission.MANAGE_EXTERNAL_STORAGE"
/>
<application
<application
android:name=
"io.flutter.app.FlutterApplication"
android:name=
"io.flutter.app.FlutterApplication"
android:icon=
"@mipmap/ic_launcher"
android:icon=
"@mipmap/ic_launcher"
...
...
permission_handler/example/lib/plugin_example/permission_list.dart
View file @
49acc864
...
@@ -20,7 +20,8 @@ class PermissionList extends StatelessWidget {
...
@@ -20,7 +20,8 @@ class PermissionList extends StatelessWidget {
permission
!=
Permission
.
storage
&&
permission
!=
Permission
.
storage
&&
permission
!=
Permission
.
ignoreBatteryOptimizations
&&
permission
!=
Permission
.
ignoreBatteryOptimizations
&&
permission
!=
Permission
.
accessMediaLocation
&&
permission
!=
Permission
.
accessMediaLocation
&&
permission
!=
Permission
.
activityRecognition
;
permission
!=
Permission
.
activityRecognition
&&
permission
!=
Permission
.
manageExternalStorage
;
}
else
{
}
else
{
return
permission
!=
Permission
.
unknown
&&
return
permission
!=
Permission
.
unknown
&&
permission
!=
Permission
.
mediaLibrary
&&
permission
!=
Permission
.
mediaLibrary
&&
...
...
permission_handler/ios/Classes/PermissionHandlerEnums.h
View file @
49acc864
...
@@ -118,6 +118,7 @@ typedef NS_ENUM(int, PermissionGroup) {
...
@@ -118,6 +118,7 @@ typedef NS_ENUM(int, PermissionGroup) {
PermissionGroupActivityRecognition
,
PermissionGroupActivityRecognition
,
PermissionGroupUnknown
,
PermissionGroupUnknown
,
PermissionGroupBluetooth
,
PermissionGroupBluetooth
,
PermissionGroupManageExternalStorage
};
};
typedef
NS_ENUM
(
int
,
PermissionStatus
)
{
typedef
NS_ENUM
(
int
,
PermissionStatus
)
{
...
...
permission_handler/pubspec.yaml
View file @
49acc864
name
:
permission_handler
name
:
permission_handler
description
:
Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
description
:
Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
version
:
6.1.3
version
:
7.0.0
homepage
:
https://github.com/baseflowit/flutter-permission-handler
homepage
:
https://github.com/baseflowit/flutter-permission-handler
flutter
:
flutter
:
...
@@ -16,7 +16,7 @@ dependencies:
...
@@ -16,7 +16,7 @@ dependencies:
flutter
:
flutter
:
sdk
:
flutter
sdk
:
flutter
meta
:
^1.3.0
meta
:
^1.3.0
permission_handler_platform_interface
:
^3.
1.3
permission_handler_platform_interface
:
^3.
2.0
dev_dependencies
:
dev_dependencies
:
flutter_test
:
flutter_test
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment