J'ai un petit problème avec la création d'un répertoire et l'enregistrement d'un fichier dans mon application Android. J'utilise ce morceau de code pour faire ceci:
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 cela lève 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 règle le nom de fichier sur: "MyApp/MediaTag-"+objectId+"
cela fonctionne, mais si j'essaie de créer et d'enregistrer le fichier dans un autre répertoire, cela lance l'exception. Alors des idées sur ce que je fais mal?
Et une autre question: existe-t-il un moyen de rendre mes fichiers privés dans le stockage externe afin que l'utilisateur ne puisse pas les voir dans la galerie, uniquement s'il connecte son appareil en tant que Disk Drive
?
Environment.getExternalStorageDirectory()
place de/sdcard
.finally
et ne pas attraper génériqueException
Intent.ACTION_MEDIA_MOUNTED
et ne fonctionnera pas sur KitKat. L'intention correcte de diffuser estnew Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file) )
Le code présenté par RajaReddy ne fonctionne 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); } }); }
la source
Mise à jour 2018, SDK> = 23.
Vous devez maintenant également vérifier si l'utilisateur a accordé l'autorisation au stockage externe en utilisant:
public boolean isStoragePermissionGranted() { String 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 String[]{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
AndroidManifest.xml
:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
la source
Vous avez besoin d'une autorisation pour cela
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
et méthode:
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 }
la source
Assurez-vous que votre application dispose des autorisations appropriées pour être autorisée à écrire sur le stockage externe: http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE
Cela devrait ressembler à quelque chose comme ceci dans votre fichier manifeste:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
la source
Essaye ça :
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"); } }
la source
J'ai créé une 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) { } } } }
la source
Une exception est probablement lancée car il n'y a pas de sous-
MediaCard
répertoire. Vous devez 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 répertoire, vous dites à Android que vous ne voulez pas qu'il analyse les fichiers multimédias et qu'ils n'apparaîtront pas dans la galerie.la source
depuis l'enregistrement du fichier Android 4.4 a été modifié. il y a
ContextCompat.getExternalFilesDirs(context, name);
il renvoie 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 renvoie un seul tableau d'éléments
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(); 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; }
la source
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; 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(); } }
Il s'agit d'un scanner multimé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); }
la source
Pour l'API de niveau 23 (Marshmallow) et versions ultérieures, en plus de l'autorisation d'utilisation dans le manifeste, l'autorisation contextuelle doit également être implémentée et l'utilisateur doit l'accorder lors de l'utilisation de l'application au moment de l'exécution.
Ci-dessous, il y a un exemple pour enregistrer en
hello world!
tant que contenu demyFile.txt
fichier dans leTest
répertoire à l'intérieur du répertoire d'image.Dans le manifeste:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Où vous souhaitez créer le fichier:
int permission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE); String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; if (permission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this,PERMISSIONS_STORAGE, 1); } File myDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Test"); myDir.mkdirs(); try { String FILENAME = "myFile.txt"; File file = new File (myDir, FILENAME); String string = "hello world!"; FileOutputStream fos = new FileOutputStream(file); fos.write(string.getBytes()); fos.close(); } catch (IOException e) { e.printStackTrace(); }
la source
Cliquez ici pour une description complète et le code source
public void saveImage(Context mContext, Bitmap bitmapImage) { File sampleDir = new File(Environment.getExternalStorageDirectory() + "/" + "ApplicationName"); TextView tvImageLocation = (TextView) findViewById(R.id.tvImageLocation); tvImageLocation.setText("Image Store At : " + sampleDir); if (!sampleDir.exists()) { createpathForImage(mContext, bitmapImage, sampleDir); } else { createpathForImage(mContext, bitmapImage, sampleDir); } }
la source