I want to save a file to app-specific storage, like shown in documentation:
String filename = "myfile.txt";
String fileContents = "Hello world!";
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
fos.write(fileContents.toByteArray());
}
Unfortunately, every time I restart the application all data are lost.
How to prevent data from being deleted?
Please note I am not interested in using SharedPreferences/External Storage/Database. Android Studio 3.5.3.
You need to close the file once you are done using it. Otherwise it is not stored to the disk, but only to the memory.
That's why when you "shut down" the app, and start over, it's not there anymore.
FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
try {
fos.write(fileContents.toByteArray());
} catch (IOException e) {
e.printStackTrace();
} finally{
try{
if (fos!=null){
fos.flush();
fos.close();
}
} catch( Exception e) {
e.printStackTrace();
}
}
Related
Here's my code:
String content = mEditText.getText().toString();
FileOutputStream fos;
try {
fos = openFileOutput(title, MODE_PRIVATE);
fos.write(content.getBytes());
Toast.makeText(EditActivity.this, "Saved to "+getFilesDir() + "/" + title, Toast.LENGTH_LONG).show();
fos.close();
saved = true;
} catch (IOException e) {
Toast.makeText(EditActivity.this, "Error happened", Toast.LENGTH_SHORT).show();
}
If I run the code like this, it tells saved to /data/data/mypackagename/files/FileTitle. I want it to save the file in another directory for example save to /data/data/mypackagename/files/userData/FileTitle.I don't know any way to do this
What you need is the File constuctor that takes a parent File and a relative path to file. You've correctly established that openFileOutput() creates the file in getFilesDir(), so the code would look something like this:
FileOutputStream fos = null;
try {
final File dir = new File(getFilesDir(), "some/long/path");
dir.mkdirs();
final File file = new File(dir, "file.txt");
fos = new FileOutputStream(file);
// Use fos...
} catch (IOException e) {
// Handle error...
} finally {
if (fos != null) {
try {
fos.close()
} catch (IOException ignore) {
// Close quietly.
}
}
}
File is just a pointer, it may point to a directory, it may even point to something that's not there yet, like a new file. FileOutputStream will create a file if it doesn't exist.
If you choose to place your new file in another directory, make sure it exists first by calling mkdirs() on the directory.
I have a very specific issue - I am trying to write to external storage on an Asus Nexus 7, but it is writing to the emulated directory on the device.
Here is the code I am using:
public static void writeExternalMedia(Context context) {
if(isExternalStorageWritable()) {
String content = "hello world";
File filedir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/test");
filedir.mkdir();
File file;
FileOutputStream outputStream;
try {
file = new File(filedir, "test.txt");
if (!file.exists()) {
file.createNewFile();
}
outputStream = new FileOutputStream(file);
outputStream.write(content.getBytes());
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Whenever I restart the device, the directories appear under the device when plugged in, which is what I would expect to happen when the function above gets executed.
I have tried searching for a solution and cannot find the answer to my question.
I made two methods. One for creating a file and one for appending to it. I think the issue is that you're not calling createNewFile.
private File CreateFile(String fileName)
{
File file = new File(this.getFilesDir(), fileName);
try
{
if(!file.exists())
{
file.createNewFile();
}
}
catch (IOException e)
{
e.printStackTrace();
}
return file;
}
private void appendToFile(String file, String content)
{
try
{
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(this.openFileOutput(file, this.MODE_APPEND));
outputStreamWriter.append(content + "\n");
outputStreamWriter.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
Alright after much searching and testing I finally came across a solution, linked via one of the other answers.
https://stackoverflow.com/a/28448843/979220
The solution was to scan the media files, which causes the files to propagate to the external storage, rather than staying in the emulated storage.
I can pass sdcard location to my adb command using
file:///sdcard/Android/screen.bmp
What is the equivalent string, if my file is saved in phone memory instead of sdcard, will it be
file:///phone/Android/screen.bmp
That isn't necessarily how you access things saved internally on your phone.
Keep in mind how you save an image to internal storage:
Bitmap bitmap = ______; //get your bitmap however
try {
FileOutputStream fos = context.openFileOutput("desiredFilename.png", Context.MODE_PRIVATE);
image.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
Log.e("saveToInternalStorage()", e.getMessage());
Log.e("Saving the bitmap",e.getMessage());
}
Now, to go read it, we just get the context, and call getFileStreamPath(filename) on it.
Bitmap retrievedImage;
String filename = "desiredFilename.png";
try {
File filePath = context.getFileStreamPath(filename);
FileInputStream fi = new FileInputStream(filePath);
retrievedImage = BitmapFactory.decodeStream(fi);
} catch (Exception e) {
Log.e("Retrieving the image", e.getMessage());
}
You can read more about this here.
I'm looking for how to store image data into my app on Android Wear.
What I want to do are followings:
Take a photo and send it to my watch. (via DataMap)
My watch displays the photo.
When my app on Android Wear restarts, the app displays the photo taken before.
For now, the photo is cleared after restart the app. I want to store the photo.
Are there any ways to save the photo into the watch.
Thanks.
[UPDATE1]
I tried to save an image by using Environment.getExternalStorageDirectory()
But "NOT EXISTS" is returned.
String imagePath = Environment.getExternalStorageDirectory()+"/test.jpg";
try {
FileOutputStream out = openFileOutput(imagePath, Context.MODE_WORLD_READABLE);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(bitmapPath);
boolean isExists = file.exists();
if (isExists) {
LOGD(TAG, "EXISTS");
} else {
LOGD(TAG, "NOT EXISTS");
}
[UPDATE2]
I found an error below..
java.lang.IllegalArgumentException: File /storage/emulated/0/test.jpg contains a path separator
[UPDATE3]
try {
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(path));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
java.io.FileNotFoundException: /image: open failed: EROFS (Read-only file system)
[UPDATE4]
I put it. But not change.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
[UPDATE5 SOLVED]
I found that the path "imagePath" was correct. (Sorry. I didn't notice it)
String imagePath = Environment.getExternalStorageDirectory() + "/test.jpg";
try {
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(imagePath));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
I believe you are having problems because openFileInput() is for internal storage, not external storage. In fact there is no reason for using Environment.getExternalStorage(). I don't believe the watches have external storage anyway.
Try something like openFileOutput("test.jpg", Context.MODE_WORLD_READABLE); (fyi MODE_WORLD_READABLE is deprecated).
Then use openFileInput("test.jpg") to get it back.
The reason you are getting an error is openFileOutput() cannot have subdirectories.
Can someone explain what is going wrong here I am using following function
public void WriteSettings(Context context, String data){
FileOutputStream fOut = null;
OutputStreamWriter osw = null;
try{
fOut = context.openFileOutput("schemas.json",Context.MODE_APPEND);
osw = new OutputStreamWriter(fOut);
osw.write(data);
osw.flush();
Toast.makeText(context, data+"Data",Toast.LENGTH_SHORT).show();
Toast.makeText(context, "Settings saved",Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(context, "Settings not saved",Toast.LENGTH_SHORT).show();
}
finally {
try {
osw.close();
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And calling with once my http request is completed
JSONObject json_res = currentDFD.getJSONObject("result");
WriteSettings(getBaseContext(),json_res.toString());
The result is alerted in toast however not written to the file
the file is located in assets folder
thanks in advance
AFAIK You can't. The assets folder is read-only at runtime.
Pick a different location to save your data, see Data Storage in Android for more information.
The assets folder is like folders res, src, gen, etc. These are all useful to provide different files as input to build system to generate APK file for your app.
All these are read-only while your app is running. At run-time you can only write to SD card.