Flutter 应用程序在请求 REQUEST_INSTALL_PACKAGES 权限后关闭

问题描述 投票:0回答:1

我正在使用权限处理程序包来获取 requestInstallPackages。但之后

await Permission.requestInstallPackages.request(); 

返回我的应用程序,我的应用程序已关闭,我收到此消息:

MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=212, result=-1, data=null} to activity .../com.....MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Activity.getPackageManager()' on a null object reference
                                                                                                        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4469)
                                                                                                        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4506)
                                                                                                        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
                                                                                                        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
                                                                                                        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
                                                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2081)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                        at android.os.Looper.loop(Looper.java:223)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7719)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
                                                                                                    Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=212, result=-1, data=null} to activity {com...../com.....MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Activity.getPackageManager()' on a null object reference
                                                                                                        at android.app.ActivityThread.deliverResults(ActivityThread.java:5061)
                                                                                                        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4456)
                                                                                                        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4506) 
                                                                                                        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
                                                                                                        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
                                                                                                        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
                                                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2081) 
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:106) 
                                                                                                        at android.os.Looper.loop(Looper.java:223) 
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7719) 
                                                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
                                                                                                    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Activity.getPackageManager()' on a null object reference
                                                                                                        at com.baseflow.permissionhandler.PermissionManager.onActivityResult(PermissionManager.java:97)
                                                                                                        at io.flutter.embedding.engine.FlutterEngineConnectionRegistry$FlutterEngineActivityPluginBinding.onActivityResult(FlutterEngineConnectionRegistry.java:774)
                                                                                                        at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.onActivityResult(FlutterEngineConnectionRegistry.java:422)
                                                                                                        at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onActivityResult(FlutterActivityAndFragmentDelegate.java:964)
                                                                                                        at io.flutter.embedding.android.FlutterActivity.onActivityResult(FlutterActivity.java:911)
                                                                                                        at android.app.Activity.dispatchActivityResult(Activity.java:8353)

有人知道我该如何解决吗?

android flutter permissions
1个回答
0
投票

解决方案

  1. 更新AndroidManifest.xml

将所需的权限和查询添加到您的

android/app/src/main/AndroidManifest.xml
:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.package.name">
    
    <!-- Add this permission -->
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    
    <!-- Add queries for package installer -->
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="package" />
        </intent>
    </queries>
    
    <application>
        <!-- ... rest of your manifest ... -->
    </application>
</manifest>
  1. 正确的权限处理
import 'package:permission_handler/permission_handler.dart';

Future<bool> requestInstallPermission() async {
  try {
    // Check current status
    final status = await Permission.requestInstallPackages.status;
    
    if (status.isDenied) {
      // Request permission
      final result = await Permission.requestInstallPackages.request();
      return result.isGranted;
    }
    
    return status.isGranted;
  } catch (e) {
    print('Error requesting install permission: $e');
    return false;
  }
}

// Usage example
void installApp() async {
  final hasPermission = await requestInstallPermission();
  
  if (hasPermission) {
    // Proceed with installation
    // Your installation code here
  } else {
    // Handle permission denied
    showPermissionDeniedDialog();
  }
}
  1. 活动结果处理

更新您的 MainActivity.kt (Kotlin) 或 MainActivity.java (Java):

// Kotlin
package your.package.name

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        
        // Add custom result handling if needed
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "install_channel")
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "checkInstallPermission" -> {
                        // Your custom permission check logic
                        result.success(true)
                    }
                    else -> result.notImplemented()
                }
            }
    }
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        // Add custom result handling if needed
    }
}
  1. 带有错误处理的完整示例
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

class InstallPermissionHandler extends StatefulWidget {
  const InstallPermissionHandler({Key? key}) : super(key: key);

  @override
  State<InstallPermissionHandler> createState() => _InstallPermissionHandlerState();
}

class _InstallPermissionHandlerState extends State<InstallPermissionHandler> {
  PermissionStatus _permissionStatus = PermissionStatus.denied;

  @override
  void initState() {
    super.initState();
    _checkPermission();
  }

  Future<void> _checkPermission() async {
    try {
      final status = await Permission.requestInstallPackages.status;
      setState(() {
        _permissionStatus = status;
      });
    } catch (e) {
      print('Error checking permission: $e');
    }
  }

  Future<void> _requestPermission() async {
    try {
      final status = await Permission.requestInstallPackages.request();
      setState(() {
        _permissionStatus = status;
      });
    } catch (e) {
      print('Error requesting permission: $e');
      // Show error dialog
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: const Text('Error'),
          content: Text('Failed to request permission: $e'),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('OK'),
            ),
          ],
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Install Permission')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Permission status: $_permissionStatus'),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _requestPermission,
              child: const Text('Request Permission'),
            ),
          ],
        ),
      ),
    );
  }
}

附加配置

  1. 渐变设置

更新您的

android/app/build.gradle

android {
    defaultConfig {
        // Minimum SDK version should be 23 or higher
        minSdkVersion 23
        
        // Other config...
    }
}
  1. ProGuard 规则(如果使用 ProGuard)

添加到

android/app/proguard-rules.pro

-keep class com.baseflow.permissionhandler.** { *; }

常见问题及解决方案

  1. 应用程序在返回时崩溃

如果从权限对话框返回时应用程序仍然崩溃:

// Wrap permission request in try-catch
Future<void> safeRequestPermission() async {
  try {
    await Permission.requestInstallPackages.request();
  } catch (e) {
    // Handle error gracefully
    print('Permission request failed: $e');
    // Optionally restart app or show error
  }
}
  1. 未显示权限

确保您的清单具有正确的权限:

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
  1. Android 13+ 问题

对于 Android 13 (API 33) 及更高版本,添加:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

最佳实践

  1. 请求前检查权限
if (await Permission.requestInstallPackages.isDenied) {
  // Request permission
}
  1. 处理永久拒绝
if (await Permission.requestInstallPackages.isPermanentlyDenied) {
  // Open app settings
  openAppSettings();
}
  1. 优雅降级
void handleInstallation() async {
  if (!await requestInstallPermission()) {
    // Provide alternative solution
    showAlternativeDialog();
  }
}

记住:

  • 处理所有可能的权限状态
  • 提供清晰的用户反馈
  • 实施正确的错误处理
  • 在多个Android版本上进行测试
  • 考虑特定于平台的行为

您希望我更详细地解释任何部分吗?

© www.soinside.com 2019 - 2024. All rights reserved.