In my app there are 3 EditTexts. I want to write the content of this EditTexts to a file, but the filewrite throws a nullpointer exception. Why?
OutputStream f1; is declared globally.
BtnSave = (Button)findViewById(R.id.Button01);
BtnSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
intoarray = name + "|" + number + "|" + freq + "\n";
Toast.makeText(Main.this, "" + intoarray, Toast.LENGTH_SHORT).show();
//so far so good
byte buf[] = intoarray.getBytes();
try {
f1 = new FileOutputStream("file2.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
f1.write(buf); //nullpointer exception
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
f1.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Most likely
f1 = new FileOutputStream("file2.txt");
failed and since you caught the exception f1 remained null. In most cases in Android you can only create files either in your application data directory or external storage.
The way you are currently using this won't work, generally you are trying to write to internal storage, which is private to your app and must be contained within your applications directory.
The proper way to create the file stream is
fin = openFileOutput("file2.txt", Context.MODE_PRIVATE); // open for writing
fout = openFileInput("file2.txt", Context.MODE_PRIVATE); // open for reading
Which will locate the file in your storage area for your application, which is typically something like
/data/data/com.yourpackagename/files/...
You can still create directories within your applications area if you need a directory structure of course.
If you need to write to external storage that's a different process, for more information see Android Data Storage
Sorry for all you were trying help me, I asked the wrong question. I wanted to use internal storage (and it is now working). I don't know what the problem is, but the with the code below (that i have used a lot) filewrite is ok:
try {
File root = Environment.getExternalStorageDirectory();
File file = new File(root, "Data.txt");
if (root.canWrite()) {
FileWriter filewriter = new FileWriter(file, true);
BufferedWriter out = new BufferedWriterfilewriter);
out.write(intoarray);
out.close();
}
} catch (IOException e) {
Log.e("TAG", "Could not write file " + e.getMessage());
}
I would delete the topic if I could. I accept this answer to close the topic.
Thanks, anyway.
Related
I searched and tried a lot before asking this.
But all the code that I'm trying is not working.
I want the file to be stored in the download folder and be accessible from the user also if he uninstalls the app.
I also tried using opencsv library. Could you provide a tested way to create a csv or txt file and store to download folder?
Save to to publicDir(Downloads folder) you first need permission.WRITE_EXTERNAL_STORAGE
check docs
Note this won't work without permmissions
private void saveData(){
String csv_data = "";/// your csv data as string;
File root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
//if you want to create a sub-dir
root = new File(root, "SubDir");
root.mkdir();
// select the name for your file
root = new File(root , "my_csv.csv");
try {
FileOutputStream fout = new FileOutputStream(root);
fout.write(csv_data.getBytes());
fout.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
boolean bool = false;
try {
// try to create the file
bool = root.createNewFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (bool){
// call the method again
saveData()
}else {
throw new IllegalStateException("Failed to create image file");
}
} catch (IOException e) {
e.printStackTrace();
}
}
I am writing values to my database and stop the time it needs for an evaluation.
Now I would like to write these times to an easy accessible file like a .txt but I can not write on the phone (some answers on the internet say because it is connected as "media source" but when I disconnect it I can not connect to eclipse anymore).
So the question is: How can I write a file which I can simply copy from my phone to my PC to get the data to analyze them.
you can use below function, text is your content:
public void backUp(String text,String namefile)
{
File file = new File(Environment.getExternalStorageDirectory()+"/yourdir/"+namefile+".txt");
if (!file.exists())
{
try
{
file.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(file, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
updated :
you should create your directory before use above function :
File yourdir = new File(Environment.getExternalStorageDirectory()+"/yourdir");
if(!yourdir.exists()){
yourdir.mkdir();
}
then :
backUp("hello world", "test");
don't forget this permission :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I'm having issues using the Cards from the recently released GDK. Basically, Card.addImage() can only take two arguments, a resource id or a URI.
For my use case, I need to open an image that exists as a file not directly as a resource. So for testing purposes I'm including the images in the assets folder. Trying to access them directly from the asset folder fails, so I'm copying them from there to internal storage. Once they're copied, I generate a URI from the file and assign it to the card. The resulting card shows a grey block where the image should be.
String fileName = step.attachment; //of the form, "folder1/images/image1.jpg"
File outFile = new File(getFilesDir()+File.separator+fileName);
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
//check to see if the file has already been cached in internal storage before copying
if(!outFile.exists()) {
FileInputStream inputStream = new FileInputStream(getAssets().openFd(fileName).getFileDescriptor());
FileOutputStream outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
inputChannel = inputStream.getChannel();
outputChannel = outputStream.getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
if(inputChannel!=null)
inputChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(outputChannel!=null)
outputChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
card.addImage(Uri.fromFile(outFile));
It's hard to diagnose because I have no clue what the Card is doing internally.
Instead of writing
new FileInputStream(getAssets().openFd(fileName).getFileDescriptor());
can you try
getAssets().openFd(fileName).createInputStream();
and see if it works?
To answer your original question, the addImage method supports resource: and file: URIs.
This is very strange, but I managed to solve my problem. I replaced the file copy code with the following and it appears to have solved my issues
InputStream in = null;
OutputStream out = null;
try {
in = getAssets().open(step.attachment);
out = new FileOutputStream(outFile);
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + step.attachment, e);
}
It's not clear to me why/how I was copying my entire apk, but I'm guessing it's the call to
getAssets().openFd(fileName).getFileDescriptor()
Perhaps it was returning the file descriptor of the apk. It's odd because I've seen some claim that the previous method works.
I am trying to read some files and put them into a new file using the below method in Eclipse.
But I am getting a read-only file system EROFS error in eclipse at run time.
Input file names will be provided as function parameter. Files are present in res\raw folder.
SampleFile.mp3 is an empty audio file placed at the location.
public void myfun(Set s)
{
try {
FileOutputStream fos=new FileOutputStream(".\\res\raw\sampleFile.mp3",true);
FileInputStream fis;
Iterator ptr=s.iterator();
String str;
while(ptr.hasNext()!=null)
{
str=ptr.next().toString();
fis=new FileInputStream(str);
int i;
while((i=fis.read())!=-1)
{
fos.write(i);
}
fis.close();
}
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You are trying to write into the 'res/raw' folder of the current directory, but android does not work like that. Go read the Storage Options section of the Android Development Guide, and choose one that fits your needs (and use case).
Also, you want to concatenate multiple files into an mp3? Are they by any chance... mp3 files themselves that you want to play?
I have a dialog with spinners and an OK button. I also have an arraylist that is populated by the user selecting items in the spinners. I want the app to save the arraylist to a file and load it at every launch (because without saving the arraylist is always empty at launch).
So here is the code i am using. The saving should be okay, at least i get the Toast message saying Saving OK. This code is the OKbtn listener so when user clicks ok, an item is added to the arraylist and there comes this code:
if (assignArr.size() > 0)
{
String filename = "file.txt";
ArrayList<String> report = new ArrayList<String>();
for (int i=0; i<assignArr.size(); i++)
{
report.add(assignArr.get(i));
}
FileOutputStream fos;
try {
fos = openFileOutput(filename,Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(report);
out.close();
Toast.makeText(MainActivity.this, "Saving OK", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I put the loading part to the beginning of the code, but i don't think it matters:
words = new ArrayList<String>(50);
try {
InputStream is = getResources().getAssets().open("file.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while((line = br.readLine()) != null)
{
words.add(line);
}
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
if (words.size() > 0)
{
for (int i=0; i<words.size(); i++)
{
assignArr.add(words.get(i));
Toast.makeText(MainActivity.this, "Loading OK", Toast.LENGTH_LONG).show();
}
}
In this case i never get the toast message.
One problem can be that where is the file created? Where in the emulator and where on the phone? And regarding the phone, is it created on the sd card or the phone memory?
I hope this is the right code to save and load an arraylist.
What is wrong with the code?
Update:
I replaced InputStream is = getResources().getAssets().open("file.txt"); withInputStream is = openFileInput("file.txt");
Now something happens. I write out the result of the saving and the loading into a toast message, which is weird:
Toast.makeText(MainActivity.this, "Saving OK + " + report, Toast.LENGTH_LONG).show();
Please take a look at it. The words on the bottom are partly hungarian names. So maybe the saving an arraylist to a file is the problem.
The file you create via openFileOutput is written into your app's private directory, which you can get using Context#getFilesDir() (usually it's /data/data/<your-app-package>/).
This directory has nothing to do with the assets folder.