Writing a file to sdcard - java

I'm trying to write a file from an Http post reply to a file on the sdcard. Everything works fine until the byte array of data is retrieved.
I've tried setting WRITE_EXTERNAL_STORAGE permission in the manifest
and tried many different combinations of tutorials I found on the net.
All I could find was using the openFileOutput("",MODE_WORLD_READABLE) method, of the activity but how my app writes file is by using a thread. Specifically, a thread is invoked from another thread when a file has to be written,
so giving an activity object didn't work even though I tried it.
The app has come a long way and I cannot change how the app is currently written.
Please, someone help me?
CODE:
File file = new File(bgdmanip.savLocation);
FileOutputStream filecon = null;
filecon = new FileOutputStream(file);
byte[] myByte;
myByte = Base64Coder.decode(seReply);
bos.write(myByte);
filecon.write(myByte);
myvals = x * 11024;
bgdmanip.savLocation holds the whole files path. seReply is a string reply from HttpPost response. The second set of code is looped with reference to x. The file is created but remains 0 bytes.

//------------------------------WRITING DATA TO THE FILE ---------------------------------
btnWriteSDFile.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
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();
Toast.makeText(v.getContext(),"Done writing SD 'mysdfile.txt'", Toast.LENGTH_SHORT).show();
txtData.setText("");
}
catch (Exception e)
{
Toast.makeText(v.getContext(), e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
});
//---------------------------READING DATA FROM THE FILE PLACED IN SDCARD-------------------//
btnReadSDFile.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
try {
File myFile = new File("/sdcard/mysdfile.txt");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(new InputStreamReader(fIn));
String aDataRow = "";
String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null)
{
aBuffer += aDataRow ;
}
txtData.setText(aBuffer);
myReader.close();
Toast.makeText(v.getContext(),"Done reading SD 'mysdfile.txt'",Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(v.getContext(), e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
});
ALONG WITH THIS ALSO WRITE THIS PERMISSION IN Android.Manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

The openFileOutput() method writes data to your application's private data area (not the SD card), so that's probably not what you want. You should be able to call Environment.getExternalStorageDirectory() to get the root path to the SD card and use that to create a FileOutputStream. From there, just use the standard java.io routines.

Here is a sample:
// Log used as debug
File log = new File(Environment.getExternalStorageDirectory(), "Log.txt");
try {
out = new BufferedWriter(new FileWriter(log.getAbsolutePath(), false));
out.write(new Date().toString());
out.write(" : \n");
} catch (Exception e) {
Log.e(TAG, "Error opening Log.", e);
}

Related

Android csv file not visible when writing to SD card

I have been having an issue that others on the site have already. I have tried those solutions and they did not work for me.
I'm currently developing an app that would create a csv file based on user input. The file needs to be retrievable by the user when the device is connected to a PC via USB. The saving code functions work correctly, however the file is not visible on the PC when the device is connected.
This is the full saving code snippet of the app:
FileWriter fileWriter = null;
File sdCard = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File dir = new File(sdCard.getAbsolutePath() + "/appFolder/");
File dir2 = new File(sdCard.getAbsolutePath() + "/appFolder/appSubFolder/");
dir.mkdirs();
dir2.mkdirs();
fileName = clientName + " " + agentName + ".csv";
path = sdCard.getAbsolutePath() + "/appFolder/appSubFolder/";
file = new File(dir2, fileName);
dir.setReadable(true);
dir.setWritable(true);
dir.setExecutable(true);
dir2.setReadable(true);
dir2.setWritable(true);
dir2.setExecutable(true);
file.setReadable(true);
file.setWritable(true);
file.setExecutable(true);
this.clientName = clientName;
this.agentName = agentName;
BufferedWriter bufferedWriter = null;
try {
if(!dir.exists()){
dir.createNewFile();
Toast.makeText(context,"dir created", Toast.LENGTH_SHORT).show();
}
if(!dir2.exists()){
dir2.createNewFile();
Toast.makeText(context,"dir2 created", Toast.LENGTH_SHORT).show();
}
if (!file.exists() )
{
file.createNewFile();
Toast.makeText(context,"file created", Toast.LENGTH_SHORT).show();
}
/*
fileWriter = new FileWriter(file, true);
bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(fullOrder);
fileWriter.flush();
bufferedWriter.flush();
bufferedWriter.close();
fileWriter.close();
*/
FileOutputStream fileOutputStream = new FileOutputStream(file);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
outputStreamWriter.append(fullOrder);
outputStreamWriter.close();
fileOutputStream.close();
MediaScannerConnection.scanFile(context, new String[]{file.toString()}, null, null);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(dir)));
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(dir2)));
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
} catch (IOException ioEx) {
Toast.makeText(context, ioEx.toString(), Toast.LENGTH_SHORT).show();
Log.d("mTag", "msg");
Log.d("Exception ioEx 1", ioEx.toString());
} catch (Exception ex) {
Toast.makeText(context, ex.toString(), Toast.LENGTH_SHORT).show();
Log.d("mTag", "msg");
Log.d("Genereic ex saveToFile", ex.toString());
}
The file is being written to external storage and while I can see that more space is taken up, the file itself is still not visible.
Any help with what might be the problem would be appreciate. Thank you!
The way you are sending broadcast to MediaScanner but may not work efficiently and is not recommended too.
The recommended way is to add the file paths of the files which have been created/updated, like this [in a String type ArrayList]
ArrayList<String> filesToBeScanned = new ArrayList<String>();
filesToBeScanned.add(item.getFilePath());
Now you need to run scanFile() static method of the MediaScannerConnection class and pass the String array containing the list of all the files which have been created/updated and needs to be media scanned.
You can also put a listener to respond when the scanning has been finished for individual files.
String[] toBeScannedStr = new String[toBeScanned.size()];
toBeScannedStr = fileToBeScanned.toArray(toBeScannedStr);
MediaScannerConnection.scanFile(getActivity(), toBeScannedStr, null, new OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
System.out.println("SCAN COMPLETED: " + path);
}
});
Hope this solves your prob.
For internal storage use:
getFilesDir() or getCacheDir()
See android documentation:
https://developer.android.com/training/data-storage

Sharing from snapchat to my app

I am unable to figure out how to share a video from SnapChat to my app while WhatsApp can do it without problems so it is possible.
Since SnapChat works with a contentprovider I figured I should just query the uri using the android contentresolver method. Using the databaseUtils I dumped the cursor to logcat but all it gives me back is the displayname and the filesize. I see no way how to get the actual file.
Help me out guys. What am I missing?
A bit late but i managed to solve it. Here is the solution. I added comments in the code to explain what i am doing.
void handleSendVideo(Intent intent)
{
// get title
String title = intent.getExtras().getString(Intent.EXTRA_SUBJECT);
// get the uri for the video
mVideoUri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM);
// check if it originates from snapchat
if (mVideoUri.getAuthority().equals(UriHelper.SNAPCHAT_FILE_PROVIDER))
{
Intent mRequestFileIntent;
ParcelFileDescriptor mInputPFD;
mRequestFileIntent = new Intent(Intent.ACTION_PICK);
mRequestFileIntent.setType("video/*");
// Query the content resolver to get the name of the file. Beware that you will not find
// the actual file here. You must read it from the fileDescriptor.
Cursor fileDataCursor = getContentResolver().query(mVideoUri, null, null, null, null);
String fileName = "";
if (fileDataCursor != null)
{
fileDataCursor.moveToFirst();
fileName = fileDataCursor.getString(0);
fileDataCursor.close();
}
// something is wrong... return
if (fileName.isEmpty())
{
return;
}
try {
// open the file descriptor that belongs to the file given to us by snapchat.
mInputPFD = getContentResolver().openFileDescriptor(mVideoUri, "r");
// fetch the descriptor
FileDescriptor fd = mInputPFD.getFileDescriptor();
// create in input stream from descriptor
InputStream inputStream = new FileInputStream(fd);
// This is the file that will be created
File targetFile = new File(Environment.getExternalStorageDirectory(), fileName);
// Open a outputstream connected to the file
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
// Create a buffer with a size equal to what is available from the inputstream.
// Note: we dont have to loop here because the file is available on the storage.
byte[] buffer = new byte[inputStream.available()];
// Read all data into the buffer
inputStream.read(buffer);
// Write the buffer to the outputstream
fileOutputStream.write(buffer);
// close all streams, our file is ready.
inputStream.close();
fileOutputStream.close();
mInputPFD.close();
// check if the new file exists.
if (targetFile.exists())
{
// add the file to the android MediaProvider
mVideoUri = addVideo(targetFile);
}
else
{
DialogMaker.showAlertMessage(this, "Could not read video", "unable to read video from SnapChat.", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
return;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
logger.i("videoUri: " + mVideoUri.toString());
logger.i("videoPath: " + mVideoUri.getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
public Uri addVideo(File videoFile) {
ContentValues values = new ContentValues(3);
values.put(MediaStore.Video.Media.TITLE, "My video title");
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATA, videoFile.getAbsolutePath());
return getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
}

My app can create a file, but cannot read it

I write a file in internal memory:
byte[] data = ... // (A buffer containing wav data)
String filename = context.getFilesDir().getAbsolutePath() + "/newout.wav";
File file = new File(filename);
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
Then I try to play it:
MediaPlayer player = new MediaPlayer();
player.setDataSource(filename);
player.prepare();
player.setLooping(false);
player.start();
But the prepare() fails:
java.io.IOException: Prepare failed.: status=0x1
I checked the file and saw that it's permission is -rw-------. I changed it to -rw-r--r--, after that it was being played successfully.
So how come my app can write a file, but can't read it? And how can I make the FileOutputStream to set the permissions right?
To change programaticaly the file permissions to -rw-r--r-- you need to do smoething like this:
Process process = null;
DataOutputStream dataOutputStream = null;
try {
process = Runtime.getRuntime().exec("su");
dataOutputStream = new DataOutputStream(process.getOutputStream());
dataOutputStream.writeBytes("chmod 644 FilePath\n");
dataOutputStream.writeBytes("exit\n");
dataOutputStream.flush();
process.waitFor();
} catch (Exception e) {
return false;
} finally {
try {
if (dataOutputStream != null) {
dataOutputStream.close();
}
process.destroy();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
If you open a file, the default mode is Context.MODE_PRIVATE, e.g. as in
File file = new File(context.getFilesDir(), filename);
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
(taken from the documentation). Modes MODE_WORLD_READABLE and MODE_WORLD_WRITABLE are deprecated and do not work on newer devices. So I'd say you should rather write on the external storage to make contents available to other apps.
Note: as per documentation:
External storage:
"It's world-readable, so files saved here may be read outside of your control."

Where will be a file created in android if I do it like this

This function creates a file but I can't figure out where is the file created and if someone has a solution to create a file in a particular directory from the external storage is very welcomed :) thanks a lot
private void writeFileToInternalStorage() {
String eol = System.getProperty("line.separator");
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(openFileOutput("myfile", MODE_WORLD_WRITEABLE)));
writer.write("This is a test1." + eol);
writer.write("This is a test2." + eol);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
for query
Where will be a file created
it will create in Internal Storage as function name said and that will be like
/data/data/yourApp_package_as_in_manifest/ (can see in DDMS)
for query
if someone has a solution to create a file in a particular directory
from the external storage is very welcomed
as per link Write a file in external storage in Android
.........
** 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 https://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);
}
and also add a WRITE_EXTERNAL_STORAGE permission to the manifest
It will be created on internal folder: /data/data/com.package.name/ You cannot access that folder using file browser.
If you want to easily access the file you can try to create it on SD card:
/*...*/
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = baseDir + "/"+ "myFile.txt";
FileOutputStream writer = null;
try {
writer = new FileOutputStream(fileName);
writer.write("This is a test1." + eol);
/*...*/

Impossible to create file on external storage Android

I want to create a .txt file and store it on the external storage of the Android phone. I added the permission to my Android Manifest. When I run the code it doesn't give me any error but the file is never created. Not sure what I am doing wrong.
public void createExternalStoragePrivateFile(String data) {
// Create a path where we will place our private file on external
// storage.
File file = new File(myContext.getExternalFilesDir(null), "state.txt");
try {
FileOutputStream os = null;
OutputStreamWriter out = null;
os = myContext.openFileOutput(data, Context.MODE_PRIVATE);
out = new OutputStreamWriter(os);
out.write(data);
os.close();
if(hasExternalStoragePrivateFile()) {
Log.w("ExternalStorageFileCreation", "File Created");
} else {
Log.w("ExternalStorageFileCreation", "File Not Created");
}
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
you need an appropriate permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
File file = new File(myContext.getExternalFilesDir(null), "state.txt");
try {
FileOutputStream os = new FileOutputStream(file, true);
OutputStreamWriter out = new OutputStreamWriter(os);
out.write(data);
out.close();
}
I was able to create the file on the external storage by using the code below:
public void createExternalStoragePrivateFile(String data) {
// Create a path where we will place our private file on external
// storage.
File file = new File(myContext.getExternalFilesDir(null), "state.txt");
try {
FileOutputStream os = new FileOutputStream(file);
OutputStreamWriter out = new OutputStreamWriter(os);
out.write(data);
out.close();
if(hasExternalStoragePrivateFile()) {
Log.w("ExternalStorageFileCreation", "File Created");
} else {
Log.w("ExternalStorageFileCreation", "File Not Created");
}
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}

Categories