Android: how to write a file to internal storage - java

I am developing a simple android application and I need to write a text file in internal storage device. I know there are a lot of questions (and answers) about this matter but I really cannot understand what I am doing in the wrong way.
This is the piece of code I use in my activity in order to write the file:
public void writeAFile(){
String fileName = "myFile.txt";
String textToWrite = "This is some text!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(fileName , Context.MODE_PRIVATE);
outputStream.write(textToWrite.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I really cannot understand which mistake I am doing. In addition, I have tried this project on my emulator in Android Studio and my phone in order to understand where I am doing something wrong but even with that project no file is written neither on the phone or on the emulator.
EDIT:
I know that no file is written to my internal storage because I try to read the content of the file, after I have written to it, with this code:
public void ReadBtn(View v) {
//reading text from file
try {
FileInputStream fileIn=openFileInput("myFile.txt");
InputStreamReader InputRead= new InputStreamReader(fileIn);
char[] inputBuffer= new char[READ_BLOCK_SIZE];
String s="";
int charRead;
while ((charRead=InputRead.read(inputBuffer))>0) {
String readstring=String.copyValueOf(inputBuffer,0,charRead);
s +=readstring;
}
InputRead.close();
textmsg.setText(s);
} catch (Exception e) {
e.printStackTrace();
}
}
Nothing is shown at all.

Use the below code to write a file to internal storage:
public void writeFileOnInternalStorage(Context mcoContext, String sFileName, String sBody){
File dir = new File(mcoContext.getFilesDir(), "mydir");
if(!dir.exists()){
dir.mkdir();
}
try {
File gpxfile = new File(dir, sFileName);
FileWriter writer = new FileWriter(gpxfile);
writer.append(sBody);
writer.flush();
writer.close();
} catch (Exception e){
e.printStackTrace();
}
}
Starting in API 19, you must ask for permission to write to storage.
You can add read and write permissions by adding the following code to AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
You can prompt the user for read/write permissions using:
requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE}, 1);
and then you can handle the result of the permission request in onRequestPermissionsResult() inside activity called from it.

no file is written neither on the phone or on the emulator.
Yes, there is. It is written to what the Android SDK refers to as internal storage. This is not what you as a user consider to be "internal storage", and you as a user cannot see what is in internal storage on a device (unless it is rooted).
If you want to write a file to where users can see it, use external storage.
This sort of basic Android development topic is covered in any decent book on Android app development.

Save to Internal storage
data="my Info to save";
try {
FileOutputStream fOut = openFileOutput(file,MODE_WORLD_READABLE);
fOut.write(data.getBytes());
fOut.close();
Toast.makeText(getBaseContext(), "file saved", Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Read from Internal storage
try {
FileInputStream fin = openFileInput(file);
int c;
String temp="";
while( (c = fin.read()) != -1){
temp = temp + Character.toString((char)c);
}
tv.setText(temp);
Toast.makeText(getBaseContext(), "file read", Toast.LENGTH_SHORT).show();
}
catch(Exception e){
}

Android 11 Update
Through Android 11 new policies on storage, You cannot create anything in the root folder of primary external storage using Environment.getExternalStorageDirectory() Which is storage/emulated/0 or internal storage in file manager. The reason is that this possibility led to external storage being just a big basket of random content. You can create your files in your own applications reserved folder storage/emulated/0/Android/data/[PACKAGE_NAME]/files folder using getFilesDir() but is not accessible by other applications such as file manager for the user! Note that this is accessible for your application!
Final solution (Not recommended)
By the way, there is a solution, Which is to turn your application to a file manager (Not recommended). To do this you should add this permission to your application and the request that permission to be permitted by the user:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
Thoriya Prahalad has described how to this job in this stackoverflow post.

To view files on a device, you can log the file location >provided by methods such as File.getAbsolutePath(), and >then browse the device files with Android Studio's Device >File Explorer.
I had a similar problem, the file was written but I never saw it. I used the Device file explorer and it was there waiting for me.
String filename = "filename.jpg";
File dir = context.getFilesDir();
File file = new File(dir, filename);
try {
Log.d(TAG, "The file path = "+file.getAbsolutePath());
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
return true;

Have you requested permission to write to external storage?
https://developer.android.com/training/basics/data-storage/files.html#GetWritePermission
Perhaps your try\catch block is swallowing an exception that could be telling you what the problem is.
Also, you do not appear to be setting the path to save to.
e.g: Android how to use Environment.getExternalStorageDirectory()

To write a file to the internal storage you can use this code :
val filename = "myfile"
val fileContents = "Hello world!"
context.openFileOutput(filename, Context.MODE_PRIVATE).use {
it.write(fileContents.toByteArray())
}

This Answer worked for me for android 11+ !! check it out, hopefully it'll work for you too
https://stackoverflow.com/a/66366102/16657358[1]
[(btw, int SDK_INT = 30; it confused me lol so thought i should mention)]

Related

Why Isn't My FileOutputstream Writing to a File?

I'm a beginner working on an Android app that uses the gcacace SignaturePad library to capture the signature of my user. My goal is to take the signature, compress it down into a JPEG, and then write that information to a file on the users phone so the picture can be accessed later.
I am currently getting no errors or crashes when I run the code, yet no directory or file is being created when I test the app out on my device(Google Pixel 2). Can anyone give me a hand figuring out where the problem is? I've thrown my head against a wall this entire morning and still don't know.
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir("images", Context.MODE_PRIVATE);
if (!directory.exists()) {
directory.mkdirs();
}
File myPath = new File(directory, "1.jpg");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(myPath);
} catch (Exception e) {
e.printStackTrace();
}
signaturePad.getSignatureBitmap().compress(Bitmap.CompressFormat.JPEG, 90, fOut);
Bitmap signature = signaturePad.getSignatureBitmap();
int bytes = signature.getByteCount();
try {
fOut.write(bytes);
fOut.flush();
fOut.close();
} catch (IOException ex) {
ex.printStackTrace();
}
Toast.makeText(activity_signature_pad.this, "Signature Saved", Toast.LENGTH_SHORT).show();
The code in your question writes to what the Android SDK refers to internal storage. That is private to your app; ordinary users do not have access to it (including you, except when using developer tools).
You appear to want to write to external storage. For that, use:
File directory = new File(getExternalFilesDir(null), "images")

Android 4.4.4 Save to SD on Samsung S4

I'm attempting to save files to my SD but i cannot get it to, I even tried moving the app to the SD to see if I can. I don't really care where it ends up on there but this isn;t working:
String state = Environment.getExternalStorageState();
File filesDir;
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
filesDir = getExternalFilesDir(null);
Log.i(Utils.TAG, "We can read and write the media: " + filesDir.getAbsolutePath()); // This is the local on the phone
} else {
// Load another directory, probably local memory
filesDir = getFilesDir();
Log.i(Utils.TAG, "Load another directory, probably local memory: " + filesDir.getAbsolutePath());
}
try {
// Creates a trace file in the primary external storage space of the
// current application.
// If the file does not exists, it is created.
//File traceFile = new File(((Context)this).getExternalFilesDir(null), "TraceFile.txt"); //This one saves to the internal file folder
File traceFile = new File(filesDir, "TraceFile.txt");
Log.i(Utils.TAG, traceFile.getAbsolutePath());
if (!traceFile.exists())
traceFile.createNewFile();
// Adds a line to the trace file
BufferedWriter writer = new BufferedWriter(new FileWriter(traceFile, true /*append*/));
writer.write("This is a test trace file.");
writer.close();
// Refresh the data so it can seen when the device is plugged in a
// computer. You may have to unplug and replug the device to see the
// latest changes. This is not necessary if the user should not modify
// the files.
MediaScannerConnection.scanFile((Context)(this),
new String[] { traceFile.toString() },
null,
null);
} catch (IOException e) {
Log.i(Utils.TAG, "Unable to write to the TraceFile.txt file.");
}
However, this gave me the SD file but I couldn't write to it:
public HashSet<String> getExternalMounts() {
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
return out;
}
Android 4.4+ allows you to write to removable media, but only in select spots obtained by methods like:
getExternalFilesDirs()
getExternalCacheDirs()
getExternalMediaDirs() (this one was added in Android 5.0 IIRC)
Note the plural on those method names. If they return 2+ entries, the second and subsequent ones should be on removable media, in a directory that is unique for your app. You can read and write to those directories without any <uses-permission> element.
You might also consider the Storage Access Framework (ACTION_OPEN_DOCUMENT and kin), to allow the user to choose where to place the file, whether that be on external storage or removable storage or Google Drive or whatever.
Android 4.4 implemented numerous SD card limits, and there were (and still are) a lot of apps which broke during this period, because of issues with write limitations to the SD card. Your code itself seems fine to me, but my believe is that it's Android 4.4's SD Card limits which ensure that it doesn't work. How to fix that (without root access) is beyond me.

How to read Read / Get Dropbox files

I want to know if it is possible to access (at least read-access) to a private Dropbox folder without oauth.
The case is, I have a Heroku app that needs to access files and folders in a given private Dropbox folder.
Looking at the docs, the only way is through oAuth (https://www.dropbox.com/developers/core/start/android). However, my Heroku app needs to access the files and folders of a given Dropbox folder, is the App key and App secret enough to do this?
What is the right approach?
#Test
public void test() throws IOException, DbxException {
FileOutputStream outputStream = new FileOutputStream("test.txt");
DbxRequestConfig config = new DbxRequestConfig("mydbapp/1.0", Locale.getDefault().toString());
DbxClient client = new DbxClient(config, Constants.accessToken);
System.out.println("Linked account: " + client.getAccountInfo().displayName);
DbxEntry.File md = null;
try {
List<DbxEntry.File> revs = client.getRevisions("/test.txt");
md = client.getFile("/test.txt", null, outputStream);
} catch (DbxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
outputStream.close();
}
assertNotNull(md);
}
I've been trying to debug this code, but it keeps throwing "not found" error, even if the file is in the account dropbox folder. What could be missing in this code?
Without client-side authentication (or at least I mean user intervention) it was possible to access dropbox files/data using the "Generated Token"
The problem with this code, is not actually the code, but with the way the Dropbox app was created. The files were stored in the root dropbox path, however the code is looking for the file in the /Apps/{appName}/ folder path.

Copy file from Android to Windows

I wrote a small app, which creats a XML file on my Android device. No I try to copy it from my phone to my Windows PC. In Windows Explorer I can't see this file specific file, on my phone I can see this file with various file explorers. When I reboot my phone, the file appears in Windows Explorer, but I can't copy it to my desktop.
Here is my code which creates my file:
String filename = "myfile.xml";
String dir = Environment.getExternalStorageDirectory().getPath()+"/"+c.getResources().getString(R.string.app_name);
createDir(dir);
File file = new File(dir,filename);
FileWriter out=null;
try {
String xml = createXml();
try {
out = new FileWriter(file);
out.write(xml);
out.close();
} catch (Exception e) {
out.close();
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
My guess is, this code doesn't free the file handle so Androids MTP cannot access this file. This would also explain, why the file is shown and could be deleted (but not able to be transfered to my PC) after rebooting my phone.
Any suggestions what goes wrong?
I think you should refresh the media scanner for that file
sendBroadcast(
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(imageAdded))
);

How to write file to sd-card? (Android) No errors, but nothing written

I'm new to developing android apps. And already overchallenged with my first project. My app should be able to save a list of EditText fields to a text file by clicking a "save"-Button.
But I got no success to write a file to my SD-card.
My code:
(function in MainActivity.java called by the button)
public void saveData(View view){
try{
File sdcard = Environment.getExternalStorageDirectory();
// to this path add a new directory path
File dir = new File(sdcard.getAbsolutePath() + "/myapp/");
// create this directory if not already created
dir.mkdir();
// create the file in which we will write the contents
File file = new File(dir, "datei.txt");
FileOutputStream os = new FileOutputStream(file);
String data = "some string";
os.write(data.getBytes());
os.flush();
os.close();
}
catch (IOException e){
Log.e("com.sarbot.FitLogAlpha", "Cant find Data.");
}
}
With Google I found another way:
public void saveData3(View view){
FileWriter fWriter;
File sdCardFile = new File(Environment.getExternalStorageDirectory() + "/datafile.txt");
Log.d("TAG", sdCardFile.getPath()); //<-- check the log to make sure the path is correct.
try{
fWriter = new FileWriter(sdCardFile, true);
fWriter.write("CONTENT CONTENT UND SO");
fWriter.flush();
fWriter.close();
}catch(Exception e){
e.printStackTrace();
}
}
In my manifest.xml I set the permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And the function from developer guide returns me True -> SD-card is writable.
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
In the res/layout/activity_main.xml are some TextViews and EditText and a save button with android:onClick="saveData" argument. The function is called. The SD-card is writable. And no IO errors. But after pressing the button (without error) there is still no new file on my SD-card. I already tried to create the file manually and just append but nothing changed. I tried some other function with BufferedWriter too .. but no success.
I'm running my Sony Xperia E with USB-Debug mode. Unmount and mounted the SD-card on my PC but cant find the file. Maybe it is only visible for the phone? It doesn't exist? I don't know what to do because I get no errors. I need the content of this file on my computer for calculations.
:EDIT:
The problem was not in the code.. just in the place I looked up. The externalStorage -> sdCard seems to be the internal and the removable sdcard is the -> ext_card.
After this line,
File file = new File(dir, "datei.txt");
Add this code
if ( !file.exists() )
{
file.createNewFile(); // This line will create new blank line.
}
os.flush() is missing in your code. Add this snippet before os.close()

Categories

Resources