Android Zapisywanie pliku do pamięci zewnętrznej
Mam mały problem z utworzeniem katalogu i zapisaniem do niego pliku w mojej aplikacji na Androida. Używam do tego kawałka kodu:
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();
Ale rzuca wyjątek:
Java. io. FileNotFoundException:/mnt/sdcard/MyApp/MediaCard / MediaCard-0.png (No such file or directory)
On that line: fos = new FileOutputStream(file);
Jeśli ustawiłem nazwę pliku na: "MyApp/MediaTag-"+objectId+"
to działa, ale jeśli spróbuję utworzyć i zapisać plik do innego katalogu to rzuca wyjątek. Jakieś pomysły, co robię źle?
I jeszcze jedno pytanie: czy jest jakiś sposób, aby moje pliki były prywatne w pamięci zewnętrznej, aby użytkownik nie mógł ich zobaczyć w galerii, tylko jeśli podłączy swoje urządzenie jako Disk Drive
?
11 answers
Użyj tej funkcji, aby zapisać bitmapę na karcie SD
private void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
if (!myDir.exists()) {
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();
}
}
I dodać to w manifeście
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
EDIT: za pomocą tej linii będziesz mógł zobaczyć zapisane obrazy w widoku galerii.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
Zobacz też ten link http://rajareddypolam.wordpress.com/?p=3&preview=true
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-07-20 13:41:21
Kod przedstawiony przez RajaReddy nie działa już dla KitKat
Ten robi (2 zmiany):
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);
}
});
}
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-01-17 16:45:23
Potrzebujesz pozwolenia na to
< 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
}
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-11-22 13:19:07
Upewnij się, że aplikacja ma odpowiednie uprawnienia do zapisu do pamięci zewnętrznej: http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE
Powinno to wyglądać mniej więcej tak w Twoim pliku manifestu:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
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-10-25 09:16:24
Spróbuj Tego:
- Sprawdź zewnętrzne urządzenie pamięci masowej
- Zapisz Plik
- Czytaj Plik
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");
}
}
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
2013-07-30 14:38:44
Prawdopodobnie wyjątek jest wyrzucany, ponieważ nie ma MediaCard
subdir. Powinieneś sprawdzić, czy istnieją wszystkie dirs na ścieżce.
O widoczności plików: jeśli umieścisz plik o nazwie .nomedia
w katalogu, mówisz Androidowi, że nie chcesz, aby zeskanował go w poszukiwaniu plików multimedialnych i nie pojawią się one w galerii.
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-10-25 09:19:38
Utworzyłem AsyncTask do zapisywania bitmap.
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)
{
}
}
}
}
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-04-22 11:17:55
Od Androida 4.4 zapisywanie plików zostało zmienione. jest
ContextCompat.getExternalFilesDirs(context, name);
Retunuje tablicę.
Gdy nazwa jest null
Pierwsza wartość to / storage / emulated / 0 / Android / com. my. package / files
Druga wartość jest jak /storage/extSdCard/Android/com.my.package / files
Android 4.3 i mniej to retuns pojedynczy element tablicy
Części trochę niechlujnego kodu, ale pokazuje jak to działa:
/** 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;
}
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-03-31 12:45:19
Aktualizacja 2018, SDK > = 23.
Teraz należy również sprawdzić, czy użytkownik udzielił uprawnień do zewnętrznego przechowywania za pomocą:
public boolean isStoragePermissionGranted() {
String TAG = "Storage Permission";
if (Build.VERSION.SDK_INT >= 23) {
if (this.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
return true;
} else {
Log.v(TAG, "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
public void saveImageBitmap(Bitmap image_bitmap, String image_name) {
String root = Environment.getExternalStorageDirectory().toString();
if (isStoragePermissionGranted()) { // check or ask permission
File myDir = new File(root, "/saved_images");
if (!myDir.exists()) {
myDir.mkdirs();
}
String fname = "Image-" + image_name + ".jpg";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}
try {
file.createNewFile(); // if file already exists will do nothing
FileOutputStream out = new FileOutputStream(file);
image_bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
MediaScannerConnection.scanFile(this, new String[]{file.toString()}, new String[]{file.getName()}, null);
}
}
I oczywiście dodać w AndroidManifest.xml
:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
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-08-10 15:40:48
Ten kod działa świetnie i działał również na Kitkacie. Docenić @ RajaReddy PolamReddy
Dodano jeszcze kilka kroków tutaj, a także widoczne w Galerii.
public void SaveOnClick(View v){
File mainfile;
String fpath;
try {
//i.e 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();
}
}
To jest skaner mediów do widocznego w Galerii.
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);
}
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-01 11:07:09
Kliknij tutaj aby uzyskać pełny opis i Kod źródłowy
public void saveImage(Context mContext, Bitmap bitmapImage) {
File sampleDir = new File(Environment.getExternalStorageDirectory() + "/" + "ApplicationName");
TextView tvImageLocation = (TextView) findViewById(R.id.tvImageLocation);
tvImageLocation.setText("Image Store At : " + sampleDir);
if (!sampleDir.exists()) {
createpathForImage(mContext, bitmapImage, sampleDir);
} else {
createpathForImage(mContext, bitmapImage, sampleDir);
}
}
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-09-15 08:16:27