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.
Related
I have created a ListView and it can add data dynamically but whenever I restart the App the previous stored list is lost.
How can I save that list ?
You can save them into client local via using android SharedPreferences
Or, you can write your own model.
You should pass your object here;
public boolean writeYourObjectOnLocal(File dir, YourObject yourObject) {
ObjectOutput output = null;
OutputStream buffer = null;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(dir.toString() + File.separator + "myFile.dat");
buffer = new BufferedOutputStream(fileOutputStream);
output = new ObjectOutputStream(buffer);
output.writeObject(yourObject);
return true;
} catch (Throwable e) {
return false;
} finally {
try {
output.close();
} catch (Throwable e) {}
try {
buffer.close();
} catch (Throwable e) {}
try {
fileOutputStream.close();
} catch (Throwable e) {}
}
}
You can Read your object;
public YourObject readYourObjectFromLocal(File dir) {
ObjectInput input = null;
BufferedInputStream buffer = null;
FileInputStream fileInputStream = null;
try {
String fileName = dir.toString() + File.separator + "myFile.dat";
fileInputStream = new FileInputStream(fileName);
buffer = new BufferedInputStream(fileInputStream);
input = new ObjectInputStream(buffer);
return (YourObject)input;
} catch (Throwable e) {
return null;
} finally {
try {
input.close();
} catch (Throwable e) {
}
try {
fileInputStream.close();
} catch (Throwable e) {
}
try {
buffer.close();
} catch (Throwable e) {
}
}
}
I would recommend you to use caching library like Reservoir. Check instructions how to use it on this link.
https://github.com/anupcowkur/Reservoir
Be sure to allocate enough memory in your application class (size in bytes).
Example: Save data (Async):
// it can be any type of object (here is String)
List<String> strings = new ArrayList<String>();
strings.add("one");
strings.add("two");
strings.add("three");
Reservoir.putAsync("myListKey", strings, new ReservoirPutCallback() {
#Override
public void onSuccess() {
//success
}
#Override
public void onFailure(Exception e) {
//error
}
});
Example: Read saved data (Async):
Reservoir.getAsync("myListKey", new TypeToken<List<String>>() {}.getType(),
new ReservoirGetCallback<List<String>>() {
#Override
public void onSuccess(List<String> strings) {
//success - set your list adapter and show those items
}
#Override
public void onFailure(Exception e) {
//error
}
});
If you need to persist large volume of data you should use SQLite database and it is best for this purpose. But you can also use xml to store your data, xml is slow then SQLite database.
You can refer this standard Storage options.
I'm creating and saving data in a file in the onPause of the Base Activity but I'm reading the information in the onCreate of other activities. The thing is, the onPause saving has been called and no errors seem to appear in the logcat. However if I try to read the info in the onCreate I'm receiving the old content I had there, instead of the new one I saved.
public String parseToJsonString(Object object){
String json = gson.toJson(object);
return json;
}
public static boolean save(Context ctx, String filename, String content){
boolean wasSaved = false;
FileOutputStream fos = null;
try {
fos = ctx.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(content.getBytes());
fos.flush();
wasSaved = true;
Log.d(TAG, content);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fos != null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return wasSaved;
}
#Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
String jsonSettings = APP().parseToJsonString(settings);
FileUtil.save(this, getString(R.string.file_settings_preferences), jsonSettings);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getResources().getBoolean(R.bool.phone_size))
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.att_base_activity);
preferences = APP().getSecuredPreferences();
workflow = APP().createWorkflow();
settings = getAttendanceSettings();
Log.d(TAG, settings.toString());
toolbar = (Toolbar) findViewById(R.id.ab_tool_bar);
setSupportActionBar(toolbar);
}
public AttSettings getAttendanceSettings() {
AttSettings settings = null;
try {
JSONObject jsonSettings = FileUtil.getJSONContentFromFile(this,
getString(R.string.file_settings_preferences));
if (jsonSettings != null)
settings = new AttSettings(jsonSettings);
else
settings = new AttSettings();
} catch (IOException e) {
e.printStackTrace();
}
return settings;
}
I really don't know what I'm doing wrong, help would be appreciated.
Hello in my app I need to store single object with several fields. At this moment it is saved like this
#Override
public Object onRetainNonConfigurationInstance() {
return UILApplication.advert;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Advert retainedAdvert = (Advert) getLastNonConfigurationInstance();
if (retainedAdvert != null) {
UILApplication.advert = retainedAdvert;
}
}
Where UILApplication is singleton to keep advert. Sometimes ( often when call camera) advert object is erised to default. So i want to know about save and efficient way to kepp this object. Is it wise to store it in file/ serialise it or create database for a single record or there is something better?
Taken from my calculator:
#SuppressWarnings("unchecked")
private void loadState() {
ObjectInputStream ois;
try {
ois = new ObjectInputStream(openFileInput(FILE_STATE));
state = ((State) ois.readObject());
ois.close();
ois = new ObjectInputStream(openFileInput(FILE_HISTORY));
historyListAdapter.setItems((List<String>) ois.readObject());
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
state = new State();
} catch (IOException e) {
e.printStackTrace();
state = new State();
} catch (ClassNotFoundException e) {
Toast t = Toast.makeText(this, "Error parsing saved state",
Toast.LENGTH_SHORT);
t.show();
state = new State();
}
setState(state);
}
private void saveState() {
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(openFileOutput(FILE_STATE,
Context.MODE_PRIVATE));
oos.writeObject(state);
oos.close();
oos = new ObjectOutputStream(openFileOutput(FILE_HISTORY,
Context.MODE_PRIVATE));
oos.writeObject(historyListAdapter.getItems());
oos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onPause() {
saveState();
super.onPause();
}
Call loadState() in onCreate().
Worked fine for me, I know its not advised to use java serialization in android, but I didn't encounter any errors or bugs whatsoever. No issues with performance either.
You should of course tweak error handling depending on your application.
Depends how big your object is. Try with shared preferences: http://developer.android.com/guide/topics/data/data-storage.html#pref
Combination of preferences, right places to populate/read from it, and some static init method could do things for you.
Hope it helps.
I'm programming a little game and I want to save on sd-card the scores and the the volume (enabled or disabled)
the code of my two functions is:
public static void load(FileIO files) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
files.readFile(".save")));
soundEnabled = Boolean.parseBoolean(in.readLine());
for (int i = 0; i < 5; i++) {
highscores[i] = Integer.parseInt(in.readLine());
}
} catch (IOException e) {
// :( It's ok we have defaults
} catch (NumberFormatException e) {
// :/ It's ok, defaults save our day
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
}
//-----------------------
public static void save(FileIO files) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
files.writeFile(".save")));
out.write(Boolean.toString(soundEnabled));
for (int i = 0; i < 5; i++) {
out.write(Integer.toString(highscores[i]));
}
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
while the program is running this code is ok but if I restart my device the scores are lost..
do you know why?
thanks!!
ps: the FileIO class is:
public class AndroidFileIO implements FileIO {
Context context;
AssetManager assets;
String externalStoragePath;
public AndroidFileIO(Context context) {
this.context = context;
this.assets = context.getAssets();
this.externalStoragePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator;
}
public InputStream readAsset(String fileName) throws IOException {
return assets.open(fileName);
}
public InputStream readFile(String fileName) throws IOException {
return new FileInputStream(externalStoragePath + fileName);
}
public OutputStream writeFile(String fileName) throws IOException {
return new FileOutputStream(externalStoragePath + fileName);
}
public SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(context);
}
}
There are two problems here. First, out.write does not insert a newline at the end of each call, you have to do that manually. So what is happening is when you do the readline in the cal to parse the Boolean you are actually consuming ALL the data in the file. Second, you need to flush and close the file before leaving that function to be sure you do not leave any data in the buffers.
Here is save rewritten that should work:
public static void save(FileIO files) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
files.writeFile(".mrnom")));
out.write(Boolean.toString(soundEnabled));
out.write("\n");
for (int i = 0; i < 5; i++) {
out.write(Integer.toString(highscores[i]));
out.write("\n");
}
out.flush();
out.close();
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
I'm proggraming for first time but iv solved this using shared prefs. That way you avoid losing data when updating the app.
i'm trying to save a list of integers in my application by saving each integer in a new line of a file in the internal storage.
For retreiving it I read it line by line and put every linevalue, parsed as integer, in my list of integers.
I know a database is better for this kinda stuff, but this should work.
I am trying for quite a while now, but it never seems to work. I always get a nullpointerexception when trying to read. I logged "line", it gave the value it should have. But
saving one id, adding it as a new string:
private void saveToFavorites(Integer saveFav) {
String favstr = String.valueOf(saveFav);
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(openFileOutput("favorites", MODE_WORLD_WRITEABLE)));
writer.newLine();
writer.append((favstr));
System.out.println(" added to favs :"+ saveFav);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And the reading method:
#SuppressWarnings("null")
private List<Integer> readFileFromInternalStorage() {
List<Integer> favs = null;
BufferedReader input = null;
try {
input = new BufferedReader(new InputStreamReader(openFileInput("favorites")));
String line;
while ((line = input.readLine()) != null) {
System.out.println("readFileFromInternalStorage line value: "+ line );
favs.add(Integer.parseInt(line));
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("readFileFromInternalStorage: fail" );
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return favs;
}
Which is in an other activity. I thought it would work but it clearly doesnt. When reading back, the logline: System.out.println("readFileFromInternalStorage line value: "+ line );
displays that the value of line equals the LAST added id,and an empty line, and not the others too. So the line by line saving fails. Also when parsing it to an integer it fails, what is weird because it is only a number.
08-01 12:29:54.190: I/System.out(1540): readFileFromInternalStorage line value:
08-01 12:29:54.190: I/System.out(1540): readFileFromInternalStorage line value: 301
Anyone knows what i need to change?
Since Integer is Serializable I sugget to serialize the entire List:
private void saveList(List<Integer> list) {
try {
File file = Environment.getExternalStorageDirectory();
File filename = new File(file, "yourfilename");
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(list);
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void readList()
{
try {
File file = Environment.getExternalStorageDirectory();
File filename = new File(file, "yourfilename");
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
List<Integer> list= (List<Integer>) in.readObject();
in.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
try this May it help you :-
1 - String saveFav = contaains all integer this form I1+"/"I2+"/"I3;
2:- then save it into file
private void saveToFavorites(String saveFav) {
//right here your code for write into file saveFave string
}
in reading file read string and split("/").it's working for me .
Here's some working code that will read and write ints to the phones internal memory.
You can create an array or list of ints and basically just iterate over it until all ints are saved/read to/from the memory:
Here's the code to write an int to the memory:
public void writePrimitiveInternalMemory(String filename, int value) {
SharedPreferences preferences = this.getPreferences(Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(filename, value);
editor.commit();
}
Here's code to read from the memory:
public int readPrimitiveInternalMemoryInteger(String filename) {
SharedPreferences preferences = this.getPreferences(Activity.MODE_PRIVATE);
return preferences.getInt(filename, 0);
}
I hope this helps you!
You are not allocating the integer list...
List<Integer> favs = null;
Allocate a new arraylist..
List<Integer> favs = new ArrayList<Integer>();