Android - Как обойти ошибку «нет свободного места на устройстве» - PullRequest
2 голосов
/ 17 февраля 2012

Так что мое последнее приложение сталкивается с этой проблемой, когда в 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;
        }

Ответы [ 2 ]

1 голос
/ 17 февраля 2012

вы фактически используете внутреннюю память, используя getCacheDir() в своем операторе else.Однако, если вы хотите хранить большие данные, рекомендуется использовать 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");
0 голосов
/ 17 февраля 2012

Я закончил тем, что изменил свой код, где я создаю свои каталоги, следующим образом:

  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();
}

Пока что с помощью этого я могу еще раз сохранить снимки, сделанные на камеру, со всеми изображениями в моем регионе.

...