Saving object to file on internal storage (Android) - android

I tried this:
public class People implements Serializable {
String name;
public People(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void saveAsObject(People p) throws FileNotFoundException, IOException
{
try
{
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(new File("test","test.dat") ));
os.writeObject(p);
os.close();
System.out.println("Sucess");
}
catch(IOException e)
{
System.out.println(e);
}
}
}
I created that folder manually. It throws this eror: "java.io.FileNotFoundException: /test/test.txt: open failed: ENOENT" (No such file or directory)
When i tried
new FileOutputStream("text.dat")
it throws java.io.FileNotFoundException: EROFS (Read only file system)
This is my main class:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
People p = new People("Ray");
try {
p.saveAsObject(p);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

this new File("test","test.dat") is not a valid way of getting a file path on Android.
try this:
new File(Environment.getExternalStorageDirectory(), "/data.dat");

Your app's default current working directory is "/", which you won't have permission to write to.

Related

java.io.FileNotFoundException: output.mp4 (Read-only file system)

I am trying to convert my images into a video. I found the sample code and used into my application. But I am getting error like
java.io.FileNotFoundException: output.mp4 (Read-only file system)
Here is the snippet of my code:
public class Main2Activity extends AppCompatActivity {
AndroidSequenceEncoder encoder;
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ArrayList<Bitmap> arrayList = new ArrayList<>();
Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.empty_collage);
Bitmap a = BitmapFactory.decodeResource(getResources(),R.drawable.images);
arrayList.add(a);
arrayList.add(b);
File file = new File("output.mp4");
SeekableByteChannel out = null;
try {
out = (SeekableByteChannel) NIOUtils.writableFileChannel(String.valueOf(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("msg",e.toString());
}
try {
encoder = new AndroidSequenceEncoder((org.jcodec.common.io.SeekableByteChannel) out, Rational.R(25,1));
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(this, "in for loop", Toast.LENGTH_SHORT).show();
for(int i=0 ;i<arrayList.size() ; i++){
try {
encoder.encodeImage(arrayList.get(i));
} catch (IOException e) {
e.printStackTrace();
}
}
Toast.makeText(this, "out of loop", Toast.LENGTH_SHORT).show();
try {
encoder.finish();
} catch (IOException e) {
e.printStackTrace();
}
NIOUtils.closeQuietly(out);
}
}
}
Hope I'll get respond very quickly.
Thank you.
File file = new File("output.mp4");
This does not point anywhere useful. Always use a method to derive a root location to write to.
For example, you could change this to:
File file = new File(getFilesDir(), "output.mp4");
or:
File file = new File(getExternalFilesDir(null), "output.mp4");

Unable to serialize an object and getting it back in Android

I'm trying to serlize an Enum Class so I can restore in in onCreate() method so each run I have an updated class.
Here is the code for serlizing and deserializing the class:
private void serializeModulesManager() {
try {
FileOutputStream fos = openFileOutput("modules.ser",
Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(Module.values());
out.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void restoreModulesManager() {
FileInputStream fileIn;
Module[] arr = null;
try {
fileIn = openFileInput("modules.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
arr = (Module[]) in.readObject();
for (Module c : arr) {
Module.valueOf(c.name()).serilize(c);
}
in.close();
fileIn.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I call serializeModulesManager() in onDestroy() , and I call restoreModulesManager() in onCreate()..
The problem is that when I force close (from task manager), ObjectInputStream fails to read the object and I get an "EOFException"..
How can I fix this?
Here is how i would handle this. This is a simple object with only a title field but you can use this same idea for more complicated objects
public class MyObject implements Parcelable{
public String title;
public MyObject(){}
public MyObject(Parcel source){
title = source.readString();
}
public void setTitle(String title){
this.title = title;
}
public String getTitle(){
return this.title;
}
// Parcel Overrides
#Override
public int describeContents(){return 0;}
#Override
public void writeToParcel(Parcel dest, int flags){
dest.writeString(title);
}
// Parcelable Creator
public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>(){
#Override
public MyObject createFromParcel(Parcel source){
return new MyObject(source);
}
#Override
public MyObject [] newArray(int size){
return new MyObject[size];
}
}
}
And then in your class that instantiates the object
// Add this in onSavedInstanceState(Bundle outState)
outState.putParcelableArray("MyObjectArray",myObjects);
then in OnCreate or whichever method your using to restore UI
// Add this
myObjects = (MyObject [])savedInstanceState.getParcelableArray("MyObjectArray");

Reading FTP File with Android

I am using FTP to upload a file. This works great. This file contains information what the app should do.
So I am doing the following:
1) Download the file with Apache FTP Client (seems to work fine)
2) Try to read out the file with a BufferedReader and FileReader.
The problem:
I get a NullPointerException while reading the file. I guess that this is a timing problem.
The code has this structure:
...
getFile().execute();
BufferedReader br = new BufferedReader(...);
How can I solve this problem?
I have to use a seperate Thread (AsyncTask) to download the file because otherwise it will throw a NetworkOnMainThread Exception.
But how can I wait until the file is completely downloaded without freezing the UI?
I cannot use the BufferedReader inside AsyncTask because I use GUI elements and I have to run the interactions on the GUI Thread, but I have no access to it from AsyncTask. RunOnUiThread does not work as well because I am inside a BroadcastReceiver.
Some code:
private class GetTask extends AsyncTask{
public GetTask(){
}
#Override
protected Object doInBackground(Object... arg0) {
FTPClient client = new FTPClient();
try {
client.connect("*****");
}
catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
client.login("*****", "*****");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream( "/sdcard/"+userID+".task" );
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
resultOk &= client.retrieveFile( userID+".task", fos );
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}/**
try {
client.deleteFile(userID+".task");
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
**/
try {
client.disconnect();
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
return null;
}
}
The Broadcastreceiver class:
public class LiveAction extends BroadcastReceiver {
...
private Context cont;
FileReader fr = null;
BufferedReader br;
#Override
public void onReceive(Context context, Intent intent)
{
cont = context;
...
new GetTask().execute();
try {
Thread.sleep(3000);
}
catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
fr = new FileReader("/sdcard/"+userID+".task");
}
catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
br = new BufferedReader(fr)
String strline = "";
try {
while ((strline = br.readLine()) != null){
if(strline.equals("taskone")){
//Some GUI Tasks
}
....
This is the relevant code.
I think the best approach would be to read the file's contents from the doInBackground inside the AsyncTask and then output an object which contains the info you need on the onPostExecute method of the async stask and then manipulate your UI.
private AsyncTask<String,Void,FileInfo> getFile(){
return new AsyncTask<String,Void,FileInfo>{
protected FileInfo doInBackground(String url){
FileInfo finfo = new FileInfo(); // FileInfo is a custom object that you need to define that has all the stuff that you need from the file you just downloaded
// Fill the custom file info object with the stuff you need from the file
return finfo;
}
protected void onPostExecute(FileInfo finfo) {
// Manipulate UI with contents of file info
}
};
}
getFile().execute();
Another option is to call another AsyncTask from onPostExecute that does the file parsing but I would not recommend it
I would try some thing like this:
private class GetTask extends AsyncTask{
LiveAction liveAction;
public GetTask(LiveAction liveAction){
this.liveAction = liveAction;
}
...
#Override
protected void onPostExecute(String result) {
liveAction.heyImDoneWithdownloading();
}
}
Ps: why the Thread.sleep(5000)?
public class LiveAction extends BroadcastReceiver {
...
public void heyImDoneWithdownloading(){
//all the things you want to do on the ui thread
}
}

Calling a method from Activity2 in Activity1

I have two classes/Activities:
FirstClass:
public class FirstClass extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void addData(String filename, String data); {
SecondClass second = new SecondClass();
second.save(name, data);
}
}
SecondClass:
public class SecondClass extends Activity {
public void save(String filename, String data) {
try {
FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
As you can see, what I want to do is to call a method from SecondClass in FirstClass. The method savse some data to the internal storage.
What is the correct way of doing this? I know i should probably do something with Context, but i don't know what exactly.
Make it as a simple java class.
public class ThirdClass
{
public void save(String filename, String data, Context context)
{
try {
FileOutputStream fos = context.openFileOutput(filename,Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Call this method like in your First Activity.
ThirdClass third= new ThirdClass();
third.save(name, data,this);
Alternative If you don't want to make the Third class and want to do with SecondClass. Then make this save method to static.
public class SecondClass extends Activity
{
//Oncreate method....
public static void save(String filename, String data)
{
try {
FileOutputStream fos = openFileOutput(filename,Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and Call this method from First Activity.
SecondClass.save(name, data);
make save a static method and/or move it to its own static class (not activity).
So you can call it using the following:
SecondClass.save(name, data);
and define it as the following:
public static void save(String filename, String data)
{
You should create a class named something like SaveHelper, that doesn't extend activity and add a static method so you can do:
FileHelper.save(...)
public class FileHelper {
public static void save(Context context, String filename, String data) {
try {
FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Android, write to file using inheritance

I am currently saving a message to a single file from multiple activity classes within my app. Each activity class has the same function WriteToFile.
public void WriteToFile(String info) {
FileOutputStream FoutS = null;
OutputStreamWriter outSW = null;
try {
FoutS = openFileOutput("file.txt", MODE_PRIVATE);
outSW = new OutputStreamWriter(FoutS);
outSW.write(info);
outSW.flush();
}
catch (Exception e) {
}
finally {
try {
outSW.close();
FoutS.close();
} catch (IOException e) {
}
}
}
I have been attempting to create a separate class which holds this function write (and read) to file but I haven't been able to without getting errors.
I think the function needs to have context passed through to the WriteToFile void like...
//Changes to this line
public void WriteToFile(String info, Context context) {
FileOutputStream FoutS = null;
OutputStreamWriter outSW = null;
try {
//Changes to this line
FoutS = context.openFileOutput("file.txt", MODE_PRIVATE);
outSW = new OutputStreamWriter(FoutS);
outSW.write(info);
outSW.flush();
}
catch (Exception e) {
}
finally {
try {
outSW.close();
FoutS.close();
} catch (IOException e) {
}
}
}
if that is correct am I passing the context correctly?
String msg = "This is a message";
WriteToFile(msg, this);
It's not working so I am doing something wrong.
You should use your context to call the method
context.openFileOutput("file.txt", context.MODE_PRIVATE);
what you wrote has no meaning, or far from what you mean.

Categories

Resources