I'm new to programming in android. I'm trying to create a csv file in the shared storage of the android device. I then want to add lines to that file based on user inputs. It looks like with android 11 the process of creating and editing file on shared storage has changed and i'm quite confused on how to accomplish it.
So far I have been able to create a csv file but I can't seem to edit it in any way. This is the code I used to create the csv file:
File baseDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
Uri baseDirUri = Uri.fromFile(baseDir);
String fileName;
String noteFile;
private void createFile() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/csv");
String currentTime = getPhoneTime();
fileName = "notes_" + currentTime + ".csv";
intent.putExtra(Intent.EXTRA_TITLE, fileName);
// Optionally, specify a URI for the directory that should be opened in
// the system file picker when your app creates the document.
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, baseDirUri);
startActivityForResult(intent, 1);
noteFile = baseDir.getAbsolutePath() + "/" + fileName;
writeToCsv("Time;ROS Time;Event;Team;Description;Ticket");
}
I then use openCSV to try and write to the csv File:
private void writeToCsv(String line) {
try {
// create FileWriter object with file as parameter
FileWriter outputfile = new FileWriter(noteFile);
// create CSVWriter object filewriter object as parameter
CSVWriter writer = new CSVWriter(outputfile);
writer.writeNext(line.split(";"));
// closing writer connection
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
But the file is empty when I go to view it. What am I doing wrong? Thanks for the help!
Related
I am creating an android application which reads and writes data to a file in the location /sdcard/ReadandWrite/.when i writing to that file it does not write in append mode.it will removes the old data and writes the new one.please help me to solve this.Here is my code.
private File openfile() {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/ReadandWrite");
dir.mkdirs();
File file = new File(dir, "myfile.txt");
file.setWritable(true);
if(file.exists())
{
file.canRead();
file.setWritable(true);
}
else {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
private void writetofile() {
try {
File file=openfile();
OutputStreamWriter myOutWriter =
new OutputStreamWriter(new FileOutputStream(file));
myOutWriter.append(text.getText());
myOutWriter.close();
myOutWriter.close();
Toast.makeText(getBaseContext(),
"Done writing SD 'mysdfile.txt'",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
You need to configure the FileOutputStream to use append mode. From JDK documentation:
public FileOutputStream(String name,
boolean append)
throws FileNotFoundException
Creates a file output stream to write to the file with the specified
name. If the second argument is true, then bytes will be written to
the end of the file rather than the beginning. A new FileDescriptor
object is created to represent this file connection.
First, if there is a security manager, its checkWrite method is called
with name as its argument.
If the file exists but is a directory rather than a regular file, does
not exist but cannot be created, or cannot be opened for any other
reason then a FileNotFoundException is thrown.
Parameters:
name - the system-dependent file name
append - if true, then bytes will be written to the end of the file rather than the beginning Throws:
FileNotFoundException - if the file exists but is a directory rather than a regular file, does not exist but cannot be created, or
cannot be opened for any other reason.
SecurityException - if a security manager exists and its checkWrite method denies write access to the file. Since:
JDK1.1 See Also:
SecurityManager.checkWrite(java.lang.String)
So change
OutputStreamWriter myOutWriter = new OutputStreamWriter(new FileOutputStream(file));
to
OutputStreamWriter myOutWriter = new OutputStreamWriter(new FileOutputStream(file, true));
I'm writing an Android application in which I want to create text files in a particular folder and afterwards I want to read the files from my device.
I'm doing this way:
File sd = Environment.getExternalStorageDirectory();
File f;
FileWriter fw = null;
String path = sd.getAbsolutePath() + "/Samples/";
f = new File(path+File.separator+"filename.txt");
if (!f.exists())
{
f.mkdirs();//Creates the directory named by this file, creating missing parent directories if necessary
try
{
f.createNewFile();
//fw = new FileWriter(f, true);
}
catch (IOException e)
{
Log.e("ERROR","Exception while creating file:"+e.toString());
}
The problem is that in this way I create another folder instead of a text file. What can I do? Thanks
Instead of:
f.mkdirs();
do:
path.mkdirs();
I found the solution and I want to share it with you:
File sd = Environment.getExternalStorageDirectory();
File folder;
String path = sd.getAbsolutePath() ;
folder = new File(path, dirName);
if (!folder.exists()){
folder.mkdirs();}
try{
File file = new File(folder, fileName+".txt");
file.createNewFile();
} catch (IOException e) {
Log.e("ERROR", "Exception while creating file:" + e.toString());
}
I hope this could help other people having the same problem. Good luck
I want to display a PDF stored in the assets folder using an external library. This library requires a path to a file.
I read that the pdf stored in the assets folder is not stored as a file. What I need is
Read the pdf-file from the assets into a (temporary) file object
get the path of that object for the external pdf-viewer-library
What I got so far is the following:
stream = getAssets().open("excerpt.pdf");
BufferedReader reader = new BufferedReader(
new InputStreamReader(stream));
I'm not really sure what to do next unfortunately...
EDIT:
I tried the following code:
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
String dirout= Environment.getExternalStorageDirectory().getAbsolutePath() + "/X/Y/Z/" ;
File outFile = new File(dirout, filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
}
}
...
I am getting an exception in "out = new FileOutputStream(outFile);" (no such file or directory). I thought the code create a file there?
Does the directory exists?
If not, it will send an IOException.
Just to make sure, try this approach:
final File directory = new File("/sdcard/X/Y/Z/");
if (!directory.exists()) {
directory.mkdirs();
}
It will create the parent directories if they don't exist. If they exist, it will return false and it will NOT delete the content in it. After this, just continue the same way you were doing it.
File outFile = new File(directory, filename);
Don't forget to add the permissions to your AndroidManifest!
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Copy the file to a public location that other applications can access using a process similar to that described in this question.
Keep a reference to the external file you created for launching your Intent(Intent.ACTION_VIEW).
Build an Intent to view your pdf, ex:
public void viewPdf(File YOUR_PUBLIC_FILE_FROM_STEP_1) {
PackageManager packageManager = getPackageManager();
Intent viewPdf = new Intent(Intent.ACTION_VIEW);
viewPdf.setType("application/pdf");
List<ResolveInfo> list =packageManager.queryIntentActivities(viewPdf,PackageManager.MATCH_DEFAULT_ONLY);
// Check available PDF viewers on device
if (list.size() > 0) {
Intent from_external_app = new Intent(Intent.ACTION_VIEW);
from_external_app.setDataAndType(Uri.fromFile(YOUR_PUBLIC_FILE_FROM_STEP_1),
"application/pdf");
from_external_app.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(from_external_app);
}
I am trying to save a file using a timestamp as the name. I can save the file no problem when I name it myself but when I try to use a timestamp it doesn't work. This is my code:
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
File newxmlfile = new File(Environment.getExternalStorageDirectory()
+ ts);
try {
newxmlfile.createNewFile();
} catch (IOException e) {
Log.e("IOException", "exception in createNewFile() method");
}
FileOutputStream fileos = null;
try {
fileos = new FileOutputStream(newxmlfile);
} catch (FileNotFoundException e) {
Log.e("FileNotFoundException", "can't create FileOutputStream");
}
Does anyone know how to do this?
EDIT(SOLVED): I changed the line below and it saved the file using the timestamp as an xml file.
File newxmlfile = new File(Environment.getExternalStorageDirectory()
,ts + ".xml");
I think you are creating you file with an invalid path.
When you doing the string concatination:
Environment.getExternalStorageDirectory() + ts
... you add your time stamp 123456to the file path (something like) /mnt/sdcard. And you end up with an invalid path like:
/mnt/sdcard14571747181
(And you havn't got access to write to that file since it isn't inside the external dir.)
Either you add a file separator yourself or you create the file with:
File newxmlfile = new File(Environment.getExternalStorageDirectory(), ts);
^^
the change
I think I have looked at all of the relevant questions and I still can't get this to work.
Here is the code:
File sdCard = Environment.getExternalStorageDirectory();
File directory= new File (sdCard.getAbsolutePath() + appName);
directory.mkdirs();
File file = new File(directory,fileName);
The folder is created, but I get an error saying the file does not exist. appName is a string containing the name of the folder and that works correctly. fileName is a string containing the name of the file I want to include.
I have included the permission in the manifest.
What am I doing wrong?
Update:
The code tries to make a subdirectory and a file at the same time, which hidden because the code uses a named String rather than a String literal. Adding an intermediate step to create the subdirectory solved the problem.
If the directory is created, then you're on the right track. In your code you are not actually creating the file on the SD card. If you need to create the file, then do this:
File sdCard = Environment.getExternalStorageDirectory();
File file = new File(sdCard.getAbsolutePath() + appName + "/" + fileName);
directory.mkdirs();
file.createNewFile()
This is notional only. It would be much better to actually separate your fileName into a separate subfolder and the actual file and handle them separately.
Try this out:
In this I am creating a text file (.txt file) of a string.
public void createFileFromString(String text)
{
File logFile = new File("sdcard/xmlresponseiphone.txt");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Test this, and see what are you missing :)
Try with something like this. In this case I'm saving an image!
For creating the directory:
File directory = new File(Environment.getExternalStorageDirectory()
+ File.separator + appName);
directory.mkdirs();
And for saving into it
public void save(Bitmap graph, Context context, String name, String time, boolean now) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
graph.compress(Bitmap.CompressFormat.PNG, 100, bytes);
// you can create a new file name "test.jpg" in sdcard folder.
String fileName = "";
if (now){
fileName = getDateTime()+"_00"+".png";
}
else {
fileName = time.replace(".txt", ".png");
}
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "appName/" + fileName);
f.createNewFile(); // write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
}
I think the trick is in File.separator!