Zapisywanie pliku w pamięci zewnętrznej w systemie Android

Chcę utworzyć plik w pamięci zewnętrznej sdCard i zapisać do niego.Szukałem przez internet i spróbować, ale nie uzyskanie wyniku, dodałem uprawnienia w pliku Manifest Androida,jak również, robię to na emulatorze, próbuję następujący kod i coraz ERRR", "nie można utworzyć plik".

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
Author: Suragch, 2011-11-30

7 answers

Możesz to zrobić również za pomocą tego kodu.

 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");
}
}
 86
Author: mH16,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-10 02:30:56

Aby zapisać do pamięci zewnętrznej w urządzeniach Lollipop+ potrzebujemy:

  1. Dodaj następujące uprawnienia do manifestu:

           <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  2. Prośba o zgodę od użytkownika:

           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!
                 }
               }
    
  3. Obsługa odpowiedzi użytkownika wewnątrz aktywności:

    @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();
            }
         }
     }
    
 13
Author: goRGon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-10 23:34:12

Powinieneś przeczytać dokumentację dotyczącą przechowywania rzeczy zewnętrznie na Androidzie. Istnieje wiele problemów, które mogą istnieć z obecnym kodem i myślę, że przeglądanie dokumentacji może pomóc ci je rozwikłać.

 2
Author: Kurtis Nusbaum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-30 17:52:28

Wiem, że to trochę za późno, ale zrobiłem to w ten sposób, tworzy katalog dokumentów, a następnie podkatalog dla aplikacji i zapisuje pliki do niego.

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

Ten tworzy nazwę pliku

   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;
    }
/ Align = "left" /
 2
Author: buckau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-21 22:03:51
 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; 
} 
 0
Author: sandhu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-22 12:34:45

ODPOWIEDŹ Uzupełniająca

Po zapisaniu do pamięci zewnętrznej, niektóre menedżery plików nie widzą Pliku od razu. Może to być mylące, jeśli użytkownik uważa, że skopiował coś na kartę SD, ale nie może go tam znaleźć. Po skopiowaniu pliku uruchom poniższy kod, aby powiadomić menedżerów plików o jego obecności.

MediaScannerConnection.scanFile(
        context,
        new String[]{myFile.getAbsolutePath()},
        null,
        null);
Więcej informacji można znaleźć w dokumentacji i tej odpowiedzi.
 0
Author: Suragch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-09 12:09:33

Mimo, że powyższe odpowiedzi są poprawne, ale chcę dodać informację, aby rozróżnić rodzaje przechowywania:

  • Pamięć wewnętrzna: powinna ona oznaczać "pamięć prywatna", ponieważ należy do aplikacji i nie może być współdzielona. Miejsce jego zapisania zależy od miejsca zainstalowania aplikacji. Jeśli aplikacja została zainstalowana na karcie SD (mam na myśli zewnętrzną kartę pamięci, którą wkładasz więcej do telefonu komórkowego, aby uzyskać więcej miejsca na przechowywanie obrazów, filmów,...), Twój plik będzie należał do aplikacji oznacza, że Twój plik będzie w Karta SD. A jeśli aplikacja została zainstalowana na wewnętrznej karcie (mam na myśli wbudowaną kartę pamięci dostarczaną z telefonem komórkowym), plik będzie znajdował się na wewnętrznej karcie.
  • external storage : powinno być napisane "public storage", ponieważ może być współdzielone. Ten tryb dzieli się na 2 grupy: prywatną zewnętrzną pamięć masową i publiczną zewnętrzną pamięć masową. Zasadniczo są one prawie takie same, możesz skonsultować Więcej z tej strony: https://developer.android.com/training/data-storage/files
  • [[4]}prawdziwa karta SD (mam na myśli zewnętrzną kartę pamięci, którą wkładasz więcej do telefonu komórkowego, aby uzyskać więcej miejsca na zdjęcia, filmy,...): nie zostało to wyraźnie stwierdzone w dokumentach Androida, więc wiele osób może być mylonych z tym, jak zapisywać pliki na tej karcie.

Oto link do kodu źródłowego przypadków, o których wspomniałem powyżej: https://github.com/mttdat/FileUtils

 0
Author: Nguyen Tan Dat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 10:46:12