首页 > 其他分享 >记一次 Android 自定义相机拍照奔溃bug事件

记一次 Android 自定义相机拍照奔溃bug事件

时间:2024-08-06 16:25:44浏览次数:17  
标签:java name 自定义 image MediaProvider Android com bug android

最近在开发一个美颜的相机功能,需要自定义抓取相机回调的数,生成照片并保存到相册,需要自定义保存照片。

相机开始使用时没有任何问题,测试拍照几次后突然奔溃,跟踪代码日志发现是图片保存失败,同样的代码,同样的逻辑,正常使用很多次以后才奔溃报错,根据日志找到报错的位置,

ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "image_name");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

在insert这一行发生的错误,表面看没有任何问题,代码一切正常。

报错日志如下

Writing exception to parcel
java.lang.IllegalStateException: Failed to build unique file: /storage/emulated/0/Pictures/image_name owner_package_name=com.vedavision.gockr _display_name=image_name mime_type=image/jpeg _data=/storage/emulated/0/Pictures/image_name relative_path=Pictures/
at com.android.providers.media.MediaProvider.ensureFileColumns(MediaProvider.java:3933)
At com.android.providers.media.MediaProvider.ensureUniqueFileColumns(MediaProvider.java:3650)
at com.android.providers.media.MediaProvider.insertFile(MediaProvider.java:4423)
at com.android.providers.media.MediaProvider.insertInternal(MediaProvider.java:4890)
at com.android.providers.media.MediaProvider.insert(MediaProvider.java:4709)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:348)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:169)
at android.os.Binder.execTransactInternal(Binder.java:1285)
at android.os.Binder.execTransact(Binder.java:1249)

具体报错位置提示:

java.lang.IllegalStateException: Failed to build unique file: /storage/emulated/0/Pictures/image_name owner_package_name=com.vedavision.gockr _display_name=image_name mime_type=image/jpeg _data=/storage/emulated/0/Pictures/image_name relative_path=Pictures/
at android.os.Parcel.createExceptionOrNull(Parcel.java:3019)
at android.os.Parcel.createException(Parcel.java:2995)
at android.os.Parcel.readException(Parcel.java:2978)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:565)
at android.content.ContentResolver.insert(ContentResolver.java:2196)
at android.content.ContentResolver.insert(ContentResolver.java:2157)
at com.vedavision.gockr.utils.ImageUtils.saveToGallery(ImageUtils.java:181)
at com.vedavision.gockr.camera.FrameDrawer.draw(FrameDrawer.java:249)
at com.vedavision.gockr.camera.FrameDrawer.draw(FrameDrawer.java:195)
at com.vedavision.gockr.camera.SimpleCameraRenderer.onDrawFrame(SimpleCameraRenderer.java:213)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1590)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1272)

从日志看 最终报错的位置是:

com.android.providers.media.MediaProvider.ensureFileColumns的方法,如下

这里可以看到我们日志中的错误,Failed to build unique file,但是明显这个错误是FileUtils.buildNonUniqueFile  或者 buildUniqueFile抛出的,我们继续跟踪,进入到buildUniqueFile方法,  在这个里面调用了 FileUtils.buildUniqueFileWithExtension(),

buildUniqueFileWithExtension这个方法注意看 n++>=32抛出异常,大概意思就是,如果我们以固定名称创建文件,不是覆盖原来的文件,而是在文件的后面增加(0),(1)这样的数字,这里的判断就相当于同一个文件名称我们最多不可以超过32,既然问题找到了,那就修复,既然不让文件名重复,那我们就在赋值文件名的地方改成随机生成文件名,我这里采用的是UUID的方式。


values.put(MediaStore.Images.Media.DISPLAY_NAME, UUID.randomUUID().toString());

这样就可以解决问题了。

这种底层限制不出问题,一般情况不会去关注,但是出了问题要学会怎么找问题,怎么修正错误。

com.android.providers.media.MediaProvider 这个类是android底层源码,需要下载源码才可以看到,直接跟代码是找不到这个类的,这点需要注意,源码获取的方式在 android源码仓库 可以看到下载方式,这个是官方公布的下载方式哦。

标签:java,name,自定义,image,MediaProvider,Android,com,bug,android
From: https://blog.csdn.net/m0_67228868/article/details/140957260

相关文章

  • 织梦dedecms调用文章列表时候判断文章自定义属性
    有时候我们需要通过判断文章的属性来给相应的属性以相应的样式,例如为推荐的文章添加推荐的标志等等。例如以下代码就可以判断出文章是否是推荐和图片这两个属性,并作不同的样式输出:[field:arrayrunphp=&#39;yes&#39;]if(@me[&#39;flag&#39;]==&#39;c,p&#39;)@me=&#39;<em>......
  • wordpress教程栏目给大家介绍自定义wordpress文件上传路径的方法
    自WordPress3.5版本开始,隐藏了后台媒体设置页面的“默认上传路径和文件的完整URL地址”选项,可以通过下面的代码将该选项调出来。将下面的代码添加到当前主题functions.php文件中,就可以调出该选项:if(get_option(&#39;upload_path&#39;)==&#39;wp-content/uploads&#39;||get_op......
  • 在 jupyter Notebook 中导入自定义模块的问题
    假设我们有一个如下的文件结构,#注意:不是实际的目录结构,而是类似的root../tests../src../__init__.pyutils../__init__.pydata.pypipeline.pysqlal../__init__.pysql_alchm.pytest.pyprocess.ipynb......
  • Windows 和 MacOS 上安装配置ADB(安卓调试桥)_android adb工具安装 mac
    一、Android调试桥(ADB)Android调试桥(ADB)是一款多功能命令行工具,它让你能够更便捷地访问和管理Android设备。使用ADB命令,你可以轻松执行以下操作网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!在设备上安装、复制和删除文件;安装应用程序;录制设备屏幕或截......
  • 呆滞料分析报表二开增加自定义字段
     业务背景物料资料添加了自定义字段,在呆滞料分析无法直观看到,同时不能直观看到物料在仓库多久了。 业务需求在呆滞料分析报表显示物料的品牌型号,以及计算物料库龄。 方案设计二开标准产品,添加字段,创建插件继承标准产品插件,重写方法,自定义临时表获取初步查询......
  • Android逆向:修改APK并重打包签名
    在Android逆向中,经常需要对APK修改,然后重新打包并签名。这篇文章中,介绍了如何使用各个工具来完成这个过程。各个步骤以及所需工具:解压APK文件; 工具:apktool进行修改;     工具:看修改需求重新打包APK; 工具:apktool将APK对齐;   工具:zipalign生成密钥文件,并对AP......
  • linux进程篇总结——实战——自定义shell
        前言:经过过去两章十二篇文章的学习,我们已经知道了进程的基本概念以及进程的控制方法。本篇内容就是使用过去学习的内容自己写一个功能简单的shell外壳程序,也就是我们使用的bash命令行。本篇内容是过去进程知识的集大成者。我们在这个实战程序中,将过去学过的......
  • Android 广播 Broadcast Receiver
    广播(Broadcast)是Android中的一种机制,允许应用程序之间传递消息。广播在Android中扮演着重要角色,能够在不同的组件间传递信息,无论是应用内部还是跨应用。下面我将详细解释广播的机制,并提供几个示例,按照难度逐步增加。广播机制详细解释1.广播的基本概念广播允许应用程序在系统中......
  • (已解决)QT4 自定义信号函数调用报错 error: C2248: “Boss::DeadSignal”: 无法访问 pr
     (解决方法见文章末尾)报错语句如下 DeadSignal是自定义槽函数,是放在public下的,不知道为什么报错说是protected,不知道是不是版本问题Boss类和DeadSignal定义如下 mboss是在自定义类Widget中调用的Boss对象 调用位置是Widget的自定义槽函数 解决方法在Boss中定......
  • Android开发 - DialogFragment 类解析
    DialogFragment是什么DialogFragment是一种用于显示对话框的工具,同时它也是一个抽象类。在Android应用中,对话框是一种小窗口,通常用于显示重要信息或提示用户进行某些操作。通过使用DialogFragment,我们可以在应用中方便地显示和管理对话框DialogFragment的好处使用Dialo......