Android - 如何解决“设备上没有剩余空间”的问题错误
所以我最新的应用程序遇到了这个问题,它在 logcat 中抱怨设备上没有空间来保存文件,但情况绝对不是这样,因为我可以关闭我的应用程序打开库存相机并拍照。其他人都是如何处理这个问题的。
编辑:此方法中发生错误
private void writeFile(Bitmap bmp, File f) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 80, out);//<---error here
} catch (NullPointerException e) {
e.printStackTrace();
Log.w("nullpointerException on image error", "nullpointer");
} catch (FileNotFoundException e) {
Log.w("fileNotfoundException on image error", "filenotfound");
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try { if (out != null ) out.close(); }
catch(Exception ex) {}
}
}
,这是有关此错误的 logcat 报告:
java.io.IOException: no space left on device
at org.apache.harmony.luni.platform.OSFileSystem.write(Native Method)
at dalvik.system.BlockGuard$WrappedFileSystem.write(BlockGuard.java:171)
at java.io.FileOutputStream.write(FileOutputStream.java:300)
at android.graphics.Bitmap.nativeCompress(Native Method)
at data.ImageManager.writeFile(ImageManager.java:215)
at data.ImageManager.getBitmap(ImageManager.java:192)
at data.ImageManager.access$1(ImageManger.java:102)
at data.ImageManager$ImageQueueManager.run(ImageManager.java:290)
at java.lang.Thread.run(Thread.java:1019)
编辑:这是我如何在外部存储器上创建目录的方式
这是我用来创建我认为是 sd 卡的位置
String sdState = android.os.Environment.getExternalStorageState();
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
File sdDir = android.os.Environment.getExternalStorageDirectory();
cacheDir = new File(sdDir,"data/gr");
}
else
cacheDir = context.getExternalCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
if(sdState.equals(android.os.Environment.MEDIA_MOUNTED)){
File adSdDir = android.os.Environment.getExternalStorageDirectory();
adCacheDir = new File(adSdDir,"data/ad");
}else
adCacheDir = context.getExternalCacheDir();
if(!adCacheDir.exists())
adCacheDir.mkdirs();
}
,然后在我查找或创建图像以进入目录的方法中:
private Bitmap getBitmap(ImgRequestObj ids) {
String url = null;
String filename = ids.objId.toString();
File f = null;
try{
if(ids.objName.equals("mark")){
url = graffMarksURL;
f = new File(cacheDir, filename);
}else if(ids.objName.equals("admark")){
url = adMarksURL;
f = new File(adCacheDir, filename);
}
// Is the bitmap in our cache?
Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
if(bitmap != null) return bitmap;
// Nope, have to download it
try {
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
DefaultHttpClient client;
HttpResponse response = null;
HttpParams params = null;// new Http parameters to be used for extra buffering room in VM
HttpPost post = null;
InputStream is = null;
BufferedInputStream bis = null;
Bitmap bmp = null;
ArrayList<NameValuePair> nvp1 = new ArrayList<NameValuePair>();
nvp1.add(new BasicNameValuePair("id", ids.objId.toString()));
// - martin passing id to php script select statement
client = new DefaultHttpClient();
try {
post = new HttpPost(url);
params = post.getParams();//Setting the new Http params to post
post.setEntity(new UrlEncodedFormEntity(nvp1));
try{
HttpConnectionParams.setSocketBufferSize(params, 8192);//Defining the new buffer size
response = client.execute(post);
}
catch(HttpResponseException e){
e.getCause();
}
//Capture response from query and prepare as input
HttpEntity entity = response.getEntity();
// move content to Input Stream
is = entity.getContent();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bis = new BufferedInputStream(is);
try{
bmp = BitmapFactory.decodeStream(bis, null, bfOptions);
}finally{}
if( is != null )
try {
is.close();
//response = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Log.w("inputstream of image closed", "for this image "+id.toString());
if( bis != null )
try {
//response = null;
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bitmap = bmp;
writeFile(bitmap, f);
try{
bmp = null;
}catch(NullPointerException e){
e.printStackTrace();
}
return bitmap;}
catch(Exception e){
e.printStackTrace();
}
return bitmap;
}catch(NullPointerException e){
e.printStackTrace();
}
return null;
}
So my latest app runs into this problem where it complains in the logcat that theres no room left on the device to save files but that is definitely not the case as I can close my app open the stock camera and take a picture. How has everybody else dealt with this problem.
Edit: The error occurs in this method
private void writeFile(Bitmap bmp, File f) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 80, out);//<---error here
} catch (NullPointerException e) {
e.printStackTrace();
Log.w("nullpointerException on image error", "nullpointer");
} catch (FileNotFoundException e) {
Log.w("fileNotfoundException on image error", "filenotfound");
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try { if (out != null ) out.close(); }
catch(Exception ex) {}
}
}
and this is the logcat report on this error:
java.io.IOException: no space left on device
at org.apache.harmony.luni.platform.OSFileSystem.write(Native Method)
at dalvik.system.BlockGuard$WrappedFileSystem.write(BlockGuard.java:171)
at java.io.FileOutputStream.write(FileOutputStream.java:300)
at android.graphics.Bitmap.nativeCompress(Native Method)
at data.ImageManager.writeFile(ImageManager.java:215)
at data.ImageManager.getBitmap(ImageManager.java:192)
at data.ImageManager.access$1(ImageManger.java:102)
at data.ImageManager$ImageQueueManager.run(ImageManager.java:290)
at java.lang.Thread.run(Thread.java:1019)
Edit: Heres how I though you create a directory on external memory
This is what Im using to create the place that I thought would be the sd card
String sdState = android.os.Environment.getExternalStorageState();
if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
File sdDir = android.os.Environment.getExternalStorageDirectory();
cacheDir = new File(sdDir,"data/gr");
}
else
cacheDir = context.getExternalCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
if(sdState.equals(android.os.Environment.MEDIA_MOUNTED)){
File adSdDir = android.os.Environment.getExternalStorageDirectory();
adCacheDir = new File(adSdDir,"data/ad");
}else
adCacheDir = context.getExternalCacheDir();
if(!adCacheDir.exists())
adCacheDir.mkdirs();
}
and then in the method that I look for or create the image to go into the directory:
private Bitmap getBitmap(ImgRequestObj ids) {
String url = null;
String filename = ids.objId.toString();
File f = null;
try{
if(ids.objName.equals("mark")){
url = graffMarksURL;
f = new File(cacheDir, filename);
}else if(ids.objName.equals("admark")){
url = adMarksURL;
f = new File(adCacheDir, filename);
}
// Is the bitmap in our cache?
Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
if(bitmap != null) return bitmap;
// Nope, have to download it
try {
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither=false; //Disable Dithering mode
bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
DefaultHttpClient client;
HttpResponse response = null;
HttpParams params = null;// new Http parameters to be used for extra buffering room in VM
HttpPost post = null;
InputStream is = null;
BufferedInputStream bis = null;
Bitmap bmp = null;
ArrayList<NameValuePair> nvp1 = new ArrayList<NameValuePair>();
nvp1.add(new BasicNameValuePair("id", ids.objId.toString()));
// - martin passing id to php script select statement
client = new DefaultHttpClient();
try {
post = new HttpPost(url);
params = post.getParams();//Setting the new Http params to post
post.setEntity(new UrlEncodedFormEntity(nvp1));
try{
HttpConnectionParams.setSocketBufferSize(params, 8192);//Defining the new buffer size
response = client.execute(post);
}
catch(HttpResponseException e){
e.getCause();
}
//Capture response from query and prepare as input
HttpEntity entity = response.getEntity();
// move content to Input Stream
is = entity.getContent();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bis = new BufferedInputStream(is);
try{
bmp = BitmapFactory.decodeStream(bis, null, bfOptions);
}finally{}
if( is != null )
try {
is.close();
//response = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Log.w("inputstream of image closed", "for this image "+id.toString());
if( bis != null )
try {
//response = null;
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bitmap = bmp;
writeFile(bitmap, f);
try{
bmp = null;
}catch(NullPointerException e){
e.printStackTrace();
}
return bitmap;}
catch(Exception e){
e.printStackTrace();
}
return bitmap;
}catch(NullPointerException e){
e.printStackTrace();
}
return null;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您实际上是通过在 else 语句中使用
getCacheDir()
来使用内部内存。但是,如果您想存储大数据,那么建议使用 getExternalCacheDir(),因为并非所有 Android 手机都具有巨大的内部存储空间,但它们确实/可能具有更大的外部存储空间。you are actually using internal memory by using
getCacheDir()
in your else statement. However, if you want to store large data then its recommended to usegetExternalCacheDir()
because not all android phones have huge internal storage, but they do/may have bigger external storage.我最终将创建目录的代码更改为以下内容:
到目前为止,使用此功能我可以再次保存用相机拍摄的图像以及我所在区域下载的所有图像。
I ended up changing my code where I create my directories to the following:
So far using this I am able to once again save images I take with the camera with all the images in my area download.