我正在尝试从照片库中选择一个图像文件并写入SD卡。以下是导致异常的代码。在尝试创建FileOutputStream时,它似乎抛出此异常。我将以下行添加到嵌套在application元素中的清单文件中。我无法找到问题的解决方案:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public boolean saveSelectedImage( Uri selectedImage, int imageGroup,
int imageNumber )
{
boolean exception = false;
InputStream input = null;
OutputStream output = null;
if( externalStorageIsWritable() )
{
try
{
ContentResolver content = ctx.getContentResolver();
input = content.openInputStream( selectedImage );
if(input != null) Log.v( CLASS_NAME, "Input Stream Opened successfully");
File outFile = null;
File root = Environment.getExternalStorageDirectory( );
if(root == null) Log.v(CLASS_NAME, "FAILED TO RETRIEVE DIRECTORY");
else Log.v(CLASS_NAME, "ROOT DIRECTORY is:"+root.toString());
output = new FileOutputStream( root+"/Image"+ imageGroup + "_" + imageNumber + ".png" );
if(output != null) Log.e( CLASS_NAME, "Output Stream Opened successfully");
// output = new FileOutputStream
// ("/sdcard/Image"+imageGroup+"_"+imageNumber+".png");
byte[] buffer = new byte[1000];
int bytesRead = 0;
while ( ( bytesRead = input.read( buffer, 0, buffer.length ) ) >= 0 )
{
output.write( buffer, 0, buffer.length );
}
} catch ( Exception e )
{
Log.e( CLASS_NAME, "Exception occurred while moving image: ");
e.printStackTrace();
exception = true;
} finally
{
// if(input != null)input.close();
// if(output != null)output.close();
// if (exception ) return false;
}
return true;
} else
return false;
}
答案 0 :(得分:24)
这是您的清单文件的样子
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".WriteCBTextToFileActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
答案 1 :(得分:9)
我有这个问题,这里的答案没有解决它,因为我犯了一个非常愚蠢的错误。
确保你给你的Android模拟器一张SD卡......我把SD卡的大小留空了,所以当然找不到任何东西。最重要的是,我在SD卡中指定了一个尚未创建的目录,所以一定要考虑这个案例。
(您可以通过转到Android虚拟设备管理器,编辑您选择的模拟器,并为SD卡大小输入一些值来更改AVD的SD卡设置)
答案 2 :(得分:7)
您还必须确保外部存储子系统处于正确状态;使用Environment.getExternalStorageState()
并查找唯一安全状态Environment.MEDIA_MOUNTED
。
将这些部分的异常处理范围缩小到IOException
也是一个好主意,因此您不要过度恢复特定于IO的问题,例如:媒体未安装。
如果您需要活动,则广播意图(Intent.ACTION_MEDIA_xxx
)包含您可以使用IntentListener
注册的相同信息。
另请注意,当您使用USB进行调试时,外部存储可能禁用!
设备启动期间还有一段延长的时间,外部存储不可用。如果你在启动时做服务,这就是一个问题。
通常,您的应用程序在访问时必须知道外部存储状态,并处理它不可用或在访问时不可用的情况。
答案 3 :(得分:3)
如果您在清单中设置了正确的权限,请确保您的设备不在&#34;磁盘驱动器&#34;连接到PC时的模式。将其更改为&#34;仅限充电&#34;模式,它应该工作。
答案 4 :(得分:2)
请注意,除了Saurabh的回答,自API 23起,您需要在运行时请求权限。
见这里: https://developer.android.com/training/permissions/requesting.html
Justin Fiedler在这里回答:https://stackoverflow.com/a/33288986/328059
此外,在更改权限并使用“即时运行”重新运行应用程序后,我发现了几种情况,但未更新权限。因此,作为最佳实践,在更改清单后,我从目标设备卸载应用程序,然后重建。
答案 5 :(得分:0)
您可以尝试:
String myPath=Environment.getExternalStorageDirectory()+"/Image"+ imageGroup + "_" + imageNumber + ".png";
File myFile = new File();
input = new FileInputStream(myFile);
答案 6 :(得分:0)
尝试使用openFileOutput("filename")
返回FileOutputStream,而不是自己指定位置。
检查文档 here