陈桥驿站 陈桥驿站

Android 调用系统相机拍照和储存( 兼容 Xiaomi、Huawei、vivo、OPPO ... ... )

--> Android 阅读 ( 153 ) 文章转载请注明来源!

前言

前几天昨做完项目,只在小米手机上面测了测,其他的手机还没测。然后给同事装上了一个程序,相机部分的功能,跳转到相机页面,点击完成没有反应。

同事用的vivo x9,我当时又用他的手机试了试,还是不行。我就叫他回去了,总不能拿他的手机开启开发者模式,然后在我的机器上面debug吧。

为了探究问题的根源,我意识到,只有一台Android手机是远远不够的,起码国内比较流行的手机都得来上一块。然后我就在某宝买了华为vivoOPPO手机各一部。

没办法,为了Android的代码在不同手机厂商的ROM的适配,牺牲点钱不算什么-_-||。

收到手机以后,我赶紧测试了一下,其中vivo手机可能是ROM的原因,USB一直不能连接到电脑,这里就先不说他的症状了。

手机型号系统症状
小米 红米6AAndroid 9.0正常
华为 荣耀畅玩5Android 5.1无法回调相机
OPPO A33Android 5.1无法回调相机
vivo X5Android 4.4无法回调相机

正题

扯了半天犊子,开始切入正题。
我们都知道调用相机用以下一段代码。

case R.id.record_camera_image:
    if (checkCameraPermission()) {
        if (cameraImages > 3) {
            Toast.makeText(RecordActivity.this, "最多就能拍摄三张图片", Toast.LENGTH_LONG).show();
        } else {
            //File
            currentImageID = id;
            File imageFile = new File(getFilesDir(), currentImageID + "_Primary.jpg");
            Intent imageIntent = new Intent();
            imageIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
            imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, file2Uri(imageFile));
            startActivityForResult(imageIntent, 1);
        }
    } else {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
    }
    break;

MediaStore.ACTION_IMAGE_CAPTURE

既然无法回调,就看是不是系统自身的相机的BUG( 当然这基本上是不可能事件-_-|| ,但是ROM自身有问题应该也是有可能的对吧。)。

修改代码

startActivityForResult(imageIntent, 1); -> startActivity(imageIntent);

最后发现可以正常结束相机页面,就说明在回调过程中出问题了。

这个时候我突然想起来了,之前写了一个file2Uri,而且反观一下,高版本的Android没问题,低版本的有问题。

FileProvider

看看之前的怎么写的吧。

这里我就不得不吐槽一下,因为最近一段时间原生Android做的比较少,做React Native做的比较多。

然后这段代码我看了很多博客都这么写的。

private Uri file2Uri(File file) {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
            FileProvider.getUriForFile(this, "net.cctv3.ZhonglianHuwai.fileProvider", file) : Uri.fromFile(file);
}

什么意思呢,就是Android 7.0以后,不能直接通过绝对路径访问File了,需要配置FileProvider。根据我的印象他好像暴露出来的是Content://... ...的形式,具体的我也懒得Log了。


按照如图所示,分别配好对应文件的内容如下。

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="net.cctv3.ZhonglianHuwai.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider_path" />
</provider>
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external-storage-root"
        path="./" />
    <files-path
        name="files-path"
        path="./" />
    <cache-path
        name="cache-path"
        path="./" />
    <!--/storage/emulated/0/Android/data/...-->
    <external-files-path
        name="external-file-path"
        path="." />
    <!--代表app 外部存储区域根目录下的文件 Context.getExternalCacheDir目录下的目录-->
    <external-cache-path
        name="external-cache-path"
        path="." />
    <!--配置root-path。这样子可以读取到sd卡和一些应用分身的目录,否则微信分身保存的图片,就会导致 java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/999/tencent/MicroMsg/WeiXin/export1544062754693.jpg,在小米6的手机上微信分身有这个crash,华为没有
-->
    <root-path
        name="root-path"
        path="" />
</paths>

然后我多说几句,作为一名程序员,都有点自己的职业操守行不???

虽然我配置了一大堆可写的路径,那是我抄的网上的配置。我自己只读写/data/data/包名/files/自己包里面的文件夹里面的东西。

我就纳了闷儿了,闲着没事儿老往用户的手机内存卡里面写东西干嘛。为什么现在Android程序卸载个程序,手机内存卡里面还留了一堆垃圾文件???

接着上面的说,我刚才经过试验发现拍照页面是可以正常返回的,也就是说就是写文件的时候出错了。

再来看这段代码。

private Uri file2Uri(File file) {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
            FileProvider.getUriForFile(this, "net.cctv3.ZhonglianHuwai.fileProvider", file) : Uri.fromFile(file);
}

现在的CSDN真的是,天下博客一把抄,你抄我抄他也抄,有意思么?

说个问题看了半天,最后连个运行的截图都没有,博文基本上也都是复制的别人的。

我尝试性的,把所有的File都通过FileProvider的形式,对文件进行引用。

private Uri file2Uri(File file) {
    return FileProvider.getUriForFile(this, "net.cctv3.ZhonglianHuwai.fileProvider", file);
}

搞定。

本文基于《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
文章链接:http://www.cctv3.net/archives/androidCameraPhoto.html (转载时请注明本文出处及文章链接)

Android
发表新评论
数据库查询到 4 条评论
  1. XXL
    XXL Windows 7Google Chrome 78.0.3904.108
    回复

    菜真彩

    1. 陈桥驿站
      陈桥驿站全国花式编程总冠军 MacBook ProGoogle Chrome 81.0.4044.122
      回复

      @XXL You can you up。

  2. 陈桥驿栈
    陈桥驿栈 Windows 10Google Chrome 72.0.3626.121
    回复

    http://live.vhall.com/327472882

  3. 陈桥驿站
    陈桥驿站全国花式编程总冠军 MacBook ProGoogle Chrome 79.0.3945.117
    回复

    https://selenium.dev/selenium-ide/

雷姆
拉姆