I'm writing a simple app which allows a user to enter their income and it deducts tax, then saves the amount in a file for future reference. Whenever I try to enter an amount I get a warning saying the application has stopped unexpectedly. Here is my code:
public void onClick(View v) {
// TODO Auto-generated method stub
try {
if (preTax !=null){
Double incomeAmount = Double.parseDouble(preTax.getText().toString());
incomeAmount =- (20 *100)/incomeAmount;
Double incomeRounded = Round(incomeAmount);
Toast.makeText(null, "Your income minus tax = "+incomeRounded, Toast.LENGTH_LONG).show();
FileOutputStream fos = openFileOutput("income", Context.MODE_PRIVATE);
fos.write("1000".getBytes());
fos.close();
}
else {
Double incomeAmount = Double.parseDouble(postTax.getText().toString());
Double incomeRounded = Round(incomeAmount);
Toast.makeText(null, "Your income is: "+ incomeRounded, Toast.LENGTH_LONG).show();
FileOutputStream fos = openFileOutput("income", Context.MODE_PRIVATE);
fos.write("1000".getBytes());
fos.close();
}
} catch (Exception e){
Toast.makeText(null, "Please fill in the catagories" + e, Toast.LENGTH_LONG).show();
}
}
This issue was happening before the fileoutstream stuff was added, so I know that that isn't the issue, but it is not clear to me what is. Program crashes regardless of whether the EditText is empty or not. Surely the try/catch should catch any errors?
Toast.makeText(null, "Please fill in the catagories" + e, Toast.LENGTH_LONG).show();
should be
Toast.makeText(v.getContext(), "Please fill in the catagories" + e, Toast.LENGTH_LONG).show();
you can't pass null in for the context, it needs to be valid.
Passing in null for the context does not exactly help. Your app in blowing up, getting caught and then blowing up again.
Related
I wrote this code to save the values of / load values to int arrayScore[10][1000] on/from a text file (ScoreFile.txt), for when the app is closed/opened.
saveData is contained in the onStop() method and loadData is contained in the onCreate() method. When I open/run/close the app, no exception is thrown. The toast says indeed "Data loaded" and "Data saved".
The values of arrayScore[][] do change during the runtime of the app, which is confirmed by these new values appearing on-screen. So during runtime everything works fine.
However, the values of the last session are not loaded when a new session is started, and after that last session ScoreFile.txt is nowhere to be found on my phone.
File scoreFile = new File("ScoreFile.txt");
public void saveData() {
try {
PrintWriter output = new PrintWriter(scoreFile);
int p, q;
for (p = 0; p <= 9; p++) {
for (q = 0; q <= 999; q++) {
output.println(arrayScore[p][q]);
}
}
} catch (Exception e){
Toast.makeText(this, "Exception savedData", Toast.LENGTH_LONG).show();
} finally {
}
Toast.makeText(this, "Data saved", Toast.LENGTH_LONG).show();
}
public void loadData() {
try {
Scanner input = new Scanner(scoreFile);
int p, q;
for (p = 0; p <= 9; p++) {
for (q = 0; q <= 999; q++) {
arrayScore[p][q] = input.nextInt();
}
}
} catch (Exception e) {
Toast.makeText(this, "Exception loadData", Toast.LENGTH_LONG).show();
} finally {
}
Toast.makeText(this, "Data loaded", Toast.LENGTH_LONG).show();
}
A few of points. First, do you have permission to write create a file at that location? Ordinarily, you'd preface the name of your file with the path to internal/external storage for your app, and check that it exists before you do anything. For example (there are many ways to write a file):
File file = new File(context.getFilesDir(), "ScoreFile.txt");
try (final FileOutputStream fos = context.openFileOutput(file, Context.MODE_PRIVATE)){
fos = openFileOutput(filename, Context.MODE_PRIVATE);
//for...
fos.write(/*...*/);
} catch (Exception e) {
e.printStackTrace();
}
Second, have you declared permission for reading and writing to the filesystem in your manifest? You may need runtime permissions for this as well on Oreo+.
Third,of course you see the "Data Saved" toast, because it runs no matter what. Replace it with throws new RuntimeException(e); in your catch and see whether your app crashes. If it does, check LogCat and add the exception to your question.
Fourth, you may need to call flush() on your PrintWriter
I just started to learn developping android and I have a (probably) basic questions, but I didn't find anything clear.
I'm trying to store data in a JSON file, well, I've understood the logic to store it, my way is:
public boolean writeFileJson(JSONObject jobj) {
try {
FileOutputStream fOut = openFileOutput(file, Context.MODE_PRIVATE);
fOut.write(jobj.toString().getBytes());
fOut.close();
Toast.makeText(getBaseContext(), "file saved", Toast.LENGTH_SHORT).show();
} catch (Exception e1) {
e1.printStackTrace();
}
return true;
}
But my problem is to read, and concretely for the first time, because the way I do it is:
public String readFileJson() {
int c;
String temp = "";
try {
FileInputStream fin = openFileInput(file);
while ((c = fin.read()) != -1) {
temp = temp + Character.toString((char) c);
}
Toast.makeText(getBaseContext(), "file read", Toast.LENGTH_SHORT).show();
} catch (Exception e2) {
}
return temp;
}
So wen I read it for the first time and I want to acces to a parameter of my JSON is obvious that any JSON Object already exist in the file.
So I try to save a first JSON Object with my parameters in onCreate() method and save it in the file, but wen I run the app, and I stop it, it returns again to execute onCreate() and deletes all data stored during the run time.
So my question is: There is any way to init only for one time the parameters of the JSON file to could access for the first time unlike it's empty???
I hope that I'd explained well!!
Thanxxxx!!!!
You can create your own flag boolean and check when you start.
Well I don't understand well why you can use a flag if the flag is set to init value in onCreate(), but I've tried a basic method: check each time if the json file is null. But it's like so basic no? Is there any ther way, or trying to understand how to use flags without reset their values?
msgjson = readFileJson();
if(msgjson == "") {
json.put("ARRAY", jsonArray);
}else{
json = new JSONObject(msgjson);
}
Thanx!!
I have a button which stores whatever text is written in the text form above it when clicked. However, the application force closes when the button is clicked. What could be the problem?
save.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String FILEOUTPUT = Day;
BufferedWriter bfw;
try {
bfw = new BufferedWriter (new FileWriter(FILEOUTPUT));
Scanner scan = new Scanner((File) editData.getText());
bfw.write(scan.nextLine());
bfw.close();
Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_SHORT);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Save error", Toast.LENGTH_SHORT);
}
}
});
It's best to first look at the reported Exception from DDMS in these cases. Can you provide the reported exception from DDMS?
Where is editData? Is it an EditText or a TextView ? You are casting a String to a File directly in that line, instead you should be creating a File object.
should be like:
Scanner scan = new Scanner(new File(editData.getText()));
I am trying to save ArrayLists(ArrayOne, ArrayTwo, and ArrayThree) of EditText's to the internal storage. As commented, it clearly shows that it attempts the save, but I never get another TOAST after that. Any help as of why it doesn't show "Save completed" or any error is appreciated.
public void save(Context c)
{
String fileName;
Toast.makeText(this, "Attempting Save", Toast.LENGTH_SHORT).show();//THIS SHOWS
if(semester.getText().toString().length() == 0)
{
Toast.makeText(c, "Please enter a filename", Toast.LENGTH_SHORT).show();
}
else
{
fileName = "test.dat";
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try
{
fos = this.openFileOutput(fileName, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(ArrayOne);
oos.writeObject(ArrayTwo);
oos.writeObject(ArrayThree);
Toast.makeText(c, "Save Completed", Toast.LENGTH_SHORT).show(); //THIS NEVER SHOWS
}
catch (FileNotFoundException e)
{
Toast.makeText(c, "Could not find " + fileName + " to save.", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (oos != null)
oos.close();
if (fos != null)
fos.close();
}
catch (Exception e)
{ /* do nothing */ }
}
}
}
The problem is that the EditText class is not serializable
If you debug and put a break point at on the printStackTrace and examine the IOException it will tell you that
catch (IOException e
{
e.printStackTrace();
}
Classes have to use "implements Serializable" in order for them to be written out as objects, which EditText does not have.
You can not extend the class and add the serializable tag either because the underlying class will still throw the exception.
I suggest you either serialize the data via your own class or save whatever you are trying to do with some other method.
I think the error is beings swallowed in your first Try block because you're only catching FileNotFound and IOException - just for debugging purposes you could catch the generic Exception and printout the stacktrace.
If it also helps this is what I do:
java.io.File file = new java.io.File("/sdcard/mystorage/ArrayOne.bin");
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
out.writeObject(obj);
out.close();
Best
-serkan
If nothing shows after the "Attempting save" you´re getting some exception in this block
catch (IOException e)
{
e.printStackTrace();
}
And you´re not viewing it in any Toast. Also you can be here in this way doing nothing with your exception:
catch (Exception e)
{ /* do nothing */ }
Instead of toasting your messages.. try to use LogCat for debbugging, is easy to use and also you don't need to put toast code in your code. Tell me how is going.
I noticed that a toast isn't displayed when it's used inside a catch block.
Does anyone know how to show toasts when catching exceptions? An Example:
try {
// try to open a file
} catch (FileNotFoundException e) {
Toast.makeText(this, R.string.txt_file_not_found, Toast.LENGTH_LONG);
return; // cancel processing
}
Should be like this:
Toast toast = Toast.makeText(this, R.string.txt_file_not_found, Toast.LENGTH_LONG);
toast.show();
Yes, I put it right behind the existing line:
Toast.makeText(this, R.string.txt_file_not_found, Toast.LENGTH_LONG).show();