【解决】Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=99

文章分析了Android程序在使用相机拍照并存储时出现的问题,主要是由于存储操作反馈的数据为空导致的闪退。问题出现在没有对onActivityResult中的data进行空值判断,以及自定义存储路径可能存在不存在的文件夹或命名含有特殊符号。解决方案包括:在使用data前做空判断,拍照前检查并创建文件夹,以及避免在照片命名中使用空格等特殊符号。
摘要由CSDN通过智能技术生成

问题出现场景

此情况出现在Android程序将相机所拍照片存至手机的过程,主要原因是存储照片的操作反馈的数据为空,在代码中没有合理处理的原因。当使用APP时,出现了闪退现象。究于此,文章进行问题分析和解决。

出现问题的代码

相机拍照请求代码:

REQUEST_CODE_CAMERA = 1
//实例化一个intent,并指定action
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//指定一个图片路径对应的file对象 
uri = Uri.fromFile(ImageUtil.getImageFile());
// 将所拍照片写至 uri 对应的文件路径
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
//启动activity
startActivityForResult(intent, REQUEST_CODE_CAMERA);

拍照后结果处理代码:

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //此处直接认为请求反馈回来的有数据,进行后续处理了。
		 if(requestCode == 1) {
                if(resultCode == RESULT_OK) {
                    Toast.makeText(getApplicationContext(), "图片已保存",
                           Toast.LENGTH_SHORT).show(); 
                }           
           }
       } 

原因分析

1 先根据Android程序的运行逻辑来看

下面代码展示了Android相机拍照过程中的关键代码,通过代码逻辑可看出:
Android系统框架Camera应用程序在默认情况下,即不需要指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);照相机有自己默认的存储路径,拍摄的照片将被写入到对应路径,且仅返回一个响应代码RESULT_OK,如果想访问原始图片,可以通过getIntent().getStringExtra(MediaStore.EXTRA_OUTPUT),得到原始图片位置,然后进行访问图片。如果指定了目标uri,data就没有反馈数据,如果没有指定uri,则data就返回有数据,且为bitmap!
综上,出错原因可能为我们没有在onActivityResult 方法中的data 进行空值判断。

// First handle the no crop case -- just return the value.  If the
// caller specifies a "save uri" then write the data to it's
// stream. Otherwise, pass back a scaled down version of the bitmap
// directly in the extras.
if (mSaveUri != null) {	//存在mSaveUri,即指定了目标uri
	OutputStream outputStream = null;
	try {
		outputStream = mContentResolver.openOutputStream(mSaveUri);
		outputStream.write(data);
		outputStream.close();
 
		setResult(RESULT_OK);	//直接返回RESULT_OK,并没有指定intent
		finish();
	} catch (IOException ex) {
		// ignore exception
	} finally {
		Util.closeSilently(outputStream);
	}
} else {
	Bitmap bitmap = createCaptureBitmap(data);
	// 返回RESULT_OK,并包含一个Intent对象,其中Extra中科key为data,value为一个bitmap
	setResult(RESULT_OK, new Intent("inline-data").putExtra("data", bitmap));
	finish();
}

其他原因

问题一
我们自定义的存储路径不存在,且我们也没有在保存前判断路径是否存在,来新建路径,导致照片无法存储,如自定义存储路径是/mnt/sdcard/pics/,而手机SD 卡下在拍照前没有名为pics
的文件夹,那么部分手机拍照后图片不会保存,导致我们无法获得照片,大多数手机的相机遇到文件夹不存在的情况都会自己创建出不存在的文件夹,而个别手机却不会创建,其代表机型为:三星I8258、华为H30-T00、红米等。解决的方法就是在指定存储路径前先判断路径中的文件夹是否都存在,不存在先创建再调用相机。
问题二
照片可以存储,但是名字不对 file:///mnt/sdcard/123 1.jpg,由于Uri 的fromFile 方法会将路径中的空格用“%20”取代。其实对于大多数的手机这都不算事,手机在解析存储路径的时候都会将“%20”替换为空格,这样实际上最终的照片名字还是我们当初指定的名字:123 1.jpg,遗憾的是个别手机(如酷派7260)系统自带的相机没有将“%20”读成空格,拍照后的照片的名字是123%201.jpg,我们用路径“file:///mnt/sdcard/123 1.jpg”就不能找到该图像了。

根据以上分析,对应的解决方案如下:

(1)如果我们指定了路径,就不要使用data 来获取照片,起码在使用前要做空判断,即使用 onActivityResult 中返回的(data)做空判断。
(2)指定拍照路径时,先检查路径中的文件夹是否都存在,不存在时先创建文件夹再调用相机拍照。
(3)指定拍照存储路径时,照片的命名中不要包含空格等特殊符号。

【文章借鉴了这位前辈的文章:https://blog.csdn.net/zimo2013/article/details/16916279】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,你遇到了一个运行时异常:Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: Cannot find implementation。这个异常通常是由于找不到某个类的实现导致的。解决这个问题的方法有以下几种: 1. 检查依赖项:首先,确保你的项目中包含了所需的依赖项。在Android开发中,你可以在项目的build.gradle文件中添加所需的依赖项。例如,如果你使用的是Gradle构建工具,你可以在dependencies部分添加所需的库。然后,重新构建你的项目并运行它。 2. 检查类路径:如果你确定依赖项已经正确添加到项目中,那么可能是类路径的问题。类路径是指Java虚拟机(JVM)用来查找类文件的路径。确保你的类路径包含了所需的类文件。你可以通过在命令行中使用java命令的-cp选项来指定类路径。例如,如果你的类文件位于一个名为lib的文件夹中,你可以使用以下命令来运行你的应用程序: ```shell java -cp lib/ YourMainClass ``` 3. 检查类名和包名:如果你确定依赖项和类路径都没有问题,那么可能是类名或包名的问题。确保你在代码中正确引用了类名和包名。检查你的import语句和类的全限定名是否正确。 4. 清除缓存和重新构建:有时候,清除构建缓存并重新构建项目可以解决一些奇怪的问题。你可以尝试清除你的项目的构建缓存,并重新构建它。 5. 检查编译版本:如果你在使用某个库或框架时遇到了这个问题,确保你的编译版本与该库或框架的要求相匹配。有时候,不同的库或框架需要特定的编译版本才能正常工作。 这些是解决Caused by: java.lang.ClassNotFoundException: Cannot find implementation异常的一些常见方法。根据你的具体情况,你可以尝试其中的一种或多种方法来解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值