2011-10-25 19 views
68

Ho un piccolo problema con la creazione di una directory e il salvataggio di un file sulla mia applicazione Android. Sto usando questo pezzo di codice per fare questo:Salvataggio di file su memoria esterna Android

String filename = "MyApp/MediaTag/MediaTag-"+objectId+".png"; 
File file = new File(Environment.getExternalStorageDirectory(), filename); 
FileOutputStream fos; 

fos = new FileOutputStream(file); 
fos.write(mediaTagBuffer); 
fos.flush(); 
fos.close(); 

ma è un'eccezione:

java.io.FileNotFoundException:/mnt/sdcard/frontend/MediaCard/MediaCard-0. png (Nessun file o directory)

su quella linea: fos = new FileOutputStream(file);

Se ho impostato il nome del file: "MyApp/MediaTag-"+objectId+" che sta funzionando, ma se io prova a creare e salvare il file in un'altra directory sta generando l'eccezione. Quindi qualche idea su cosa sto facendo male?

E un'altra domanda: esiste un modo per rendere privati ​​i miei file nella memoria esterna in modo che l'utente non possa vederli nella galleria, solo se connette il suo dispositivo come Disk Drive?

risposta

164

Usare questa funzione per salvare il bitmap nella scheda SD

private void SaveImage(Bitmap finalBitmap) { 

    String root = Environment.getExternalStorageDirectory().toString(); 
    File myDir = new File(root + "/saved_images");  
    myDir.mkdirs(); 
    Random generator = new Random(); 
    int n = 10000; 
    n = generator.nextInt(n); 
    String fname = "Image-"+ n +".jpg"; 
    File file = new File (myDir, fname); 
    if (file.exists()) 
     file.delete(); 
    try { 
     FileOutputStream out = new FileOutputStream(file); 
     finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); 
     out.flush(); 
     out.close(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

e aggiungere questo in palese

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

MODIFICA: Utilizzando questa linea sarà possibile vedere le immagini salvate nella vista galleria.

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, 
         Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 

un'occhiata a questo link anche http://rajareddypolam.wordpress.com/?p=3&preview=true

+9

Si dovrebbe ancora usare 'Environment.getExternalStorageDirectory()' invece di '/ sdcard'. Codice –

+0

funziona bene. Ma le immagini vengono mostrate in due posti nella galleria nella fotocamera e anche nella mia cartella. Come posso fare questo. –

+1

salva solo nella tua cartella, mostra nella fotocamera significa che stai acquisendo le immagini attraverso la fotocamera automaticamente memorizza nella Fotocamera .. –

3

Probabilmente viene generata un'eccezione perché non c'è MediaCard sottodirectory. Dovresti controllare se esistono tutte le dir nel percorso.

Informazioni sulla visibilità dei file: se si inserisce il file con il nome .nomedia nella directory dir, si dice ad Android che non si desidera eseguirne la scansione per i file multimediali e che non verranno visualizzati nella galleria.

4

Try This:

  1. controllare un dispositivo di memorizzazione esterno
  2. Write File
  3. leggere il file
public class WriteSDCard extends Activity { 

    private static final String TAG = "MEDIA"; 
    private TextView tv; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     tv = (TextView) findViewById(R.id.TextView01); 
     checkExternalMedia(); 
     writeToSDFile(); 
     readRaw(); 
    } 

    /** 
    * Method to check whether external media available and writable. This is 
    * adapted from 
    * http://developer.android.com/guide/topics/data/data-storage.html 
    * #filesExternal 
    */ 
    private void checkExternalMedia() { 
     boolean mExternalStorageAvailable = false; 
     boolean mExternalStorageWriteable = false; 
     String state = Environment.getExternalStorageState(); 
     if (Environment.MEDIA_MOUNTED.equals(state)) { 
      // Can read and write the media 
      mExternalStorageAvailable = mExternalStorageWriteable = true; 
     } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { 
      // Can only read the media 
      mExternalStorageAvailable = true; 
      mExternalStorageWriteable = false; 
     } else { 
      // Can't read or write 
      mExternalStorageAvailable = mExternalStorageWriteable = false; 
     } 
     tv.append("\n\nExternal Media: readable=" + mExternalStorageAvailable 
      + " writable=" + mExternalStorageWriteable); 
    } 

    /** 
    * Method to write ascii text characters to file on SD card. Note that you 
    * must add a WRITE_EXTERNAL_STORAGE permission to the manifest file or this 
    * method will throw a FileNotFound Exception because you won't have write 
    * permission. 
    */ 
    private void writeToSDFile() { 
     // Find the root of the external storage. 
     // See http://developer.android.com/guide/topics/data/data- 
     // storage.html#filesExternal 
     File root = android.os.Environment.getExternalStorageDirectory(); 
     tv.append("\nExternal file system root: " + root); 
     // See 
     // http://stackoverflow.com/questions/3551821/android-write-to-sd-card-folder 
     File dir = new File(root.getAbsolutePath() + "/download"); 
     dir.mkdirs(); 
     File file = new File(dir, "myData.txt"); 
     try { 
      FileOutputStream f = new FileOutputStream(file); 
      PrintWriter pw = new PrintWriter(f); 
      pw.println("Hi , How are you"); 
      pw.println("Hello"); 
      pw.flush(); 
      pw.close(); 
      f.close(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
      Log.i(TAG, "******* File not found. Did you" 
       + " add a WRITE_EXTERNAL_STORAGE permission to the manifest?"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     tv.append("\n\nFile written to " + file); 
    } 

    /** 
    * Method to read in a text file placed in the res/raw directory of the 
    * application. The method reads in all lines of the file sequentially. 
    */ 
    private void readRaw() { 
     tv.append("\nData read from res/raw/textfile.txt:"); 
     InputStream is = this.getResources().openRawResource(R.raw.textfile); 
     InputStreamReader isr = new InputStreamReader(is); 
     BufferedReader br = new BufferedReader(isr, 8192); // 2nd arg is buffer 
     // size 
     // More efficient (less readable) implementation of above is the 
     // composite expression 
     /* 
     * BufferedReader br = new BufferedReader(new InputStreamReader(
     * this.getResources().openRawResource(R.raw.textfile)), 8192); 
     */ 
     try { 
      String test; 
      while (true) { 
       test = br.readLine(); 
       // readLine() returns null if no more lines in the file 
       if (test == null) break; 
       tv.append("\n" + " " + test); 
      } 
      isr.close(); 
      is.close(); 
      br.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     tv.append("\n\nThat is all"); 
    } 
} 
+2

Questo sembra molto simile al codice da qui: http://stackoverflow.com/a/8330635/19679 . Se è stato disegnato da lì, dovresti probabilmente citarlo nella tua risposta. –

20

Il codice presentato da RajaReddy non lavora più per KitKat

Questo lo fa (2 cambi):

private void saveImageToExternalStorage(Bitmap finalBitmap) { 
    String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString(); 
    File myDir = new File(root + "/saved_images"); 
    myDir.mkdirs(); 
    Random generator = new Random(); 
    int n = 10000; 
    n = generator.nextInt(n); 
    String fname = "Image-" + n + ".jpg"; 
    File file = new File(myDir, fname); 
    if (file.exists()) 
     file.delete(); 
    try { 
     FileOutputStream out = new FileOutputStream(file); 
     finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); 
     out.flush(); 
     out.close(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 


    // Tell the media scanner about the new file so that it is 
    // immediately available to the user. 
    MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null, 
      new MediaScannerConnection.OnScanCompletedListener() { 
       public void onScanCompleted(String path, Uri uri) { 
        Log.i("ExternalStorage", "Scanned " + path + ":"); 
        Log.i("ExternalStorage", "-> uri=" + uri); 
       } 
    }); 

} 
+1

Sto ottenendo uri null? –

0

Questo codice sta lavorando molto & Ha lavorato alle KitKat pure. Apprezzo @RajaReddy PolamReddy
Aggiunti altri passaggi qui e anche Visibile sulla Galleria.

public void SaveOnClick(View v){ 
File mainfile; 
String fpath; 


    try { 
//i.e v2:My view to save on own folder  
     v2.setDrawingCacheEnabled(true); 
//Your final bitmap according to my code. 
     bitmap_tmp = v2.getDrawingCache(); 

File(getExternalFilesDir(Environment.DIRECTORY_PICTURES)+File.separator+"/MyFolder"); 

      Random random=new Random(); 
      int ii=100000; 
      ii=random.nextInt(ii); 
      String fname="MyPic_"+ ii + ".jpg"; 
      File direct = new File(Environment.getExternalStorageDirectory() + "/MyFolder"); 

      if (!direct.exists()) { 
       File wallpaperDirectory = new File("/sdcard/MyFolder/"); 
       wallpaperDirectory.mkdirs(); 
      } 

      mainfile = new File(new File("/sdcard/MyFolder/"), fname); 
      if (mainfile.exists()) { 
       mainfile.delete(); 
      } 

       FileOutputStream fileOutputStream; 
     fileOutputStream = new FileOutputStream(mainfile); 

     bitmap_tmp.compress(CompressFormat.JPEG, 100, fileOutputStream); 
     Toast.makeText(MyActivity.this.getApplicationContext(), "Saved in Gallery..", Toast.LENGTH_LONG).show(); 
     fileOutputStream.flush(); 
     fileOutputStream.close(); 
     fpath=mainfile.toString(); 
     galleryAddPic(fpath); 
    } catch(FileNotFoundException e){ 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

Questo è lo scanner Media visibile in Galleria.

private void galleryAddPic(String fpath) { 
    Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE"); 
    File f = new File(fpath); 
    Uri contentUri = Uri.fromFile(f); 
    mediaScanIntent.setData(contentUri); 
    this.sendBroadcast(mediaScanIntent); 
} 
2

da quando il salvataggio di file 4.4 di Android è stato modificato. c'è

ContextCompat.getExternalFilesDirs(context, name); 

esso Retuns un array.

quando il nome è null

il primo valore è come /storage/emulated/0/Android/com.my.package/files

il secondo valore è come /immagazzinaggio/extSdCard/Android/com.my.package/file

Android 4.3 e meno si Retuns un singolo array oggetto

parti po 'di codice disordinato ma dimostra come funziona:

/** Create a File for saving an image or video 
    * @throws Exception */ 
    private File getOutputMediaFile(int type) throws Exception{ 

     // Check that the SDCard is mounted 
     File mediaStorageDir; 
     if(internalstorage.isChecked()) 
     { 
      mediaStorageDir = new File(getFilesDir().getAbsolutePath()); 
     } 
     else 
     { 
      File[] dirs=ContextCompat.getExternalFilesDirs(this, null); 
      mediaStorageDir = new File(dirs[dirs.length>1?1:0].getAbsolutePath()); 
     } 


     // Create the storage directory(MyCameraVideo) if it does not exist 
     if (! mediaStorageDir.exists()){ 

      if (! mediaStorageDir.mkdirs()){ 

       output.setText("Failed to create directory."); 

       Toast.makeText(this, "Failed to create directory.", Toast.LENGTH_LONG).show(); 

       Log.d("myapp", "Failed to create directory"); 
       return null; 
      } 
     } 


     // Create a media file name 

     // For unique file name appending current timeStamp with file name 
     java.util.Date date= new java.util.Date(); 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.ENGLISH) .format(date.getTime()); 

     File mediaFile; 

     if(type == MEDIA_TYPE_VIDEO) { 

      // For unique video file name appending current timeStamp with file name 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator + slpid + "_" + pwsid + "_" + timeStamp + ".mp4"); 

     } 
     else if(type == MEDIA_TYPE_AUDIO) { 

      // For unique video file name appending current timeStamp with file name 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator + slpid + "_" + pwsid + "_" + timeStamp + ".3gp"); 

     } else { 
      return null; 
     } 

     return mediaFile; 
    } 



    /** Create a file Uri for saving an image or video 
    * @throws Exception */ 
    private Uri getOutputMediaFileUri(int type) throws Exception{ 

      return Uri.fromFile(getOutputMediaFile(type)); 
    } 

//usage: 
     try { 
      file=getOutputMediaFileUri(MEDIA_TYPE_AUDIO).getPath(); 
     } catch (Exception e1) { 
      e1.printStackTrace(); 
      return; 
     } 
3

Ho creato un AsyncTask per il salvataggio di bitmap.

public class BitmapSaver extends AsyncTask<Void, Void, Void> 
{ 
    public static final String TAG ="BitmapSaver"; 

    private Bitmap bmp; 

    private Context ctx; 

    private File pictureFile; 

    public BitmapSaver(Context paramContext , Bitmap paramBitmap) 
    { 
     ctx = paramContext; 

     bmp = paramBitmap; 
    } 

    /** Create a File for saving an image or video */ 
    private File getOutputMediaFile() 
    { 
     // To be safe, you should check that the SDCard is mounted 
     // using Environment.getExternalStorageState() before doing this. 
     File mediaStorageDir = new File(Environment.getExternalStorageDirectory() 
       + "/Android/data/" 
       + ctx.getPackageName() 
       + "/Files"); 

     // This location works best if you want the created images to be shared 
     // between applications and persist after your app has been uninstalled. 

     // Create the storage directory if it does not exist 
     if (! mediaStorageDir.exists()){ 
      if (! mediaStorageDir.mkdirs()){ 
       return null; 
      } 
     } 
     // Create a media file name 
     String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date()); 
     File mediaFile; 
      String mImageName="MI_"+ timeStamp +".jpg"; 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName); 
     return mediaFile; 

    } 
    protected Void doInBackground(Void... paramVarArgs) 
    { 
     this.pictureFile = getOutputMediaFile(); 

     if (this.pictureFile == null) { return null; } 

     try 
     { 
      FileOutputStream localFileOutputStream = new FileOutputStream(this.pictureFile); 
      this.bmp.compress(Bitmap.CompressFormat.PNG, 90, localFileOutputStream); 
      localFileOutputStream.close(); 
     } 
     catch (FileNotFoundException localFileNotFoundException) 
     { 
      return null; 
     } 
     catch (IOException localIOException) 
     { 
     } 
     return null; 
    } 

    protected void onPostExecute(Void paramVoid) 
    { 
     super.onPostExecute(paramVoid); 

     try 
     { 
      //it will help you broadcast and view the saved bitmap in Gallery 
      this.ctx.sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri 
        .parse("file://" + Environment.getExternalStorageDirectory()))); 

      Toast.makeText(this.ctx, "File saved", 0).show(); 

      return; 
     } 
     catch (Exception localException1) 
     { 
      try 
      { 
       Context localContext = this.ctx; 
       String[] arrayOfString = new String[1]; 
       arrayOfString[0] = this.pictureFile.toString(); 
       MediaScannerConnection.scanFile(localContext, arrayOfString, null, 
         new MediaScannerConnection.OnScanCompletedListener() 
         { 
          public void onScanCompleted(String paramAnonymousString , 
            Uri paramAnonymousUri) 
          { 
          } 
         }); 
       return; 
      } 
      catch (Exception localException2) 
      { 
      } 
     } 
    } 
} 
+0

Come posso salvare l'immagine gif ?? –

+1

L'immagine GIF contiene più immagini. devi prima separare quei fotogrammi, quindi puoi usare questo metodo. È la mia opinione. – Nepster

+1

l'ho fatto da http://stackoverflow.com/questions/39826400/how-to-save-gif-image-in-sdcard –

5

Hai bisogno di un permesso per questo

< uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

public boolean saveImageOnExternalData(String filePath, byte[] fileData) { 

    boolean isFileSaved = false; 
    try { 
     File f = new File(filePath); 
     if (f.exists()) 
      f.delete(); 
     f.createNewFile(); 
     FileOutputStream fos = new FileOutputStream(f); 
     fos.write(fileData); 
     fos.flush(); 
     fos.close(); 
     isFileSaved = true; 
     // File Saved 
    } catch (FileNotFoundException e) { 
     System.out.println("FileNotFoundException"); 
     e.printStackTrace(); 
    } catch (IOException e) { 
     System.out.println("IOException"); 
     e.printStackTrace(); 
    } 
    return isFileSaved; 
    // File Not Saved 
} 
Problemi correlati