I'm trying to save and load a String to/from the internal storage in a way that allows the user to exit the app, even shut down the phone, but still access this String whenever the app is used.
When I exit the app it and re-enter, it will not load the String I stored previously. I need it to load the previous String even if I reboot the phone. Here is what I have so far:
EditText sharedData;
TextView dataResults;
FileOutputStream fos;
String FILENAME = "InternalString";
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.sharedpreferences);
setupVariables();
}
private void setupVariables() {
// TODO Auto-generated method stub
sharedData = (EditText) findViewById(R.id.editText_SharedPrefs);
dataResults = (TextView) findViewById(R.id.textView_LoadSharedPrefs);
Button save = (Button) findViewById(R.id.button_save);
Button load = (Button) findViewById(R.id.button_load);
save.setOnClickListener(this);
load.setOnClickListener(this);
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button_save:
String data = sharedData.getText().toString();
try {
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();
}
break;
case R.id.button_load:
String collected = null;
FileInputStream fis = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
collected = new String(dataArray);
}
dataResults.setText(collected);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
Depending on what sort of "string" you're using you should use SharedPreferences rather than write files... unless it's a lot of data.
getSharedPreferences(getPackageName() , MODE_PRIVATE).edit().putString("myString").commit();
That will persist through phone powercycles. It will get lost if you uninstall the app however (which is probably a good thing).
Here's the Android doc for all the various data saving possibilities open to you...
Saving Stuff On Android
Related
I'm currently learning about IO and Async but am having issues. I'm following a guide, and according to the guide this is supposed to work. I have created an activity with a simple EditText, TextView, and 2 Buttons(save and load). I am trying to have the save button take the text in the EditText and save to internal storage, and the load button take whatever is saved and set the TextView as that. Everything works flawlessly when I put all the code to run in the UI thread, but if I change the code to have the UI thread call the Async class for the loading, nothing seems to happen.
**Packages and imports have been removed to save space.
public class InternalData extends Activity implements OnClickListener {
EditText etSharedData;
TextView tvDataResults;
FileOutputStream fos;
String FILENAME = "InternalString";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.sharedpreferences);
setupVariables();
}
private void setupVariables() {
Button bSave = (Button) findViewById(R.id.bSave);
Button bLoad = (Button) findViewById(R.id.bLoad);
etSharedData = (EditText) findViewById(R.id.etSharedPrefs);
tvDataResults = (TextView) findViewById(R.id.tvLoadSharedPrefs);
bSave.setOnClickListener(this);
bLoad.setOnClickListener(this);
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bSave:
String sData = etSharedData.getText().toString();
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(sData.getBytes());
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case R.id.bLoad:
String sCollected = null;
FileInputStream fis = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
sCollected = new String(dataArray);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
fis.close();
tvDataResults.setText(sCollected);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
The previous code makes everything work, but the UI lags a bit when trying to load large strings. When I try to have an LoadSomeStuff(Async) class do the loading, it does absolutely nothing when I hit Load on my phone. Within the LoadSomeStuff class it has the doInBackground method open the file and read the data into a string then return that string, and the onPostExecute method set the TextView's text to the returned String. Here's the code:
The onClick method for load button has:
new LoadSomeStuff().execute(FILENAME);
LoadSomeStuff Class *Note: This class is declared within the InternalData class.
public class LoadSomeStuff extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
String sCollected = null;
FileInputStream fis = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
sCollected = new String(dataArray);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
fis.close();
return sCollected;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String result){
tvDataResults.setText(result);
}
}
}
Any help is greatly appreciated, thanks!
It actually looks like I had an extra method or two(like onPreExecute) with no code in them and when I deleted them it starting working.
I'm trying to save a custom object when I click a menu item. The problem is its crashing. Before we start, when I try to read that data in another activity, that also crashes. Here is my code where I'm trying to save the data:
Here's a pastebin link.
my write function in the menu
myInfo.setOnMenuItemClickListener(new OnMenuItemClickListener()
{
public boolean onMenuItemClick(MenuItem item)
{
Intent ourIntent = new Intent(Results.this, listTimes.class);
ourIntent.putExtra("Meeting", meetingObj);
try {
fos = new FileOutputStream(filename);
oos = new ObjectOutputStream(fos);
oos.writeObject(businesses.get(positionChecked));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
oos.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//startActivity(ourIntent);
return true;
}
// My read function
private void getData()
{
try {
fis = openFileInput(filename);
ois = new ObjectInputStream(fis);
business = (Business) ois.readObject();
} 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();
}
finally
{
try {
ois.close();
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The code creates a text file in local memory, but how do I get all files created by my application in a list view:
public class newfile extends Activity {
public EditText textBox,textbox2;
FileOutputStream fos=null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newfile);
Button save = (Button) findViewById(R.id.btnSave);
save.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
textBox = (EditText) findViewById(R.id.txtText1);
textbox2 = (EditText) findViewById(R.id.fname);
String FILENAME = textbox2.getText().toString();
String value = textBox.getText().toString();
try{
fos = openFileOutput(FILENAME,MODE_WORLD_WRITEABLE);
}
catch(IOException e)
{
e.printStackTrace();
}
byte[] buffer = value.getBytes();
try {
fos.write(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
Toast.makeText(getBaseContext(), "File saved successfully!", Toast.LENGTH_LONG).show();
finish();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
You can get a list all application files using Context.fileList. Then use ArrayAdapter to populate your list view
My app crashes when it tryes to load a file that isnt there. how do i stop it from loading the file when there isnt a file but when there is a file of that name it does load it.
Here is the code I am using to load the file. Any comments would be appreciated :)
Cheers
try {
fis = openFileInput(FILENAME1);
byte[] dataArray = new byte[fis.available()];
while (fis.read(dataArray) != -1){
task1 = new String(dataArray);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Try something like this:
fis = getContext().getFileStreamPath(FILENAME1);
if( fis.exists() ) {
...
}
else {
....
}
I am an amateur programmer developing for android. I am just trying get the basics down right now, but I am having an error and I don't know why.
I am creating a activity that has a save and a load button, which using the fileOutputStream and fileInputStream to achieve this task.
The problem I am having is if I hit the load button the first time I use the activity, my application crashes. Can anyone help me with how to skip the load section if the file hasn't been created yet? What should I use within my if statement.
Thanks a ton, here is my code:
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class InternalData extends Activity implements OnClickListener {
String FILENAME = "InternalString";
EditText sharedData;
TextView dataResults;
FileOutputStream fos;
String d;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.sharedpreferences);
Button save = (Button) findViewById(R.id.bSave);
Button load = (Button) findViewById(R.id.bLoad);
sharedData = (EditText) findViewById(R.id.etSharedPrefs);
dataResults = (TextView) findViewById(R.id.tvLoadSharedPrefs);
save.setOnClickListener(this);
load.setOnClickListener(this);
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bSave:
d = sharedData.getText().toString();
try {
fos.write(d.getBytes());
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case R.id.bLoad:
FileInputStream fis = null;
try {
if (openFileInput(FILENAME) != null){
fis = openFileInput(FILENAME);
byte[] data = new byte[fis.available()];
while(fis.read(data) != -1){
String readData = new String(data);
dataResults.setText(readData);
}}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
}
Thanks for the help Lukas, I have updated my code, and I was wondering if you could look it over to make sure I am using the AsyncTask properly. Thanks again!
public class InternalData extends Activity implements OnClickListener {
String FILENAME = "InternalString";
EditText sharedData;
TextView dataResults;
FileOutputStream fos;
String d;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.sharedpreferences);
Button save = (Button) findViewById(R.id.bSave);
Button load = (Button) findViewById(R.id.bLoad);
sharedData = (EditText) findViewById(R.id.etSharedPrefs);
dataResults = (TextView) findViewById(R.id.tvLoadSharedPrefs);
save.setOnClickListener(this);
load.setOnClickListener(this);
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bSave:
d = sharedData.getText().toString();
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(d.getBytes());
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case R.id.bLoad:
AsyncTask<String, Integer, String> dat = new loadInternalData().execute(FILENAME);
break;
}
}
public class loadInternalData extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
FileInputStream fis = null;
String collected = null;
try {
fis = openFileInput(FILENAME);
byte[] data = new byte[fis.available()];
while (fis.read(data) != -1){
collected = new String(data);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
fis.close();
return collected;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return collected;
}
#Override
protected void onPostExecute( String result )
{
super.onPostExecute(result);
Log.i( "InteralStorage", "onPostExecute(): " + result );
dataResults.setText( result );
}
}
}
You are calling openFileInput twice. Just call it once.
Instead of this
if (openFileInput(FILENAME) != null){
fis = openFileInput(FILENAME);
}
Do this:
fis = openFileInput(FILENAME);
if (fis != null) {
// Read file
}
If you execute something on the UI-Thread, it shouldn't take longer then 5 seconds or an ANR will be triggered.
If you want to do something that might take longer then those 5 seconds, you'll want to do it in a Service or an AsyncTask.
Also, if your App gets force closed and you don't know why, you should always have a look at the LogCat output which can be shown in Eclipse. Also, you should include it with every question you ask here (about Android).