Android - 如何解决“设备上没有剩余空间”的问题错误

发布于 2025-01-07 03:22:18 字数 6215 浏览 4 评论 0原文

所以我最新的应用程序遇到了这个问题,它在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很糊涂小朋友 2025-01-14 03:22:18

您实际上是通过在 else 语句中使用 getCacheDir() 来使用内部内存。但是,如果您想存储大数据,那么建议使用 getExternalCacheDir(),因为并非所有 Android 手机都具有巨大的内部存储空间,但它们确实/可能具有更大的外部存储空间。

if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) { 
   File sdDir = context.getExternalCacheDir();
   cacheDir = new File(sdDir,"data"); 
} 
else 
   Log.e("storage", "SD card not found");

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 use getExternalCacheDir() because not all android phones have huge internal storage, but they do/may have bigger external storage.

if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) { 
   File sdDir = context.getExternalCacheDir();
   cacheDir = new File(sdDir,"data"); 
} 
else 
   Log.e("storage", "SD card not found");
指尖凝香 2025-01-14 03:22:18

我最终将创建目录的代码更改为以下内容:

  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.getExternalFilesDir(sdState); <--changed

    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.getExternalFilesDir(sdState); <--changed

    if(!adCacheDir.exists())
        adCacheDir.mkdirs();
}

到目前为止,使用此功能我可以再次保存用相机拍摄的图像以及我所在区域下载的所有图像。

I ended up changing my code where I create my directories to the following:

  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.getExternalFilesDir(sdState); <--changed

    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.getExternalFilesDir(sdState); <--changed

    if(!adCacheDir.exists())
        adCacheDir.mkdirs();
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文