Запись файла на внешнем накопителе в Android
Я хочу создать файл во внешнем хранилище sdCard и написать ему. Я искал в Интернете и пытаюсь, но не получаю результат, я добавил разрешение в файле манифеста Android также, я делаю это на эмуляторе, я я пытаюсь выполнить следующий код и получить 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
Ответы
Ответ 1
Вы также можете сделать это с помощью этого кода.
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");
}
}
Ответ 2
Для записи во внешнее хранилище в устройствах 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();
}
}
}
Ответ 3
Вы должны прочитать документацию по хранению материалов на внешнем устройстве на Android. Там существует множество проблем, которые могут существовать с вашим текущим кодом, и я думаю, что рассмотрение документации может помочь вам их убрать.
Ответ 4
Приведенный ниже код создает каталог документов, а затем подкаталог приложения и сохраняет в нем файлы.
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;
}
Надеюсь это поможет! Мне потребовалось много времени, чтобы заставить его работать.
Ответ 5
Хотя приведенные выше ответы верны, я хочу добавить уведомление, чтобы различать типы хранилищ:
- Внутреннее хранилище: должно быть "личное хранилище", потому что оно принадлежит приложению и не может быть общим. Где это сохранено, зависит от того, где установлено приложение. Если приложение было установлено на SD-карту (я имею в виду внешнюю карту памяти, которую вы поместили в мобильный телефон, чтобы иметь больше места для хранения изображений, видео и т.д.), Ваш файл будет принадлежать приложению, значит, ваш файл будет SD-карта. И если приложение было установлено на Внутреннюю карту (я имею в виду встроенную карту памяти, поставляемую с вашим мобильным телефоном), ваш файл будет на Внутренней карте.
- Внешнее хранилище: должно быть "публичное хранилище", потому что оно может быть общим. И этот режим делится на 2 группы: частное внешнее хранилище и публичное внешнее хранилище. По сути, они почти одинаковы, вы можете узнать больше на этом сайте: https://developer.android.com/training/data-storage/files
- Настоящая SD-карта (я имею в виду внешнюю карту памяти, которую вы помещаете в мобильный телефон, чтобы иметь больше места для хранения изображений, видео и т.д.): Об этом не было ясно сказано в документации для Android, поэтому многие люди могут быть озадачены тем, как сохранить файлы на этой карте.
Вот ссылка на исходный код для случаев, о которых я упоминал выше: https://github.com/mttdat/FileUtils
Ответ 6
Вы можете найти эти методы полезными при чтении и записи данных в Android.
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();
}
}
}
}
Ответ 7
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;
}
Ответ 8
Дополнительный ответ
После записи во внешнее хранилище некоторые файловые менеджеры сразу не видят файл. Это может сбивать с толку, если пользователь думает, что он что-то скопировал на SD-карту, но тогда не может найти его там. Поэтому после того, как вы скопируете файл, запустите следующий код, чтобы уведомить файловые менеджеры о его присутствии.
MediaScannerConnection.scanFile(
context,
new String[]{myFile.getAbsolutePath()},
null,
null);
Подробнее см. документация и этот ответ.