2011-10-25 6 views
68

J'ai un petit problème avec la création d'un répertoire et l'enregistrement d'un fichier sur mon application Android. J'utilise ce morceau de code pour ce faire:Enregistrement d'un fichier Android sur le stockage externe

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

Mais il est lancer une exception:

java.io.FileNotFoundException:/mnt/sdcard/MyApp/MediaCard/MediaCard-0. .png (Aucun fichier ou répertoire)

sur cette ligne: fos = new FileOutputStream(file);

Si je mets le nom du fichier: "MyApp/MediaTag-"+objectId+" il fonctionne, mais si je essayez de créer et enregistrer le fichier dans un autre répertoire où il lance l'exception. Donc, des idées que je fais mal?

Et une autre question: Y at-il un moyen de rendre mes fichiers privés dans le stockage externe afin que l'utilisateur ne peut pas les voir dans la galerie, seulement s'il connecte son appareil comme Disk Drive?

Répondre

164

Utilisez cette fonction pour enregistrer votre bitmap dans la carte 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(); 
    } 
} 

et ajoutez ceci dans le manifeste

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

EDIT: En utilisant cette ligne, vous pourrez voir les images enregistrées dans la vue de la galerie.

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

regard sur ce lien aussi http://rajareddypolam.wordpress.com/?p=3&preview=true

+9

Vous devriez toujours utiliser 'Environment.getExternalStorageDirectory()' au lieu de '/ sdcard'. –

+0

le code fonctionne bien, mais les images sont montrées à deux endroits dans la galerie à huis clos et mon dossier aussi. Comment puis-je faire cela. –

+1

il enregistre dans votre dossier seulement, il montre à huis clos signifie que vous prenez des images par l'appareil photo automatiquement il stocke dans l'appareil photo .. –

3

Probablement exception est levée parce qu'il n'y a pas MediaCard subdir. Vous devriez vérifier si tous les répertoires du chemin existent. A propos de la visibilité de vos fichiers: si vous placez le fichier .nomedia dans votre répertoire, vous indiquez à Android que vous ne souhaitez pas qu'il les analyse pour les fichiers multimédia et qu'ils n'apparaissent pas dans la galerie.

4

Essayez ceci:

  1. Vérifiez le périphérique de stockage externe
  2. Ecrire fichier
  3. Lire fichier
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

Cela ressemble beaucoup au code d'ici: http://stackoverflow.com/a/8330635/19679 . Si c'est tiré de là, vous devriez probablement citer cela dans votre réponse. –

20

Le code présenté par RajaReddy ne travaille plus pour KitKat

Celui-ci fait (2 changements):

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

Je reçois uri null? –

0

Ce code fonctionne très & sur KitKat A travaillé aussi bien. Appréciez @RajaReddy PolamReddy
Ajouté quelques étapes supplémentaires ici et également visible sur la galerie.

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

} 

Ceci est un scanner de média visible dans la galerie.

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

depuis l'enregistrement du fichier android 4.4 a été modifié. il y a

ContextCompat.getExternalFilesDirs(context, name); 

il retaille un tableau.

lorsque le nom est nulle

la première valeur est comme /storage/emulated/0/Android/com.my.package/files

la deuxième valeur est comme /storage/extSdCard/Applications/com.my.package/fichiers

android 4.3 et moins il un seul tableau retour précis ou chiffré de l'article

parties du peu de code compliqué, mais il montre comment cela fonctionne:

/** 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

J'ai créé un AsyncTask pour enregistrer des bitmaps.

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

Comment puis-je enregistrer l'image gif ?? –

+1

L'image Gif contient plusieurs images. vous devez d'abord séparer ces images, vous pouvez utiliser cette méthode. C'est mon point de vue. – Nepster

+1

je l'ai fait à partir de http://stackoverflow.com/questions/39826400/how-to-save-gif-image-in-sdcard –

5

Vous avez besoin d'une autorisation pour cette

< 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 
} 
Questions connexes