You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12中拍照或扫描二维码后应用崩溃问题求助

解决Android 12下拍照/扫描二维码后应用崩溃问题

问题说明

应用支持拍照和扫描二维码功能,在Android 12以外的所有版本运行正常,但在Android 12系统中执行拍照或扫码操作后会崩溃。

相关代码

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
        java.io.File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (java.io.IOException ex) {
            android.widget.Toast.makeText(this,
                    "Error occure while creating image file",
                    android.widget.Toast.LENGTH_LONG).show();
        }

        if (photoFile != null) {
            cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.net.Uri.fromFile(photoFile));
            startActivityForResult(cameraIntent, CAMERA_RESULT);
        }
    }

崩溃日志

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=3001, result=-1, data=Intent { (has extras) }} to activity {com.xxxxx/com.xxxx.xxxxx}: java.lang.NullPointerException: Attempt to read from field 'org.apache.cordova.PluginManager org.apache.cordova.CordovaWebView.pluginManager' on a null object reference in method 'void org.apache.cordova.CordovaActivity.onActivityResult(int, int, android.content.Intent)'

    android.app.ActivityThread.deliverResults(ActivityThread.java:5567)
    android.app.ActivityThread.performResumeActivity(ActivityThread.java:4953)
    android.app.ActivityThread.handleResumeActivity(ActivityThread.java:5017)
    android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:60)
    android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
    android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
    android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    android.app.ActivityThread$H.handleMessage(ActivityThread.java:2374)
    android.os.Handler.dispatchMessage(Handler.java:106)
    android.os.Looper.loopOnce(Looper.java:233)
    android.os.Looper.loop(Looper.java:344)
    android.app.ActivityThread.main(ActivityThread.java:8248)
    java.lang.reflect.Method.invoke(Native Method)
    com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589)
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071)

原因分析

  1. File Uri权限问题:Android 7.0+已禁止直接使用Uri.fromFile()传递文件路径,Android 12对此限制更严格,会导致相机应用无法访问文件,间接触发Activity生命周期异常。
  2. Cordova Activity回收问题:Android 12对后台Activity回收逻辑更严格,启动相机后原Cordova Activity可能被系统回收,恢复时CordovaWebView或PluginManager为空,导致onActivityResult回调抛出空指针。

解决方案

1. 替换File Uri为FileProvider

  • 在AndroidManifest.xml中注册FileProvider:
    <application>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>
    
  • 在res/xml目录创建file_paths.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-files-path name="camera_photos" path="Pictures" />
    </paths>
    
  • 修改代码中的Uri生成逻辑:
    if (photoFile != null) {
        Uri photoUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", photoFile);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        startActivityForResult(cameraIntent, CAMERA_RESULT);
    }
    

2. 修复Cordova onActivityResult空指针

  • 重写CordovaActivity的onActivityResult方法,增加空指针判断:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (this.appView != null && this.appView.getPluginManager() != null) {
            super.onActivityResult(requestCode, resultCode, intent);
        } else {
            // 暂存结果,待Activity恢复后处理
            if (resultCode == RESULT_OK && requestCode == CAMERA_RESULT) {
                SharedPreferences prefs = getSharedPreferences("CameraTemp", MODE_PRIVATE);
                prefs.edit().putString("temp_photo_path", photoFile.getAbsolutePath()).apply();
            }
        }
    }
    
  • 在onCreate中添加结果恢复逻辑:
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 检查暂存的拍照结果
        SharedPreferences prefs = getSharedPreferences("CameraTemp", MODE_PRIVATE);
        String tempPhotoPath = prefs.getString("temp_photo_path", null);
        if (tempPhotoPath != null) {
            // 处理拍照结果(如显示图片、传递给业务逻辑)
            handleCapturedPhoto(tempPhotoPath);
            prefs.edit().remove("temp_photo_path").apply();
        }
    }
    

3. 优化Activity生命周期配置

在AndroidManifest.xml中给目标Activity添加配置,减少系统回收概率:

<activity
    android:name=".YourCordovaActivity"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
    android:exported="true">
</activity>

内容的提问来源于stack exchange,提问作者suresh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:50:28