Programing

Android의 외부 저장소에 파일 쓰기

crosscheck 2020. 12. 1. 07:41
반응형

Android의 외부 저장소에 파일 쓰기


외부 저장소 sdCard에 파일을 만들어서 쓰고 싶습니다. 인터넷을 통해 검색했지만 결과를 얻지 못했습니다 .Android Manifest 파일에도 권한을 추가했습니다. 에뮬레이터에서이 작업을 수행하고 있습니다. 다음 코드와 ERRR ","파일을 만들 수 없습니다. "

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 + 기기의 외부 저장소에 쓰려면 다음이 필요합니다.

  1. Manifest에 다음 권한을 추가하십시오.

           <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  2. 사용자에게 승인 요청 :

           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. 활동 내에서 사용자 응답을 처리합니다.

    @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에서 외부 저장에 대한 문서를 읽어야합니다 . 현재 코드에 존재할 수있는 많은 문제가 있으며 문서를 살펴보면 문제를 해결하는 데 도움이 될 것입니다.


아래 코드는 문서 디렉토리를 만든 다음 응용 프로그램의 하위 디렉토리를 만들고 여기에 파일을 저장합니다.

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

이것은 파일 이름을 빌드합니다.

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

도움이 되었기를 바랍니다! 작동하는 데 오랜 시간이 걸렸습니다.


이 방법은 안드로이드에서 데이터를 읽고 쓰는 데 유용합니다.

 public void saveData(View view) {
    String text = "This is the text in the file, this is the part of the issue of the name and also called the name od the college ";
    FileOutputStream fos = null;
    try {
        fos = openFileOutput("FILE_NAME", MODE_PRIVATE);
        fos.write(text.getBytes());
        Toast.makeText(this, "Data is saved "+ getFilesDir(), Toast.LENGTH_SHORT).show();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if (fos!= null){
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}

public void logData(View view) {
    FileInputStream fis = null;

    try {
        fis = openFileInput("FILE_NAME");
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);
        StringBuilder sb=  new StringBuilder();
        String text;
        while((text = br.readLine()) != null){
            sb.append(text).append("\n");
            Log.e("TAG", text
            );
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if(fis != null){
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

위의 답변이 맞더라도 저장 유형을 구분하기 위해 알림을 추가하고 싶습니다.

  • Internal storage: It should say 'private storage' because it belongs to the app and cannot be shared. Where it's saved is based on where the app installed. If the app was installed on a SD card (I mean the external storage card you put more into a cell phone for more space to store images, videos, ...), your file will belong to the app means your file will be in a SD card. And if the app was installed on an Internal card (I mean the onboard storage card coming with your cell phone), your file will be in an Internal card.
  • External storage: It should say 'public storage' because it can be shared. And this mode divides into 2 groups: private external storage and public external storage. Basically, they are nearly the same, you can consult more from this site: https://developer.android.com/training/data-storage/files
  • A real SD card (I mean the external storage card you put more into a cell phone for more space to store images, videos, ...): this was not stated clearly on Android docs, so many people might be confused with how to save files in this card.

Here is the link to a source code for cases I mentioned above: https://github.com/mttdat/FileUtils


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

Supplemental Answer

After writing to external storage, some file managers don't see the file right away. This can be confusing if a user thinks they copied something to the SD card, but then can't find it there. So after you copy the file, run the following code to notify file managers of its presence.

MediaScannerConnection.scanFile(
        context,
        new String[]{myFile.getAbsolutePath()},
        null,
        null);

See the documentation and this answer for more.

참고URL : https://stackoverflow.com/questions/8330276/write-a-file-in-external-storage-in-android

반응형