Android 13 compatibility update

This commit is contained in:
Ming Ming 2023-09-02 02:15:41 +08:00
parent 601f5e1af2
commit 150c4c4831
8 changed files with 129 additions and 16 deletions

View file

@ -45,7 +45,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.nkming.nc_photos"
minSdkVersion 21
targetSdkVersion 31
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
ndk {

View file

@ -3,10 +3,13 @@
package="com.nkming.nc_photos">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application
android:name=".App"

View file

@ -3,15 +3,24 @@ import 'package:nc_photos/stream_extension.dart';
import 'package:np_platform_permission/np_platform_permission.dart';
Future<Map<String, int>> requestPermissionsForResult(
List<String> permissions) async {
List<String> permissions) =>
_doRequest(() => Permission.request(permissions));
Future<Map<String, int>> requestReadExternalStorageForResult() =>
_doRequest(() => Permission.requestReadExternalStorage());
Future<Map<String, int>> requestPostNotificationsForResult() =>
_doRequest(() => Permission.requestPostNotifications());
Future<Map<String, int>> _doRequest(Future Function() op) async {
Map<String, int>? result;
final resultFuture = Permission.stream
.whereType<PermissionRequestResult>()
.first
.then((ev) => result = ev.grantResults);
await Permission.request(permissions);
await op();
await resultFuture;
_log.info("[requestPermissionsForResult] Result: $result");
_log.info("[_doRequest] Result: $result");
return result!;
}

View file

@ -341,11 +341,11 @@ class _EnhancedPhotoBrowserState extends State<EnhancedPhotoBrowser>
if (getRawPlatform() == NpPlatform.android) {
if (AndroidInfo().sdkInt >= AndroidVersion.R) {
if (!await Permission.hasReadExternalStorage()) {
final results = await requestPermissionsForResult([
Permission.READ_EXTERNAL_STORAGE,
]);
final results = await requestReadExternalStorageForResult();
return results[Permission.READ_EXTERNAL_STORAGE] ==
PermissionRequestResult.granted;
PermissionRequestResult.granted ||
results[Permission.READ_MEDIA_IMAGES] ==
PermissionRequestResult.granted;
}
} else {
if (!await Permission.hasWriteExternalStorage()) {

View file

@ -11,6 +11,7 @@ import 'package:nc_photos/entity/pref.dart';
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/mobile/android/activity.dart';
import 'package:nc_photos/mobile/android/permission_util.dart';
import 'package:nc_photos/use_case/compat/v29.dart';
import 'package:nc_photos/use_case/compat/v46.dart';
import 'package:nc_photos/use_case/compat/v55.dart';
@ -19,6 +20,7 @@ import 'package:nc_photos/widget/home.dart';
import 'package:nc_photos/widget/setup.dart';
import 'package:nc_photos/widget/sign_in.dart';
import 'package:np_codegen/np_codegen.dart';
import 'package:np_platform_permission/np_platform_permission.dart';
import 'package:np_platform_util/np_platform_util.dart';
import 'package:to_string/to_string.dart';
@ -38,7 +40,7 @@ class Splash extends StatefulWidget {
@npLog
class _SplashState extends State<Splash> {
@override
initState() {
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_doWork();
@ -46,6 +48,9 @@ class _SplashState extends State<Splash> {
}
Future<void> _doWork() async {
if (!await Permission.hasPostNotifications()) {
await requestPostNotificationsForResult();
}
if (Pref().getFirstRunTime() == null) {
await Pref().setFirstRunTime(clock.now().millisecondsSinceEpoch);
}

View file

@ -4,6 +4,8 @@ import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
@ -20,14 +22,20 @@ interface PermissionUtil {
}
fun hasReadExternalStorage(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
context, Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
hasReadExternalStorage33(context)
} else {
hasReadExternalStorage0(context)
}
}
fun requestReadExternalStorage(activity: Activity) = request(
activity, Manifest.permission.READ_EXTERNAL_STORAGE
)
fun requestReadExternalStorage(activity: Activity) {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestReadExternalStorage33(activity)
} else {
requestReadExternalStorage0(activity)
}
}
fun hasWriteExternalStorage(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
@ -38,5 +46,53 @@ interface PermissionUtil {
fun requestWriteExternalStorage(activity: Activity) = request(
activity, Manifest.permission.WRITE_EXTERNAL_STORAGE
)
fun hasPostNotifications(context: Context): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
hasPostNotifications33(context)
} else {
true
}
}
fun requestPostNotifications(activity: Activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPostNotifications33(activity)
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun hasReadExternalStorage33(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
context, Manifest.permission.READ_MEDIA_IMAGES
) == PackageManager.PERMISSION_GRANTED
}
private fun hasReadExternalStorage0(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
context, Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun requestReadExternalStorage33(activity: Activity) = request(
activity, Manifest.permission.READ_MEDIA_IMAGES
)
private fun requestReadExternalStorage0(activity: Activity) = request(
activity, Manifest.permission.READ_EXTERNAL_STORAGE
)
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun hasPostNotifications33(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
context, Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun requestPostNotifications33(activity: Activity) = request(
activity, Manifest.permission.POST_NOTIFICATIONS
)
}
}

View file

@ -93,6 +93,34 @@ internal class PermissionChannelHandler(context: Context) :
}
}
"requestReadExternalStorage" -> {
try {
PermissionUtil.requestReadExternalStorage(activity!!)
result.success(null)
} catch (e: Throwable) {
result.error("systemException", e.toString(), null)
}
}
"hasPostNotifications" -> {
try {
result.success(
PermissionUtil.hasPostNotifications(context)
)
} catch (e: Throwable) {
result.error("systemException", e.toString(), null)
}
}
"requestPostNotifications" -> {
try {
PermissionUtil.requestPostNotifications(activity!!)
result.success(null)
} catch (e: Throwable) {
result.error("systemException", e.toString(), null)
}
}
else -> result.notImplemented()
}
}

View file

@ -9,6 +9,8 @@ import 'package:np_platform_permission/src/k.dart' as k;
class Permission {
static const READ_EXTERNAL_STORAGE =
"android.permission.READ_EXTERNAL_STORAGE";
static const READ_MEDIA_IMAGES =
"android.permission.READ_MEDIA_IMAGES";
static const WRITE_EXTERNAL_STORAGE =
"android.permission.WRITE_EXTERNAL_STORAGE";
@ -26,6 +28,16 @@ class Permission {
return (await _methodChannel.invokeMethod<bool>("hasReadExternalStorage"))!;
}
static Future<void> requestReadExternalStorage() =>
_methodChannel.invokeMethod("requestReadExternalStorage");
static Future<bool> hasPostNotifications() async {
return (await _methodChannel.invokeMethod<bool>("hasPostNotifications"))!;
}
static Future<void> requestPostNotifications() =>
_methodChannel.invokeMethod("requestPostNotifications");
static Stream get stream => _eventStream;
static final _eventStream =