Fichier de sauvegarde Android sur un stockage externe

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 faire ceci:

Ssortingng 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 cela lance une exception:

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

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

Si je mets le nom de fichier à: "MyApp/MediaTag-"+objectId+" cela fonctionne, mais si j’essaye de créer et de sauvegarder le fichier dans un autre répertoire, il jette l’exception.

Et une autre question: Existe-t-il un moyen de rendre mes fichiers privés dans un stockage externe afin que les utilisateurs ne puissent pas les voir dans la galerie, uniquement s’ils connectent leur périphérique en tant que Disk Drive ?

Utilisez cette fonction pour enregistrer votre bitmap dans la carte SD

 private void SaveImage(Bitmap finalBitmap) { Ssortingng root = Environment.getExternalStorageDirectory().toSsortingng(); File myDir = new File(root + "/saved_images"); if (!myDir.exists()) { myDir.mkdirs(); } Random generator = new Random(); int n = 10000; n = generator.nextInt(n); Ssortingng 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

  

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

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

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

Celui-ci le fait (2 changements):

 private void saveImageToExternalStorage(Bitmap finalBitmap) { Ssortingng root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toSsortingng(); File myDir = new File(root + "/saved_images"); myDir.mkdirs(); Random generator = new Random(); int n = 10000; n = generator.nextInt(n); Ssortingng 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 Ssortingng[] { file.toSsortingng() }, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(Ssortingng path, Uri uri) { Log.i("ExternalStorage", "Scanned " + path + ":"); Log.i("ExternalStorage", "-> uri=" + uri); } }); } 

Vous avez besoin d’une permission pour cela

 < uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> public boolean saveImageOnExternalData(Ssortingng 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 } 

Assurez-vous que votre application dispose des permissions appropriées pour pouvoir écrire sur le stockage externe: http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE

Cela devrait ressembler à ceci dans votre fichier manifeste:

  

Essaye ça :

  1. Vérifiez le périphérique de stockage externe
  2. Ecrire un fichier
  3. Lire le fichier
 public class WriteSDCard extends Activity { private static final Ssortingng 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; Ssortingng 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 { Ssortingng 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"); } } 

Probablement une exception est levée parce qu’il n’y a pas de sous- MediaCard MediaCard. Vous devriez vérifier si tous les répertoires du chemin existent.

À propos de la visibilité de vos fichiers: si vous placez un fichier nommé .nomedia dans votre .nomedia vous .nomedia à Android que vous ne souhaitez pas qu’il recherche des fichiers multimédias et qu’ils n’apparaissent pas dans la galerie.

J’ai créé une AsyncTask pour enregistrer des bitmaps.

 public class BitmapSaver extends AsyncTask { public static final Ssortingng 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 Ssortingng timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date()); File mediaFile; Ssortingng 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; Ssortingng[] arrayOfSsortingng = new Ssortingng[1]; arrayOfSsortingng[0] = this.pictureFile.toSsortingng(); MediaScannerConnection.scanFile(localContext, arrayOfSsortingng, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(Ssortingng paramAnonymousSsortingng , Uri paramAnonymousUri) { } }); return; } catch (Exception localException2) { } } } } 

depuis Android 4.4 sauvegarde des fichiers a été modifiée. il y a

 ContextCompat.getExternalFilesDirs(context, name); 

il reprend un tableau.

quand le nom est nul

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

la deuxième valeur est comme /storage/extSdCard/Android/com.my.package/files

Android 4.3 et moins, il retient un seul tableau d’article

parties de code peu compliqué mais cela 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(); Ssortingng 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; } 

Mise à jour 2018, SDK> = 23.

Maintenant, vous devez également vérifier si l’utilisateur a accordé la permission de stockage externe en utilisant:

 public boolean isStoragePermissionGranted() { Ssortingng TAG = "Storage Permission"; if (Build.VERSION.SDK_INT >= 23) { if (this.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { Log.v(TAG, "Permission is granted"); return true; } else { Log.v(TAG, "Permission is revoked"); ActivityCompat.requestPermissions(this, new Ssortingng[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); return false; } } else { //permission is automatically granted on sdk<23 upon installation Log.v(TAG,"Permission is granted"); return true; } } public void saveImageBitmap(Bitmap image_bitmap, String image_name) { String root = Environment.getExternalStorageDirectory().toString(); if (isStoragePermissionGranted()) { // check or ask permission File myDir = new File(root, "/saved_images"); if (!myDir.exists()) { myDir.mkdirs(); } String fname = "Image-" + image_name + ".jpg"; File file = new File(myDir, fname); if (file.exists()) { file.delete(); } try { file.createNewFile(); // if file already exists will do nothing FileOutputStream out = new FileOutputStream(file); image_bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } MediaScannerConnection.scanFile(this, new String[]{file.toString()}, new String[]{file.getName()}, null); } } 

et bien sûr, ajoutez le AndroidManifest.xml :

  

Ce code fonctionne très bien et a également fonctionné sur KitKat. Appréciez @RajaReddy PolamReddy
Ajout de quelques étapes supplémentaires ici et également visible sur la galerie.

 public void SaveOnClick(View v){ File mainfile; Ssortingng fpath; try { //ie 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); Ssortingng 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.toSsortingng(); galleryAddPic(fpath); } catch(FileNotFoundException e){ e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

Ceci est le scanner de médias à visible dans la galerie.

 private void galleryAddPic(Ssortingng 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); }