Android 11 WebView打开文件选择按返回键后相机无法响应问题
Android 11 WebView图片选择返回后无法再次触发问题修复方案
根因分析
- Android 11及以上版本的
onActivityResult逻辑中,用户点击返回键触发RESULT_CANCELED时,仅处理了file_req_code对应的file_data回调,未对图片选择常用的INPUT_FILE_REQUEST_CODE对应的mFilePathCallback进行回调通知和置空操作 - WebView的
ValueCallback如果没有调用onReceiveValue方法,会一直处于等待状态,后续触发文件选择请求时不会再生成新的回调实例,导致点击无响应 - 低版本分支对取消场景做了明确的
onReceiveValue(null)处理,所以不会出现该问题
修复步骤
- 找到Android 11分支下的
RESULT_CANCELED判断块,补全INPUT_FILE_REQUEST_CODE的处理逻辑 - 补充results变量的非空判断,避免取消场景下空指针崩溃
修复后完整代码片段
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult Version R and Greater --> requestCode --> " + requestCode); if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult requestCode --> NULL "); super.onActivityResult(requestCode, resultCode, intent); return; } Uri[] results = null; // Check that the response is a good one if (resultCode == Activity.RESULT_OK) { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult --> RESULT_OK "); if (intent == null) { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult data --> null "); // If there is not data, then we may have taken a photo if (mCameraPhotoPath != null) { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult mCameraPhotoPath --> not null "); results = new Uri[]{Uri.parse(mCameraPhotoPath)}; } } else { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult DATA --> NOT null "); String dataString = intent.getDataString(); writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult DATA --> NOT null dataString "+dataString); if (dataString != null) { results = new Uri[]{Uri.parse(dataString)}; writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult dataString --> NOT null "); } else { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult dataString --> NULL "); results = new Uri[]{pictureUri}; } } mFilePathCallback.onReceiveValue(results); mFilePathCallback = null; } else if (resultCode == Activity.RESULT_CANCELED) { Log.e(TAG, "Image file selection canceled"); // 补全INPUT_FILE_REQUEST_CODE的取消处理,解决后续无法触发的问题 if (requestCode == INPUT_FILE_REQUEST_CODE && mFilePathCallback != null) { mFilePathCallback.onReceiveValue(null); mFilePathCallback = null; } if (requestCode == file_req_code) { if (null == file_data) return; Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData(); file_data.onReceiveValue(result); file_data = null; } } // 补全非空判断,避免空指针崩溃 if(results != null && results.length > 0) { writeLog("Web Frame -->" + Thread.currentThread().getStackTrace()[1]. getLineNumber() + " --> Camera onActivityResult Length --> "+results.length+" result "+results[0].toString()); } } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { writeLog("Web Screen -->"+ Thread.currentThread().getStackTrace()[1]. getLineNumber()+" Camera onActivityResult--> Inside Version Q or Less"); Uri[] results = null; /*-- if file request cancelled; exited camera. we need to send null value to make future attempts workable --*/ if (resultCode == Activity.RESULT_CANCELED) { if (requestCode == file_req_code) { file_path.onReceiveValue(null); return; } } /*-- continue if response is positive --*/ if (resultCode == Activity.RESULT_OK) { if (requestCode == file_req_code) { if (null == file_path) { return; } ClipData clipData; String stringData; try { clipData = intent.getClipData(); stringData = intent.getDataString(); } catch (Exception e) { clipData = null; stringData = null; } if (clipData == null && stringData == null && cam_file_data != null) { results = new Uri[]{ Uri.parse(cam_file_data) }; } else { if (clipData != null) { // checking if multiple files selected or not final int numSelectedFiles = clipData.getItemCount(); results = new Uri[numSelectedFiles]; for (int i = 0; i < clipData.getItemCount(); i++) { results[i] = clipData.getItemAt(i).getUri(); } } else { results = new Uri[]{ Uri.parse(stringData) }; } } } } file_path.onReceiveValue(results); file_path = null; } else { if (requestCode == file_req_code) { if (null == file_data) return; Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData(); file_data.onReceiveValue(result); file_data = null; } } }
内容的提问来源于stack exchange,提问作者Malhotra
相关产品推荐
相关产品推荐

