android 调用系统相机拍照爬坑 onActivityResult 结果码为0

     Android调用系统相机,需要注意的地方无非就是6.0之后的动态授权,7.0的系统对api 的限制需要使用Provider 等适配问题,大家网上一搜一大堆相关的文章。

  但是最近做项目发现6.0,7.0 等适配问题都做了处理,但是拍完照片之后 onActivityResult 的结果码resultCode始终等于0,网上搜了很多答案有说是activity 启动模式为单例的,有说是没有权限的等等。 纠结了很久 ,最终发现是调用MediaStore.EXTRA_OUTPUT       设置自定义目录路径的问题 。代码如下:   


 /**
     * 打开相机操作
     */
    private void startCamera(Activity context) {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File file = FileUtils.createOriImageFile();
        if (file != null) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                imgUriOri = Uri.fromFile(file);
            } else {
                imgUriOri = FileProvider.getUriForFile(context, "com.qh.insurance.file_provider", file);
            }
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imgUriOri);
            context.startActivityForResult(cameraIntent, Constants.PHOTO_REQUEST_CAMERA);
        }
    }

/**
     * 创建拍照需要的文件
     *
     * @return
     */
    public static File createOriImageFile() {
        String imgNameOri = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String mTempPhotoPath  = Environment.getExternalStorageDirectory().getAbsolutePath() + "/qhphoto/" + imgNameOri + ".jpeg";

        File file =new File(mTempPhotoPath);
        if (!file.exists())
        {
            file.getParentFile().mkdirs();  //注意此处创建文件调用getParentFile()再调用    mkdirs()
        }
        return file;
    }

    原因是在创建拍照文件的时候路 file不存在调用 file.mkdirs() , 最终创建的xxx.jpeg 是文件夹而非文件。

  对于File类来说,他既可以表示一个文件,也可以表示一个文件夹,那么在声明情况下他会创建文件夹,什么情况下会创建文件

  1. 看下面例子
public static File createOriImageFile() {
       
       String mTempPhotoPath  = Environment.getExternalStorageDirectory().getAbsolutePath() + "/qhphoto/"+ "test.jpeg";

        File file =new File(mTempPhotoPath);
        if (!file.exists())
        {
            file.mkdirs();
        }
        return file;
    }
这种情况下最终创建的test.jpeg 是文件夹,test.jpeg是文件夹的名字 

    2. 为什么会出现一个test.jpeg的文件夹:java默认情况下是创建一个文件就会想test.jpeg看成一个整体,成为一个文件的名字

那么怎么解决这个问题:你需要告诉它我要建一个文件, 所以你要告诉它所在的父目录代码如下:

public static File createOriImageFile() {
       
       String mTempPhotoPath  = Environment.getExternalStorageDirectory().getAbsolutePath() + "/qhphoto/"+ "test.jpeg";

        File file =new File(mTempPhotoPath);
        if (!file.exists())
        {
               file.getParentFile().mkdirs();
        }
        return file;
    }

 到此问题解决,成功获取了拍照后的文件。

 本文主要是记录开发中遇到的坑,希望能够对你有帮助,如有问题,请大家指出斧正!

  /**
     * 打开讯飞语音识别
     */
    @JavascriptInterface
    public String xunFeiSpeech() {
        String[] permissions = new String[]{Manifest.permission.RECORD_AUDIO};
        if (PermissionUtil.hasPermissons(mainActivity, permissions)) {
            mIatResults.clear();
            //1. 创建SpeechRecognizer对象,第二个参数: 本地识别时传 InitListener
            SpeechRecognizer mIat = SpeechRecognizer.createRecognizer(mainActivity, null); //语音识别器
            //2. 设置听写参数,详见《 MSC Reference Manual》 SpeechConstant类
            mIat.setParameter(SpeechConstant.DOMAIN, "iat");// 短信和日常用语: iat (默认)
            mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");// 设置中文
            mIat.setParameter(SpeechConstant.ACCENT, "mandarin");// 设置普通话
            // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
            mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
            // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
            mIat.setParameter(SpeechConstant.VAD_EOS, "2000");
            mIat.setParameter(SpeechConstant.AUDIO_FORMAT_AUE, "speex");
            mIat.setParameter(SpeechConstant.ASR_PTT, "0");// 不要标点
            mIat.setParameter(SpeechConstant.SAMPLE_RATE, "16000");// 采样率16k
            //3. 开始听写
            mIat.startListening(new RecognizerListener() {
                //一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
                //isLast等于true 时会话结束。
                @SuppressLint("LongLogTag")
                public void onResult(RecognizerResult results, boolean isLast) {
                    Log.e(TAG, results.getResultString());
                    System.out.println(results.getResultString());
                    String result = results.getResultString(); //为解析的
                    Log.e("没有解析的", result);
                    String text = JsonParser.parseIatResult(result);//解析过后的
                    Log.e("解析后的", text);
                    String sn = null;
                    // 读取json结果中的 sn字段
                    try {
                        JSONObject resultJson = new JSONObject(results.getResultString());
                        sn = resultJson.optString("sn");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    mIatResults.put(sn, text);//没有得到一句,添加到
                    StringBuffer resultBuffer = new StringBuffer();
                    for (String key : mIatResults.keySet()) {
                        resultBuffer.append(mIatResults.get(key));
                    }
                    if (isLast) {
                        if (recognizerDialogManager != null) {
                            recognizerDialogManager.dismissRecognizerDialog();
                        }
                        //此处可调用js将识别结果传给h5
                        ToastUtil.getInstance().showToastLong(resultBuffer.toString());
                        Log.i("识别结果", resultBuffer.toString().toUpperCase());
                        String speechResult = resultBuffer.toString().toUpperCase();
                        if (TextUtils.isEmpty(speechResult)) {
                            return;
                        }

                    }
                }

                // 会话发生错误回调接口
                @SuppressLint("LongLogTag")
                public void onError(SpeechError error) {
                    if (recognizerDialogManager != null) {
                        recognizerDialogManager.dismissRecognizerDialog();
                    }
                    // 获取错误码描述
                    Log.e(TAG, "error.getPlainDescription(true)==" + error.getPlainDescription(true));
                }

                // 开始录音
                public void onBeginOfSpeech() {
                    if (recognizerDialogManager != null) {
                        recognizerDialogManager.showRecognizerDialog();
                    }
                }

                //volume 音量值0~30, data音频数据
                public void onVolumeChanged(int volume, byte[] data) {
                    if (recognizerDialogManager != null) {
                        recognizerDialogManager.setVoiceImage(volume);
                    }
                    Logger.i("volume", volume + "");
                    Logger.i("录音文件data", data.length + "");
                }

                // 结束录音
                public void onEndOfSpeech() {
                    if (recognizerDialogManager != null) {
                        recognizerDialogManager.showWaiting();
                    }
                }

                // 扩展用接口
                @SuppressLint("LongLogTag")
                public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
                    if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                        String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
                        Log.d(TAG, "session id =" + sid);
                    }
                }
            });
            recognizerDialogManager = new RecognizerDialogManager(mainActivity);
        } else {
            PermissionUtil.getAudioPermissions(mainActivity, Constants.REQUEST_PERMISSIONS_AUDIO);
        }

        return "此处要返回onResult() 方法返回的值";
    }

猜你喜欢

转载自blog.csdn.net/qq_21199331/article/details/83042001