Try catch does not work (always does catch code) - java

If anyone can help me I would be grateful! It should be converted the three EditText variables into strings and then integers. I added the exception because without it, the program crashed on startup. I'm not sure whether the problem is in the conversion of the variables, in my try catch code, or in both. Please help!
package boston.project;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class TheBostonProjectActivity extends Activity {
public EditText aed, bed, ced;
public TextView dtv;
public int a, b, c;
public Button solve;
public double dis;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
aed = (EditText)(findViewById(R.id.etA));
try {
a = Integer.parseInt(aed.getText().toString());
} catch (NumberFormatException e) {
a = 0;
}
bed = (EditText)(findViewById(R.id.etB));
try {
b = Integer.parseInt(bed.getText().toString());
} catch (NumberFormatException e) {
b = 0;
}
ced = (EditText)(findViewById(R.id.etC));
try {
c = Integer.parseInt(ced.getText().toString());
} catch (NumberFormatException e) {
c = 0;
}
solve = (Button)(findViewById(R.id.bsolve));
solve.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
dis = (b*b)-(4*a*c);
dtv = (TextView)findViewById(R.id.tvdis);
dtv.setText("Discriminant:" + dis);
}
});
}
}

You are trying to get the text from EditTexts just after you created them (by calling setContentView). They are all empty - contain no text. And since
Integer.parseInt("");
Throws an exception, all your catch blocks are executed (and that means, that they actually work, not the contrary).

Related

button not working in android basic apo I am trying to create

I am having an issue with my first app. When I click on "Submit" it is meant to create a textfile with the values that the user has entered however it is not creating it. I am not sure what the issue is.
I would also like to know if there is a better way of storing the data entered by the user to make is useable eventually in a excel spread sheet. Or just use plain text file to make it easy?
package com.example.mybodyrecord;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
String myBodyRecord = "My_Body_Record.txt";
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
File file; // declare here and initialize inside onCreate.
Button button;
EditText weightInput;
EditText ketoneBloodInput;
EditText ketoneUrineInput;
EditText bloodPressureInput;
EditText bloodSugarInput;
String weight;
String ketoneBlood;
String ketoneUrine;
String bloodPressure;
String bloodSugar;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setting where to get the data from, ie what fields
weightInput = findViewById(R.id.weight);
ketoneBloodInput = findViewById(R.id.ketoneblood);
ketoneUrineInput = findViewById(R.id.ketoneurine);
bloodPressureInput = findViewById(R.id.bp);
bloodSugarInput = findViewById(R.id.bslvl);
button = findViewById(R.id.submit);
//activity has a context now you can use getApplicationContext or this
file = new File(this.getFilesDir(),myBodyRecord);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FileOutputStream fos = null;
//Taking input from the fields
weight = weightInput.getText().toString() +"kg";
ketoneBlood = ketoneBloodInput.getText().toString() +"mmol/L";
ketoneUrine = ketoneUrineInput.getText().toString();
bloodPressure = bloodPressureInput.getText().toString() +"mmHg";
bloodSugar = bloodSugarInput.getText().toString() +"mmol/L";
//Save to the file, with the date and time
if (file.exists()) {
try {
fos = openFileOutput(myBodyRecord, getApplicationContext().MODE_APPEND);
fos.write("\n\r".getBytes());
fos.write(formatter.format(date).getBytes());
fos.write(weight.getBytes());
fos.write(ketoneBlood.getBytes());
fos.write(ketoneUrine.getBytes());
fos.write(bloodPressure.getBytes());
fos.write(bloodSugar.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
else {
try {
fos = openFileOutput(myBodyRecord, getApplicationContext().MODE_PRIVATE);
fos.write("\n\r".getBytes());
fos.write(formatter.format(date).getBytes());
fos.write(weight.getBytes());
fos.write(ketoneBlood.getBytes());
fos.write(ketoneUrine.getBytes());
fos.write(bloodPressure.getBytes());
fos.write(bloodSugar.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
}
}
Collins
The question how to read/write to text files in android is already answered in this thread:
How can I read a text file in Android?
However, tis is not what you want in android.
First, you should be familiar with the concept of application and service.
Then, to solve your problem:
- For a smaller amount of data (eg. settings) you might use SharedPreferences.
- For more data (eg. records) the recommended approach is a ContentProvider with SQLite database.

Android - after notifyDataSetChanged ListView remains blank

It's hours I search for something, but it doesn't seem to help.. Android Studio doesn't launch any error, but the screen remains blank. Why?
package org.newapp;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import saxrssreader.*;
public class MainActivity extends Activity {
private ArrayAdapter<RssItem> rssItemsArrayAdapter;
ListView codeLearnLessons;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RssItem[] rssItems = new RssItem[]{};
rssItemsArrayAdapter = new ArrayAdapter<RssItem>(this, android.R.layout.simple_list_item_1, rssItems);
new WebCall().execute(rssItems);
codeLearnLessons = (ListView)findViewById(R.id.listView1);
codeLearnLessons.setAdapter(rssItemsArrayAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private class WebCall extends AsyncTask<RssItem, Void, Void> {
#Override
protected Void doInBackground(RssItem... items) {
URL url = null;
try {
url = new URL("http://www.somewpsite.com/feed");
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
ArrayList<RssItem> listItems = RssReader.read(url).getRssItems();
items = listItems.toArray(new RssItem[listItems.size()]);
final int l = items.length;
runOnUiThread(new Runnable() {
#Override
public void run() {
codeLearnLessons.invalidateViews();
rssItemsArrayAdapter.notifyDataSetChanged();
Log.i("rec", "rec" + l);
}
});
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
/*ProgressDialog mDialog = new ProgressDialog(MainActivity.this);
mDialog.setMessage("Please wait...");
mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDialog.setIndeterminate(true);
mDialog.setCancelable(false);
mDialog.show();*/
}
}
}
The issue is that your using a ArrayList which only has scope inside of the AsyncTask.doInBackground() method. Since it is not given to the adapter, the notifyDataSetChanged() does nothing. You'll need to replace the existing array like this:
rssItemsArrayAdapter.clear();
rssItemsArrayAdapter.addAll(listItems);
rssItemsArrayAdapter.notifyDataSetChanged();
Having said that, you also really need to change your use of AsyncTask. There's no need to call runOnUiThread() from within your doInBackground() as the AsyncTask will automatically run its onPostExecute() on the UI thread. Have your doInBackground() method return your new ArrayList<RssItem> and create an onPostExecute() override method which adjusts the adapter as shown above.
You are passing your items to the AsyncTask but in the AsyncTask you declare them new with the content of your result. You never pass the items to your ArrayAdapter back. Make them a property of your class instance.
Edit - Example:
rssItemsArrayAdapter.clear();
rssItemsArrayAdapter.addAll(items);
and afterwards
rssItemsArrayAdapter.notifyDataSetChanged();

After 'takePicture' call, 'onPictureTaken' response is dependent on location in app...why?

I'm trying to build an app which will periodically call the Camera to take a picture and save it.
My problem is that unless I put the 'takePictuce' call in the 'onCreate' the response to 'takePicture' (onPictureTaken) is never called.
I've broken down the app as simply as possible to illustrate.
if a class to handle the camera is partially defined as:
public class CameraHandler {
private Camera mCamera;
public CameraHandler(){
mCamera = Camera.open();
mCamera.setPreviewTexture(new SurfaceTexture(10));
mCamera.startPreview();
mCamera.takePicture(null, null, mPicture);
}
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) { }
}
};
Then when I put the following code into MainActivity.java, 'onPictureTaken' IS called when CameraHandler is instantiated.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CameraHandler cameraHandler = new CameraHandler();
}
However, putting the call to instantiate CameraHandler in a click event in the MainActivity.java will NOT call 'onPictureTaken' in response to the takePicture call.
(This snippet is located in MainACtivity.java)
public void onClickListener(View view){
CameraHandler cameraHandler = new CameraHandler();
}
So why is this occurring, and how can I get the call to take a picture in the class where it belongs and not in the 'main' of the program?
All help welcome
Finally figured out how to set the phone to take timed pics without any screen display.
There were 2 main issues I struggled with. First, I wanted to take the pics without displaying to screen. Along those lines, I found an example where they used :
mCamera.setPreviewTexture(new SurfaceTexture(10));
and nothing showed on the screen when using this preview method. It appears that some sort of preview is required. Another method was to set the preview to 1 pixel. This method had examples online which appeared to work as well, but I did not try it.
The second and bigger problem had to do with 'onPictureTaken' method. This method processes your picture after the 'takePicture' call.
It seemed that no matter what looping method I used, or where in the code the call to 'takePicture' was located, all of the 'onPictureTaken' methods were queued up and called one after another once the parent of the 'takePicture' caller ended.
Although the picture data processed by onPictureTaken were in a proper time sequence, I could see that having several hundred pics stored and waiting to process could cause problems, and a method needed to be found where on pic was processed and stored before the next pic was taken.
Along those lines, I stumbled upon the AlarmManager and coupled that with the BroadcastReceiver and Future classes to solve the problem.
What I've done is set the alarmManger to go off at a set time or time frequency. The BroadcaseReceiver captures this call & in turn calls a method which creates
a thread where a 'Future' object makes the call to take a picture.
'Future' object is nice, because it will wait for the physical camera to take the picture (takePicture) and then process it (onPictureTaken). This all occurs in one thread, then terminates. So no queuing of pics to process and each picture sequence is handled separately.
Code is contained below. Note that some of the default 'Overrides' have been left out to save space. Also, the visible screen was basically a button which captured the click event...very basic.
MainActivity.java:
package myTest.com.test;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MainActivity extends Activity {
CameraHandler cameraHandler;
public BroadcastReceiver br;
public PendingIntent pi;
public AlarmManager am;
final static private long LOOPTIME = 20000;
private static final ExecutorService threadpool = Executors.newFixedThreadPool(3);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setup();
}
private void setup() {
try{
cameraHandler = new CameraHandler();
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
//Toast.makeText(c, "Taking a pic!", Toast.LENGTH_LONG).show();
TryAThread();
}
};
registerReceiver(br, new IntentFilter("com.timedActivity.activity") );
pi = PendingIntent.getBroadcast(this, 0, new Intent("com.timedActivity.activity"), 0);
am = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
catch (Exception e){ }
}
private void TryAThread() {
try{
CameraCaller cameraCaller = new CameraCaller(cameraHandler);
Future future = threadpool.submit(cameraCaller);
while (!future.isDone()) {
try {
Thread.sleep(5000);
} catch (Exception ex) { }
}
}
catch (Exception e){ }
}
#Override
protected void onDestroy() {
am.cancel(pi);
unregisterReceiver(br);
super.onDestroy();
}
public void onClickListener(View view){
try{
am.setRepeating(am.ELAPSED_REALTIME,SystemClock.elapsedRealtime(), LOOPTIME, pi);
}
catch (Exception e){ }
}
}
CameraCaller.java:.
package myTest.com.test;
import java.util.concurrent.Callable;
public class CameraCaller implements Callable {
private CameraHandler cameraHandler;
public CameraCaller(CameraHandler ch){
cameraHandler = ch;
}
#Override
public Object call() throws Exception {
cameraHandler.takeAPic();
return true;
}
}
CameraHandler.java:.
package myTest.com.test;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Environment;
import android.util.Log;
import junit.runner.Version;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CameraHandler implements Camera.PictureCallback{
private Camera mCamera;
public CameraHandler(){
}
public Boolean takeAPic(){
try{
if (mCamera == null){
mCamera = Camera.open();
mCamera.enableShutterSound(false);
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
}
catch (IOException e1) {Log.e(Version.id(), e1.getMessage());
}
}
mCamera.startPreview();
mCamera.takePicture(null, null, this);
}
catch (Exception ex){ }
return true;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) { }
try {
Thread.sleep(2000);
}catch (Exception ex){}
}
public static File getOutputMediaFile() {
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File mediaStorageDir = new File(file, "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
}

Limiting what jsoup retrieves

I'm Having fun learning to use jsoup and have successfully retrieved and displayed data from a website, but now I would like some further guidance on it if anyone can help.
Using the code below returns all the table rows 30+, How can I retrieve only say the first 10 of those rows?
also
When returning those rows and the data on them there are gaps/spaces in the row between the data, the spaces between rows are fine but its the spaces within the row that I want to get rid of, how can I omit those spaces/gaps?
My code so far...
package com.example.shiftzer;
import java.io.IOException;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity{
TextView textView1;
ListView shippingList;
public static final String APP_PREFERENCES = "AppPrefs";
SharedPreferences settings;
SharedPreferences.Editor prefEditor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//rest of the code
textView1 = (TextView)findViewById(R.id.textView1);
shippingList = (ListView) findViewById(R.id.listView1);
settings = getSharedPreferences(APP_PREFERENCES, MODE_PRIVATE);
prefEditor = settings.edit();
new VTSTask().execute();//starts AsyncTask in private class VTSTask to get shipping info
}
private class VTSTask extends AsyncTask<Void, Void, ArrayList<String>> {
ArrayList<String> arr_shipping=new ArrayList<String>();
/**
* #param args
*/
#Override
protected ArrayList<String> doInBackground(Void... params) {
Document doc;
String shippingList;
try {
doc = Jsoup.connect("https://vts.mhpa.co.uk/main_movelistb.asp").get();
Elements tableRows = doc.select("table.dynlist tr td");
for (Element element : tableRows) {
shippingList = element.text();
arr_shipping.add(shippingList);// add value to ArrayList
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return arr_shipping;//<< Return ArrayList from here
}
#Override
protected void onPostExecute(ArrayList<String> result) {
//TextView tVShipping= (TextView)findViewById(R.id.textView2);
shippingList = (ListView) findViewById(R.id.listView1);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1,
android.R.id.text1);
for (String shipping_result : result)
{
adapter.add(shipping_result);
}
// Assign adapter to ListView
shippingList.setAdapter(adapter);
}
}
}
Thank you.
EDIT:
try {
doc = Jsoup.connect("https://vts.mhpa.co.uk/main_movelistb.asp").get();
Elements tableRows = doc.select("table.dynlist tr td");
tableRows.size();
for(int i = 0; i < 10; i++){
tableRows.get(i);
shippingList = tableRows.get(i).text() +"\n";
arr_shipping.add(shippingList);// add value to ArrayList
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return arr_shipping;//<< return ArrayList from here
}
Instead of doing for(Element element:tableRows), Elements has a size method.
So, you should be able to just do some validation with the size, and then simply
for(int i = 0; i < 10; i++){
tableRows.get(i);
}
to get 10 of them.
As for the spaces, before you store them in your arraylist just use regular expressions and remove the spaces.
http://www.vogella.com/articles/JavaRegularExpressions/article.html
Try This
import java.io.IOException;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class test
{
static ArrayList<String> arr_shipping=new ArrayList<String>();
public static void main(String args[]) throws IOException
{
try {
Document doc = Jsoup.connect("https://vts.mhpa.co.uk/main_movelistb.asp").timeout(600000).get();
Elements tableRows = doc.select("table.dynlist tr:not(:eq(0))");
tableRows.size();
for(int i = 0; i < 10; i++){
//tableRows.get(i);
String shippingList =tableRows.get(i).text() +"\n";
arr_shipping.add(shippingList);// add value to ArrayList
System.out.println(shippingList);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// return arr_shipping;//<< return ArrayList from here
}
}
Try this
doc.select("table.dynlist tr:lt(10)");
to limt the results.
Reference

removing delay in sending string through tcp/ip

My project has a light switch which has an IP address and port and accepts strings to control. I am trying to create an application to switch this on and off.
My code works, however after the first click, there is a significant delay between the next click and the switch actually switching.
I have a button for on and off. main.java:
package com.android.lswitch;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class lightswitch extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Handle swon button
Button swon = (Button) findViewById(R.id.swon);
swon.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sw(true);
}
});
// Handle swoff button
Button swoff = (Button) findViewById(R.id.swoff);
swoff.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sw(false);
}
});
}
private void sw(boolean swstate) {
if (swstate == true) {
Thread swonThread = new Thread(new swon());
swonThread.start();
}
if (swstate == false) {
Thread swoffThread = new Thread(new swoff());
swoffThread.start();
}
}
}
and button on java:
package com.android.lswitch;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class swon implements Runnable {
public static final String SERVERIP = "10.0.0.25";
public static final int SERVERPORT = 4000;
public void run(){
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Socket socket = new Socket(serverAddr, SERVERPORT);
String swon = "A55A6B0550000000FFFBDE0030C8";
String but0 = "A55A6B0500000000FFFBDE002066";
PrintWriter out = new PrintWriter( new BufferedWriter
( new OutputStreamWriter(socket.getOutputStream())),true);
out.println(swon);
out.println(but0);
socket.close();
} catch(Exception e) {
}
finally {
}
}
}
button off is virtually the same but with different strings.
I'm new to android coding (and java coding) so can't see where the hold up is. Do I need to flush the strings somewhere? or is there a better way of tackling this project?
Cheers
PrintWriter may be buffered, so you should definitely flush() it before issuing any close() operation on the underlying socket.
It is also preferable to call PrintWriter.close() instead of Socket.close(), e.g., in a finally block, such as:
PrintWriter out = new PrintWriter( new BufferedWriter
( new OutputStreamWriter(socket.getOutputStream())),true);
try {
out.println(swon);
out.println(but0);
out.flush();
} finally {
out.close();
}

Categories