Android将文件保存到外部存储

我有一个小问题,创build一个目录,并在我的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(); 

但它抛出一个例外:

java.io.FileNotFoundException:/mnt/sdcard/MyApp/MediaCard/MediaCard-0.png(没有这样的文件或目录)

在这一行: fos = new FileOutputStream(file);

如果我将文件名设置为: "MyApp/MediaTag-"+objectId+"它正在工作,但是如果我尝试创build文件并将其保存到另一个目录,则抛出exception。

另一个问题:有没有办法让我的文件在外部存储保密,所以用户不能在库中看到他们,只要他连接他的设备作为Disk Drive

使用此function将您的位图保存在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(); } } 

并将其添加到清单中

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

编辑:通过使用这一行,你将能够看到图库视图中保存的图像。

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

看看这个链接也http://rajareddypolam.wordpress.com/?p=3&preview=true

RajaReddy提供的代码不再适用于KitKat

这个(2个变化):

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

您需要获得此许可

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

确保你的应用程序有适当的权限被允许写入到外部存储: http : //developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE

它应该在你的清单文件中看起来像这样:

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

尝试这个 :

  1. 检查外部存储设备
  2. 写入文件
  3. 读取文件
 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"); } } 

可能是因为没有MediaCard引发exception。 你应该检查path中的所有目录是否存在。

关于你的文件的可见性:如果你把名为.nomedia文件放在你的目录中,你告诉Android,你不想让它扫描它的媒体文件,它们不会出现在图库中。

我创build了一个AsyncTask来保存位图。

 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) { } } } } 

因为android 4.4文件保存已经改变。 有

 ContextCompat.getExternalFilesDirs(context, name); 

它回退一个数组。

当名称为空时

第一个值就像/storage/emulated/0/Android/com.my.package/files

第二个值就像/storage/extSdCard/Android/com.my.package/files

android 4.3和更less它回顾单个项目数组

小杂乱的部分代码,但它演示了它是如何工作的:

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

这段代码工作得很好,也在KitKat上工作过。 感谢@RajaReddy PolamReddy
在这里添加了更多的步骤,也可以在Gallery上看到。

 public void SaveOnClick(View v){ File mainfile; String 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); 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(); } } 

这是媒体扫描仪可以在图库中看到。

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