在Android中的外部存储中写入文件
我想在外部存储SD卡创build一个文件,并写入它。我已经通过互联网search,尝试但没有得到的结果,我已经在Android Manifest文件中添加权限,我在模拟器上做这个,我正在尝试下面的代码并得到一个ERRR“,”无法创build文件“。
btnWriteSDFile = (Button) findViewById(R.id.btnWriteSDFile); btnWriteSDFile.setOnClickListener(new OnClickListener() { //private Throwable e; @Override public void onClick(View v) { // write on SD card file data from the text box try { File myFile = new File("/sdcard/mysdfile.txt"); myFile.createNewFile(); FileOutputStream fOut = new FileOutputStream(myFile); OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut); myOutWriter.append(txtData.getText()); myOutWriter.close(); fOut.close(); } catch (Exception e) { Log.e("ERRR", "Could not create file",e); } }// onClick }); // btnWriteSDFile
你也可以用这个代码来做到这一点。
public class WriteSDCard extends Activity { private static final String TAG = "MEDIA"; private TextView tv; /** Called when the activity is first created. */ @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"); } }
要在Lollipop +设备中写入外部存储,我们需要:
-
将以下权限添加到清单:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
请求用户的批准:
public static final int REQUEST_WRITE_STORAGE = 112; private requestPermission(Activity context) { boolean hasPermission = (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED); if (!hasPermission) { ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE); } else { // You are allowed to write external storage: String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/new_folder"; File storageDir = new File(path); if (!storageDir.exists() && !storageDir.mkdirs()) { // This should never happen - log handled exception! } }
-
在Activity中处理用户响应:
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case Preferences.REQUEST_WRITE_STORAGE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "The app was allowed to write to your storage!", Toast.LENGTH_LONG).show(); // Reload the activity with permission granted or use the features what required the permission } else { Toast.makeText(this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show(); } } }
您应该阅读有关在Android上从外部存储内容的文档 。 当前代码可能存在许多问题,我认为通过文档可能会帮助您解决这些问题。
我知道这有点晚了,但是我没有这样做,它创build了一个Documents目录,然后为应用程序创build了一个子目录,并将这些文件保存到它。
public class loadDataTooDisk extends AsyncTask<String, Integer, String> { String sdCardFileTxt; @Override protected String doInBackground(String... params) { //check to see if external storage is avalibel checkState(); if(canW == canR == true) { //get the path to sdcard File pathToExternalStorage = Environment.getExternalStorageDirectory(); //to this path add a new directory path and create new App dir (InstroList) in /documents Dir File appDirectory = new File(pathToExternalStorage.getAbsolutePath() + "/documents/InstroList"); // have the object build the directory structure, if needed. appDirectory.mkdirs(); //test to see if it is a Text file if ( myNewFileName.endsWith(".txt") ) { //Create a File for the output file data File saveFilePath = new File (appDirectory, myNewFileName); //Adds the textbox data to the file try{ String newline = "\r\n"; FileOutputStream fos = new FileOutputStream (saveFilePath); OutputStreamWriter OutDataWriter = new OutputStreamWriter(fos); OutDataWriter.write(equipNo.getText() + newline); // OutDataWriter.append(equipNo.getText() + newline); OutDataWriter.append(equip_Type.getText() + newline); OutDataWriter.append(equip_Make.getText()+ newline); OutDataWriter.append(equipModel_No.getText()+ newline); OutDataWriter.append(equip_Password.getText()+ newline); OutDataWriter.append(equipWeb_Site.getText()+ newline); //OutDataWriter.append(equipNotes.getText()); OutDataWriter.close(); fos.flush(); fos.close(); }catch(Exception e){ e.printStackTrace(); } } } return null; } }
这个创build文件名
private String BuildNewFileName() { // creates a new filr name Time today = new Time(Time.getCurrentTimezone()); today.setToNow(); StringBuilder sb = new StringBuilder(); sb.append(today.year + ""); // Year) sb.append("_"); sb.append(today.monthDay + ""); // Day of the month (1-31) sb.append("_"); sb.append(today.month + ""); // Month (0-11)) sb.append("_"); sb.append(today.format("%k:%M:%S")); // Current time sb.append(".txt"); //Completed file name myNewFileName = sb.toString(); //Replace (:) with (_) myNewFileName = myNewFileName.replaceAll(":", "_"); return myNewFileName; }
跳这有助于一些人花了很长时间来解决它,并使其工作。
ContextWrapper contextWrapper = new ContextWrapper(getApplicationContext()); //getappcontext for just this activity context get File file = contextWrapper.getDir(file_path, Context.MODE_PRIVATE); if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) { saveToExternalStorage.setEnabled(false); } else { External_File = new File(getExternalFilesDir(file_path), file_name);//if ready then create a file for external } } try { FileInputStream fis = new FileInputStream(External_File); DataInputStream in = new DataInputStream(fis); BufferedReader br =new BufferedReader(new InputStreamReader(in)); String strLine; while ((strLine = br.readLine()) != null) { myData = myData + strLine; } in.close(); } catch (IOException e) { e.printStackTrace(); } InputText.setText("Save data of External file:::: "+myData); private static boolean isExternalStorageReadOnly() { String extStorageState = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) { return true; } return false; } private static boolean isExternalStorageAvailable() { String extStorageState = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(extStorageState)) { return true; } return false; }
补充答案
写入外部存储后,一些文件pipe理器不会立即看到该文件。 如果用户认为他们将某些东西复制到了SD卡上,但是在那里找不到,这可能会引起混淆。 因此,在复制文件之后,运行以下代码以通知文件pipe理器它的存在。
MediaScannerConnection.scanFile( context, new String[]{myFile.getAbsolutePath()}, null, null);
有关更多信息 ,请参阅文档和此答案 。