No TextViews Created - android

MainActivity.java
public class MainActivity extends AppCompatActivity {
double MOA;
TextView turretClicks;
boolean noMOA;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
turretClicks = (TextView) findViewById(R.id.turretClicks);
// Create an anonymous implementation of OnClickListener
View.OnClickListener btnClickCalc = new View.OnClickListener() {
#Override
public void onClick(View v) {
double clicks = (MOA * 4);
String toText = Double.toString(clicks);
turretClicks.setText(toText);
EditText range = (EditText) findViewById(R.id.rangeEntry);
String stringRange = range.getText().toString();
int finalRange = Integer.parseInt(stringRange);
if (finalRange <= 200) {
MOA = 0;
}
if (finalRange > 200 && finalRange <= 225) {
MOA = .5;
}
if (finalRange > 225 && finalRange <= 250) {
MOA = 1;
}
if (finalRange > 250 && finalRange <= 275) {
MOA = 1.65;
}
if (finalRange > 275 && finalRange <= 300) {
MOA = 2.25;
}
if (finalRange > 300 && finalRange <= 325) {
MOA = 2.8;
}
if (finalRange > 325 && finalRange <= 350) {
MOA = 3.5;
}
if (finalRange > 350 && finalRange <= 375) {
MOA = 4.0;
}
if (finalRange > 375 && finalRange <= 400) {
MOA = 4.75;
}
if (finalRange > 400 && finalRange <= 425) {
MOA = 5.50;
}
if (finalRange > 425 && finalRange <= 450) {
MOA = 6.25;
}
if (finalRange > 450 && finalRange <= 475) {
MOA = 7.0;
}
if (finalRange > 475 && finalRange <= 500) {
MOA = 7.5;
}
if (finalRange > 500 && finalRange <= 525) {
MOA = 8.25;
}
if (finalRange > 525 && finalRange <= 550) {
MOA = 9.0;
}
if (finalRange > 550 && finalRange <= 575) {
MOA = 9.75;
}
if (finalRange > 575 && finalRange <= 600) {
MOA = 10.5;
}
if (finalRange > 600 && finalRange <= 625) {
MOA = 11.5;
}
if (finalRange > 625 && finalRange <= 650) {
MOA = 12.25;
}
if (finalRange > 650 && finalRange <= 675) {
MOA = 13;
}
if (finalRange > 675 && finalRange <= 700) {
MOA = 14;
}
if (finalRange > 700) {
noMOA = true;
}
}
};
// Capture our button from layout
Button button = (Button) findViewById(R.id.btnClickCalc);
// Register the onClick listener with the implementation above
button.setOnClickListener(btnClickCalc);
final View.OnClickListener btnRecordRange = new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText range = (EditText) findViewById(R.id.rangeEntry);
final String recordableClicks = turretClicks.toString();
final String recordableRange = range.toString();
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("recordings.csv", Context.MODE_PRIVATE));
outputStreamWriter.write("Clicks" + " " + recordableClicks + "," + " " + "#Range" + recordableRange + "\n");
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
Toast.makeText(MainActivity.this, " Clicks # Range" + "\n" + "Successfully Recorded", Toast.LENGTH_SHORT).show();
}
};
// Capture our button from layout
Button recordRange = (Button) findViewById(R.id.btnRecordRange);
// Register the onClick listener with the implementation above
recordRange.setOnClickListener(btnRecordRange);
// Create an anonymous implementation of OnClickListener
final View.OnClickListener btnToRecorded = new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,RangeRecords.class));
}
};
// Capture our button from layout
Button showRecords = (Button) findViewById(R.id.btnToRecorded);
// Register the onClick listener with the implementation above
showRecords.setOnClickListener(btnToRecorded);
// Create an anonymous implementation of OnClickListener
}
}
RangeRecords.java
public class RangeRecords extends ListActivity {
public static TextView ListItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_recorded_ranges);
readFromFile("recordings.csv");
}
public String readFromFile(String fname) {
List<String> rangeList = new ArrayList();
String ret = "";
try {
InputStream inputStream = openFileInput(fname);
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString;
StringBuilder stringBuilder = new StringBuilder();
while ((receiveString = bufferedReader.readLine()) != null) {
stringBuilder.append(receiveString);
}
rangeList.add(stringBuilder.toString());
View linearLayout = findViewById(R.id.linLay);
for (int i = 0; i < rangeList.size(); i++) {
TextView value = new TextView(this);
value.setText(i);
value.setId(i);
value.setTextSize(20);
value.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
((LinearLayout) linearLayout).addView(value);
}
}
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
}
content_recorded_ranges.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/linLay">
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
When I run this program on my phone, it works perfectly on the first activity. When I click the button to switch to the second activity, which should be displaying in TextViews the data I've recorded, the screen is just white. I can see the Android bar on the top where I see my service and battery life, etc, but it is even kinda blurred out a bit as if something is laying over the top of it.
The only reason I have the ListView is because the compiler demanded I have it in the code. I don't want/need it, but apparently the compiler thinks I do.
What am I doing wrong here? I want to display the recorded data on the second activity... so, we calculate the clicks on the turret, shoot the rifle, and record that data to a file if it's a good shot, then all we should have to do is come back to the second activity and view the data we've recorded from all our previous shots at varying ranges.
Anyone? Been at this all day.
Thanks!
EDIT
This is the code now:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_recorded_ranges"
tools:context="lol2dubs.stevemoa.recorded_ranges"
android:background="#fefefe">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/linLay">
</LinearLayout>
</RelativeLayout>
RangeRecords.java
public class RangeRecords extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_recorded_ranges);
readFromFile("recordings.csv");
}
public String readFromFile(String fname) {
List<String> rangeList = new ArrayList();
String ret = "";
try {
InputStream inputStream = openFileInput(fname);
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString;
StringBuilder stringBuilder = new StringBuilder();
while ((receiveString = bufferedReader.readLine()) != null) {
stringBuilder.append(receiveString);
}
rangeList.add(stringBuilder.toString());
View linearLayout = findViewById(R.id.linLay);
for (int i = 0; i < rangeList.size(); i++) {
TextView value = new TextView(this);
value.setText(i);
value.setId(i);
value.setTextSize(20);
value.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
((LinearLayout) linearLayout).addView(value);
}
}
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
}
Same thing is still occurring after removing the extends ListActivity and the ListView from the XML.

The ListView is demanded because you are extending ListActivity. Also, the ListView blocks your TextView so you couldn't see it.
However, you should use stick in using ListView since you are displaying multiple textviews with a dynamic number. See this for a tutorial.
If you don't want to use it then change
public class RangeRecords extends ListActivity
to
public class RangeRecords extends AppCompatActivity
Remove ListView on your layout
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="#+id/linLay">
</LinearLayout>

Related

java: Convert Location into String and back

For android Room, i need a type converter to save Location objects. Converting Locations to String is rather simple, e.g.:
public static String locationStringFromLocation(final Location location) {
if (location==null) return "Location was null";
return Location.convert(location.getLatitude(), Location.FORMAT_DEGREES) + " " + Location.convert(location.getLongitude(), Location.FORMAT_DEGREES);
}
But the other way around seems less obvious. I could append all the properties and separate them with a delimiter, but that seems not quite elegant. Any ideas would be appreciated.
My current workaround is to just save latitude and longitude, but I'd prefer to have the object.
public static Location locationFromString(String location){
if (location != null && (location.contains(","))) {
Location result = new Location("Generated_location");
String[] locationStrings = location.split(",");
if (locationStrings.length == 2) {
result.setLatitude(Double.parseDouble(locationStrings[0]));
result.setLongitude((Double.parseDouble(locationStrings[1])));
return result;
} else { return null; }
} else return null;
}
static Location parseLocationString(String locString){
if(locString != null && locString.contains("Location")) {
Location location = new Location("");
String rep = locString.replace("Location", "")
.replace("[", "")
.replace("]", "");
String[] k = rep.split(" ");
for (int part = 0; part < k.length; part++) {
String string = k[part];
if(part == 0)location.setProvider(string);
else if (part == 1){
String[] latlng = string.split(",");
if(latlng.length > 1){
location.setLatitude(Double.parseDouble(latlng[0]));
location.setLongitude(Double.parseDouble(latlng[1]));
}
}
else if (part > 1){
String[] locationDetails = string.split("=");
if (locationDetails.length > 1){
String locationKey = locationDetails[0];
String locationValue = locationDetails[1];
if (locationKey.contains("hAcc")) {
if (!locationValue.contains("?"))
location.setAccuracy((float)Float.parseFloat(locationValue));
}else if (locationKey.contains("et")){
if( !locationValue.contains("?") )
if(Build.VERSION.SDK_INT >= 17) {
if(locationValue.contains("+")) {
long days = 0, hours, min, sec, mill;
//separate string value
String nmbr = locationValue.split("\\+")[1];
String[] hr;
//isolate each value
String[] d = nmbr.split("d");
if(d.length > 1){
days = Long.parseLong(d[0]);
}
if(d.length > 1)
hr = d[1].split("h");
else
hr = nmbr.split("h");
if(hr.length > 1) {
hours = Long.parseLong(hr[0]);
}else hours = 0;
if(days > 0)
hours += 24*days;
String[] m;
if(hr.length > 1)
m = hr[1].split("m");
else
m = hr[0].split("m");
if(m.length > 1) {
if(m[0].length() > 0)
try {
min = Long.parseLong(m[0]);
}catch(NumberFormatException e){
min = 0;
}
else min = 0;
} else min= 0;
String[] s = m[0].split("s");
if(s.length > 1) {
sec = Long.parseLong(s[0]);
}else sec = 0;
if(min != 0 || hours != 0) {
String[] ms = s[0].split("ms");
if (ms.length >= 0 && !ms[0].contains("s")) {
mill = Long.parseLong(ms[0]);
} else mill = 0;
}else{
String ms = s[1];
if (ms.length() >= 0 && !ms.contains("s")) {
mill = Long.parseLong(ms);
} else mill = 0;
}
long millInNano = 1000000;
long nano = mill * millInNano;
nano += (sec * 1000) * millInNano;
nano += ((min * 60) * 1000) * millInNano;
nano += (((hours * 60) * 60) * 1000) * millInNano;
location.setElapsedRealtimeNanos(nano);
}
}
}else if (locationKey.contains("vel")) {
if (!locationValue.contains("?"))
location.setSpeed(Float.parseFloat(locationValue));
}else if (locationKey.contains("vAcc")) {
if (!locationValue.contains("?"))
if(Build.VERSION.SDK_INT >= 26)
location.setVerticalAccuracyMeters(Float.parseFloat(locationValue));
}else if (locationKey.contains("sAcc")) {
if (!locationValue.contains("?"))
if(Build.VERSION.SDK_INT >= 26)
location.setSpeedAccuracyMetersPerSecond(Float.parseFloat(locationValue));
}else if (locationKey.contains("bAcc")) {
if (!locationValue.contains("?"))
if(Build.VERSION.SDK_INT >= 26)
location.setBearingAccuracyDegrees(Float.parseFloat(locationValue));
}
}
}
}
return location;
}else{
return null;
}
}

Reading temperature through DHT11 using Android Things

I am using Raspberry pi3 and DHT11 sensor for temperature monitoring project.
I have following pin positions
VCC to pin no : 2
Ground to pin no : 6
Output to GPIO : BCM22 i.e pin no 15
Code that I have used:
public class WeatherStationActivity extends Activity {
private Handler mHandler = new Handler();
private TextView mTxtStatus;
private PeripheralManagerService service = new PeripheralManagerService();
private Gpio tempGpio;
private int i = 0;
int[] dht11_dat = {0, 0, 0, 0, 0};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("Weather station", "Started Weather Station");
setContentView(R.layout.activity_main);
mTxtStatus = (TextView) findViewById(R.id.txtStatus);
try {
tempGpio = service.openGpio("BCM22");
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (i == 10) {
handler.removeCallbacks(this);
} else {
getTemp();
handler.postDelayed(this, 5000);
}
i++;
}
}, 5000);
} catch (Exception e) {
e.printStackTrace();
}
}
private void getTemp() {
boolean laststate = false;
try {
laststate = tempGpio.getValue();
} catch (IOException e) {
e.printStackTrace();
}
int j = 0;
final int MAXTIMINGS = 85;
dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
try {
tempGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
// tempGpio.setActiveType(Gpio.ACTIVE_LOW);
tempGpio.setValue(false);
// Thread.sleep(18);
TimeUnit.MILLISECONDS.sleep(18);
// tempGpio.setActiveType(Gpio.ACTIVE_HIGH);
// tempGpio.setActiveType(Gpio.ACTIVE_HIGH);
tempGpio.setValue(true);
TimeUnit.MICROSECONDS.sleep(40);
tempGpio.setDirection(Gpio.DIRECTION_IN);
/* tempGpio.setActiveType(Gpio.ACTIVE_HIGH);
tempGpio.setValue(true);*/
// tempGpio.setValue(true);
StringBuilder value = new StringBuilder();
for (int i = 0; i < MAXTIMINGS; i++) {
int counter = 0;
while (tempGpio.getValue() == laststate) {
counter++;
TimeUnit.MICROSECONDS.sleep(1);
if (counter == 255) {
break;
}
}
laststate = tempGpio.getValue();
mTxtStatus.append("\nLast State of Sensor " + laststate);
if (counter == 255) {
break;
}
//* ignore first 3 transitions *//*
if ((i >= 4) && (i % 2 == 0)) {
//* shove each bit into the storage bytes *//*
dht11_dat[j / 8] <<= 1;
if (counter > 16) {
dht11_dat[j / 8] |= 1;
}
j++;
}
}
// check we read 40 bits (8bit x 5 ) + verify checksum in the last
// byte
if ((j >= 40) && checkParity()) {
value.append(dht11_dat[2]).append(".").append(dht11_dat[3]);
Log.i("Logger", "temperature value readed: " + value.toString());
mTxtStatus.append("\nTemp " + value.toString());
} else {
mTxtStatus.append("\nNothing is working ");
Log.i("Logger", "Nothing is working ");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean checkParity() {
return dht11_dat[4] == (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3] & 0xFF);
}
}
Above code is giving me "Nothing is working" as output.
Any suggestion where I might be doing wrong?
You can't read data from DHT11 using Raspberry Pi 3 with Android Things because duration of DHT11 response pulses is from 26-28 us to 70 us, but max frequency of RP3 with AT GPIO is around 3kHz, which means around 300 us pulse duration. Take a look at answers to this question.

Peak between different Peak values

Am trying to get these two peaks once I read from my text file. I have defined two string to compare two value in order to find the peak, but I think my if(y_0>MP) statement is not correct one to find the two peak. What should I do please.
//Read data.
Recall = (Button) findViewById(R.id.Recall);
Recall.setOnClickListener(new View.OnClickListener() {
StringBuilder stringBuilder;
#Override
public void onClick(View v) {
//readTextFile(this, R.raw.books);
stringBuilder = new StringBuilder();
String line;
try {
FileInputStream fIn = new FileInputStream(file);
BufferedReader bufferedreader = new BufferedReader(new
InputStreamReader(fIn));
while ((line = bufferedreader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(" ");
stringBuilder.length();
}
bufferedreader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String a;
a = String.valueOf(stringBuilder);
String dataArray[];
int t;
dataArray = a.split(" ");
int MP = 0;
for (t = 1; t < dataArray.length - 1; t++) {
float y_0 = Float.valueOf(dataArray[t]);
float y_1 = Float.valueOf(dataArray[t + 1]);
float y_2 = Float.valueOf(dataArray[t - 1]);
float left = y_0 - y_2;
float right = y_1 - y_0;
if (left > 0 && right < 0) {
if (y_0 > MP) {
MP = (int) y_0;
} else {
MP = (int) y_0;
}
Toast.makeText(getApplicationContext(), "Number of peaks
founds\n: " + MP, Toast.LENGTH_SHORT).show();
}
}
DataAlert alert = new DataAlert();
alert.show(getFragmentManager(), "DataAlert");
}
});
Your suspicions about the if (y_0 > MP) line are correct. If you want to make a toast showing the number of peaks found, then you either need to keep a list of the peaks, or a counter, and add to it every time a peak is found. Then, after the for-loop has finished searching for peaks, you would make a toast saying how many peaks were found.
List<Integer> peaks = new ArrayList<>();
for (t = 1; t < dataArray.length - 1; t++) {
float y_0 = Float.valueOf(dataArray[t]);
float y_1 = Float.valueOf(dataArray[t + 1]);
float y_2 = Float.valueOf(dataArray[t - 1]);
float left = y_0 - y_2;
float right = y_1 - y_0;
if (left > 0 && right < 0)
peaks.add(t);
}
Toast.makeText(getApplicationContext(), "Number of peaks founds\n: " + peaks.size(), Toast.LENGTH_SHORT).show();
for (Integer peak : peaks) {
float value = Float.valueOf(dataArray[peak]);
Toast.makeText(getApplicationContext(), "Peak of height " + value + " found at index " + peak, Toast.LENGTH_SHORT).show();
}
For future reference, this section of code
if (y_0 > MP) {
MP = (int) y_0;
} else {
MP = (int) y_0;
}
Is equivalent to this:
MP = (int) y_0;
You assign MP = (int) y_0 regardless of whether the if statement is true or false.

Lag on Game Generation

I have this game and it truly requires a load of item generation so I have it all being handled in an AsyncTask however this class is taking an extremely long time to execute sometimes while other times it take miliseconds... What is causing this to sometimes be fast and sometimes slow?
public class handleStuff extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... arg0) {
Random r = new Random();
if(r.nextInt(200) == 0 && clouds.size() <= 6)
{
Cloud c = new Cloud(SCREEN_WIDTH, SCREEN_HEIGHT, cloudBM1.getWidth(), cloudBM2.getHeight());
clouds.add(c);
}
for(int i = clouds.size() - 1; i > -1; i--)
{
Cloud tempC = clouds.get(i);
if(tempC.x <= 0 - cloudBM1.getWidth() && tempC.dir == 0)
clouds.remove(i);
if(tempC.x >= SCREEN_WIDTH && tempC.dir == 1)
clouds.remove(i);
}
if(System.currentTimeMillis() - lastESpawn >= 750)
{
Enemy x = new Enemy(SCREEN_WIDTH, SCREEN_HEIGHT, enemy.getWidth(), enemy.getHeight());
enemies.add(x);
lastESpawn = System.currentTimeMillis();
}
for(int i = enemies.size() - 1; i > -1; i--)
{
Enemy tempE = enemies.get(i);
if(tempE.x <= 0 - enemy.getWidth())
enemies.remove(tempE);
}
for(int i = 0; i < enemies.size(); i++)
{
Enemy tempE = enemies.get(i);
if(System.currentTimeMillis() - tempE.lastBulletSpawn >= 800 && tempE.x <= SCREEN_WIDTH)
{
EnemyBullet eb = new EnemyBullet(tempE.x, tempE.y, enemyBullet.getWidth(), enemyBullet.getHeight(), enemy.getWidth(), enemy.getHeight());
enemyBullets.add(eb);
tempE.lastBulletSpawn = System.currentTimeMillis();
}
}
for(int i = bullets.size() - 1; i > -1; i--)
{
Bullet tempB = bullets.get(i);
if(tempB.x >= SCREEN_WIDTH)
bullets.remove(i);
}
for(int i = enemyBullets.size() - 1; i > -1; i--)
{
EnemyBullet tempEB = enemyBullets.get(i);
if(tempEB.x <= 0 - enemyBullet.getWidth())
enemyBullets.remove(i);
}
if(System.currentTimeMillis() - lastPBSpawn >= 400)
{
Bullet b = new Bullet(x, y, player.getWidth(), player.getHeight());
bullets.add(b);
lastPBSpawn = System.currentTimeMillis();
}
for(int i = explosions.size() - 1; i > -1; i--)
{
Explosion tempEx = explosions.get(i);
tempEx.update();
if(tempEx.duration <= 0)
explosions.remove(i);
}
initial_load = true;
return null;
}
}
Well, nobody likes debugging and I bet no one will make the tests themselves. That is up to you. So what you do is you log how long an operation takes. That is very easy. Some example code.
public class HandleStuffJob extends AsyncTask<String, Integer, String> {
private long mTime;
#Override
protected String doInBackground(String... params) {
startLogging();
try {
doSomeFancyStuff();
}
catch (InterruptedException e) {
e.printStackTrace();
}
stopLogging();
return null;
}
private void startLogging() {
mTime = System.currentTimeMillis();
}
private void doSomeFancyStuff() throws InterruptedException {
/*
* For this demonstration I will just sleep the thread and pretend it to
* do some work.
*/
Thread.sleep(1234);
}
private void stopLogging() {
long now = System.currentTimeMillis();
Log.d("Test", "The operation took " + (now - mTime) + " milliseconds or " + ((now - mTime) / 1000) + " seconds.");
}
}
And please only use Upper Case characters for class names.

NullPointerException when user presses Ok button in dialog?

I'm currently trying to debug my application, however, I'm running into some difficulties with a NullPointerException. I have a dialog box with 4 checkboxes, a save button, and a cancel button. When the user marks their choices in the dialog box then presses the save button it returns a NullPointerException and I don't understand why. Below is the XML file in case it's relevant to finding the solution:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollviewPref"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:layout_marginTop="10dip">
<LinearLayout
android:layout_width="300dip"
android:layout_height="wrap_content"
android:orientation="vertical"
android:minWidth="200dip">
<CheckBox
android:id="#+id/altitudeCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Altitude"
android:layout_gravity="left" />
<CheckBox
android:id="#+id/latitudeCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Latitude"
android:layout_gravity="left" />
<CheckBox
android:id="#+id/longitudeCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Longitude"
android:layout_gravity="left" />
<CheckBox
android:id="#+id/velocityCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Velocity"
android:layout_gravity="left" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginBottom="10dip"
android:layout_marginTop="10dip">
<Button
android:id="#+id/saveBtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Save"
android:layout_weight="1" />
<Button
android:id="#+id/cancelBtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
</ScrollView>
The set set of code is the code that saves the user's choices to a SharedPreferences.
package shc_BalloonSat.namespace;
import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
public class CheckPreferences extends Dialog
{
Context shc;
private CheckBox altitudeCheckBox = null;
private CheckBox latitudeCheckbox = null;
private CheckBox longitudeCheckbox = null;
private CheckBox velocityCheckbox = null;
private CheckPreferencesListener listener;
SharedPreferences pref;
Editor prefEditor;
String userAltitudePreference = "";
String userLatitudePreference = "";
String userLongitudePreference = "";
String userVelocityPreference = "";
String userAltitudeChoice = "";
String userLatitudeChoice = "";
String userLongitudeChoice = "";
String userVelocityChoice = "";
public interface CheckPreferencesListener
{
public void onSettingsSaved();
public void onCancel();
}
public CheckPreferences(Context context, CheckPreferencesListener l)
{
super(context);
shc = context;
this.listener = l;
this.setContentView(R.layout.custompreferences);
altitudeCheckBox = (CheckBox) findViewById(R.id.altitudeCheckbox);
latitudeCheckbox = (CheckBox) findViewById(R.id.latitudeCheckbox);
longitudeCheckbox = (CheckBox) findViewById(R.id.longitudeCheckbox);
velocityCheckbox = (CheckBox) findViewById(R.id.velocityCheckbox);
this.setCancelable(false);
this.setCanceledOnTouchOutside(false);
this.setTitle("Data View Settings");
pref = shc.getSharedPreferences("shared_prefs", 1);
prefEditor = pref.edit();
initOnClick();
}
private void initOnClick()
{
View.OnClickListener click = new View.OnClickListener()
{
public void onClick(View v)
{
switch (v.getId())
{
case R.id.saveBtn:
{
saveSettings();
listener.onSettingsSaved();
dismiss();
break;
}
case R.id.cancelBtn:
{
listener.onCancel();
dismiss();
break;
}
}
}
};
// Save Button
this.findViewById(R.id.saveBtn).setOnClickListener(click);
// Cancel Button
this.findViewById(R.id.cancelBtn).setOnClickListener(click);
}
// This function is called when the user chooses the save their preferences
public void saveSettings()
{
try
{
if (altitudeCheckBox.isChecked())
{
userAltitudeChoice = "true";
prefEditor.putString(userAltitudePreference, userAltitudeChoice);
prefEditor.commit();
}
else if (latitudeCheckbox.isChecked())
{
userLatitudeChoice = "true";
prefEditor.putString(userLatitudePreference, userLatitudeChoice);
prefEditor.commit();
}
else if (longitudeCheckbox.isChecked())
{
userLongitudeChoice = "true";
prefEditor.putString(userLongitudePreference, userLongitudeChoice);
prefEditor.commit();
}
else if (velocityCheckbox.isChecked())
{
userVelocityChoice = "true";
prefEditor.putString(userVelocityPreference, userVelocityChoice);
prefEditor.commit();
}
else
{
}
}
catch (NullPointerException npe)
{
if (npe.getMessage() != null)
{
Log.e("<tag>", npe.getMessage());
}
else
{
Log.e("<tag>", "Save Settings e.getMessage() was null");
}
}
}
}
The NullPointerException happens in the savedSettings function. All that function does is put data in the SharedPreferences. Any idea why that wold cause something to be null? Thanks in advance for any help given.
Update: Below is the error log.
05-09 17:25:28.835: E/<tag>(5447): Save Settings e.getMessage() was null
05-09 17:25:28.866: E/AndroidRuntime(5447): FATAL EXCEPTION: main
05-09 17:25:28.866: E/AndroidRuntime(5447): java.lang.NullPointerException
05-09 17:25:28.866: E/AndroidRuntime(5447): at shc_BalloonSat.namespace.CheckPreferences$1.onClick(CheckPreferences.java:59)
05-09 17:25:28.866: E/AndroidRuntime(5447): at android.view.View.performClick(View.java:2408)
05-09 17:25:28.866: E/AndroidRuntime(5447): at android.view.View$PerformClick.run(View.java:8816)
05-09 17:25:28.866: E/AndroidRuntime(5447): at android.os.Handler.handleCallback(Handler.java:587)
05-09 17:25:28.866: E/AndroidRuntime(5447): at android.os.Handler.dispatchMessage(Handler.java:92)
05-09 17:25:28.866: E/AndroidRuntime(5447): at android.os.Looper.loop(Looper.java:123)
05-09 17:25:28.866: E/AndroidRuntime(5447): at android.app.ActivityThread.main(ActivityThread.java:4627)
05-09 17:25:28.866: E/AndroidRuntime(5447): at java.lang.reflect.Method.invokeNative(Native Method)
05-09 17:25:28.866: E/AndroidRuntime(5447): at java.lang.reflect.Method.invoke(Method.java:521)
05-09 17:25:28.866: E/AndroidRuntime(5447): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
05-09 17:25:28.866: E/AndroidRuntime(5447): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
05-09 17:25:28.866: E/AndroidRuntime(5447): at dalvik.system.NativeStart.main(Native Method)
Below is my main class where the listener is instantiated.
package shc_BalloonSat.namespace;
import java.text.DecimalFormat;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.TextView;
import android.widget.Toast;
public class Shc_BalloonSat_Activity extends Activity
{
int historyCountFromUser;
httpAPI api;
mapAPI map;
runDialog dialog;
CheckPreferences check;
DecimalFormat df = new DecimalFormat("##.#####");
DecimalFormat decimalf = new DecimalFormat("##.######");
AlertDialog alert;
SharedPreferences pref;
Editor prefEditor;
String lastpacketsPHP;
TextView historyTV;
TextView infoTV;
// User to determine how many packet the user would like to see.
int userDefinedCount = 5;
/*
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
loadApp();
}
public boolean isNetworkConnected(Context context)
{
ConnectivityManager connectionManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectionManager.getActiveNetworkInfo() != null && connectionManager.getActiveNetworkInfo().isAvailable() && connectionManager.getActiveNetworkInfo().isConnected())
{
return true;
}
else
{
return false;
}
}
public void showAlert()
{
alert.setTitle("Sorry!");
alert.setMessage("Please connect to the internet to access the full functionality of this app.");
alert.setButton("OK", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
}
});
alert.show();
}
public void loadApp()
{
setContentView(shc_BalloonSat.namespace.R.layout.main);
alert = new AlertDialog.Builder(this).create();
lastpacketsPHP = "";
pref = getSharedPreferences("shared_prefs", 1);
prefEditor = pref.edit();
//prefEditor.putString(lastpacketsPHP, "\* PHP file location goes here. */");
//prefEditor.commit();
// These next two lines are used to test the PHP files on the SHC server by determining if PHP is set up correctly.
prefEditor.putString(lastpacketsPHP, "\* PHP file location goes here. */");
prefEditor.commit();
if (!isNetworkConnected(this))
{
showAlert();
}
else
{
api = new httpAPI(this);
map = new mapAPI(this);
dialog = new runDialog(this, api, new runDialog.OnDataLoadedListener()
{
public void dataLoaded(String textViewString)
{
infoTV = (TextView)findViewById(shc_BalloonSat.namespace.R.id.info);
infoTV.setText(textViewString);
}
});
dialog.execute();
}
CheckPreferences cp = new CheckPreferences(this, new CheckPreferences.CheckPreferencesListener()
{
public void onSettingsSaved()
{
// This function let's the activity know that the user has saved their preferences and
// that the rest of the app should be now be shown.
check.saveSettings();
assignInfoToInfoTextView();
assignInfoToHistoryTextView();
}
public void onCancel()
{
Toast.makeText(getApplicationContext(), "Settings dialog cancelled", Toast.LENGTH_LONG).show();
}
});
cp.show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(shc_BalloonSat.namespace.R.menu.mainmenu, menu);
SubMenu submenu = menu.addSubMenu(0, Menu.FIRST, Menu.NONE, "Preferences");
submenu.add(0, 5, Menu.NONE, "Get Last 5 Packets");
submenu.add(0, 10, Menu.NONE, "Get Last 10 Packets");
submenu.add(0, 20, Menu.NONE, "Get Last 20 Packets");
inflater.inflate(shc_BalloonSat.namespace.R.menu.mainmenu, submenu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle item selection
switch (item.getItemId())
{
case shc_BalloonSat.namespace.R.id.viewKML:
viewKML();
return true;
case 5:
viewLast5Packets();
return true;
case 10:
viewLast10Packets();
return true;
case 20:
viewLast20Packets();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void assignInfoToInfoTextView()
{
try
{
String result = api.result.substring(1, api.result.length()-2);
JSONObject json_data = new JSONObject(result);
String infoText = "";
if (check.userAltitudePreference.equals("true"))
{
double altitudeData = json_data.getDouble("altitude");
double altitudeInFeet = altitudeData * 3.281;
infoText = "Last Known Altitude: " + df.format(altitudeInFeet) + " ft\n";
}
else if (check.userVelocityPreference.equals("true"))
{
Double speedData = json_data.optDouble("speed");
if (speedData.isNaN())
{
speedData = 0.00;
}
Double direction = json_data.optDouble("heading");
String directionUnits = " degrees from N";
String directionText = "";
if (direction == 0)
{
directionText = ", N";
}
else if (direction > 0 && direction < 45)
{
directionText = ", N NE";
}
else if (direction == 45)
{
directionText = ", NE";
}
else if (direction > 45 && direction < 90)
{
directionText = ", E NE";
}
else if (direction == 90)
{
directionText = ", E";
}
else if (direction > 90 && direction < 135)
{
directionText = ", E SE";
}
else if (direction == 135)
{
directionText = ", SE";
}
else if (direction > 135 && direction < 180)
{
directionText = ", S SE";
}
else if (direction == 180)
{
directionText = ", S";
}
else if (direction > 180 && direction < 225)
{
directionText = ", S SW";
}
else if (direction == 225)
{
directionText = ", SW";
}
else if (direction > 225 && direction < 270)
{
directionText = ", W SW";
}
else if (direction == 270)
{
directionText = ", W";
}
else if (direction > 270 && direction < 315)
{
directionText = ", W NW";
}
else if (direction == 315)
{
directionText = ", NW";
}
else if (direction > 315 && direction < 360)
{
directionText = ", N NW";
}
else if (direction.isNaN())
{
directionText = " Invalid direction";
}
else
{
}
infoText += "Last Known Velocity: " + df.format(speedData) + " m/s " + direction + directionUnits + directionText + "\n";
}
else if (check.userLatitudePreference.equals("true"))
{
double recentLatitudeData = json_data.getDouble("latitude");
infoText += "Last Known Latitude: " + df.format(recentLatitudeData) + "\n";
}
else if (check.userLongitudePreference.equals("true"))
{
double recentLongitudeData = json_data.getDouble("longitude");
infoText += "Last Known Longtitude: " + df.format(recentLongitudeData) + "\n";
}
infoTV.setText(infoText);
}
catch (JSONException e)
{
if (e.getMessage() != null)
{
Log.e("<tag>", e.getMessage());
}
else
{
Log.e("<tag>", "Last Known Textview 1 e.getMessage() was null");
}
Toast.makeText(this,"JSON Error in (Last Known) method!",Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
//broke here, not getting a message for some reason
if (e.getMessage() != null)
{
Log.e("<tag>", e.getMessage());
}
else
{
Log.e("<tag>", "Last Known Textview 2 e.getMessage() was null");
}
Toast.makeText(this,"Error in (Last Known) method!",Toast.LENGTH_SHORT).show();
}
}
public void assignInfoToHistoryTextView()
{
try
{
JSONArray jArray = new JSONArray(api.result);
historyTV = (TextView)findViewById(shc_BalloonSat.namespace.R.id.history);
for (int count = 1; count < userDefinedCount; count++)
{
JSONObject json_data = jArray.getJSONObject(count);
double altitudeData = json_data.getDouble("altitude");
double altitudeInFeet = altitudeData * 3.281;
String historyText = "Altitude: " + decimalf.format(altitudeInFeet) + " ft\n";
Double speedData = json_data.optDouble("speed");
if (speedData.isNaN())
{
speedData = 0.00;
}
Double direction = json_data.optDouble("heading");
String directionUnits = " degrees from N";
String directionText = "";
if (direction == 0)
{
directionText = ", N";
}
else if (direction > 0 && direction < 45)
{
directionText = ", N NE";
}
else if (direction == 45)
{
directionText = ", NE";
}
else if (direction > 45 && direction < 90)
{
directionText = ", E NE";
}
else if (direction == 90)
{
directionText = ", E";
}
else if (direction > 90 && direction < 135)
{
directionText = ", E SE";
}
else if (direction == 135)
{
directionText = ", SE";
}
else if (direction > 135 && direction < 180)
{
directionText = ", S SE";
}
else if (direction == 180)
{
directionText = ", S";
}
else if (direction > 180 && direction < 225)
{
directionText = ", S SW";
}
else if (direction == 225)
{
directionText = ", SW";
}
else if (direction > 225 && direction < 270)
{
directionText = ", W SW";
}
else if (direction == 270)
{
directionText = ", W";
}
else if (direction > 270 && direction < 315)
{
directionText = ", W NW";
}
else if (direction == 315)
{
directionText = ", NW";
}
else if (direction > 315 && direction < 360)
{
directionText = ", N NW";
}
else if (direction.isNaN())
{
directionText = " Invalid direction";
}
else
{
}
if (direction.isNaN())
{
historyText += "Velocity: " + df.format(speedData) + " m/s " + directionText + "\n";
}
else
{
historyText += "Velocity: " + df.format(speedData) + " m/s,\n" + direction + directionUnits + directionText + "\n";
}
double latitudeData = json_data.getDouble("latitude");
historyText += "Latitude: " + df.format(latitudeData) + "\n";
double longitudeData = json_data.getDouble("longitude");
historyText += "Longtitude: " + df.format(longitudeData) + "\n\n";
historyTV.setText(historyTV.getText().toString() + historyText);
}
}
catch (JSONException e)
{
if (e.getMessage() != null)
{
Log.e("log_tag", "Error parsing data: " + e.toString());
}
else
{
Log.e("<tag>", "History TextView 1 e.getMessage() was null");
}
}
catch(Exception e)
{
if (e.getMessage() != null)
{
Log.e("log_tag", "Error parsing data: " + e.toString());
}
else
{
Log.e("<tag>", "History TextView 2 e.getMessage() was null");
}
}
}
void viewLast5Packets()
{
if (!isNetworkConnected(this))
{
showAlert();
}
else
{
historyTV.setText("");
userDefinedCount = 5;
//prefEditor.putString(lastpacketsPHP, "\* PHP file location goes here. */");
//prefEditor.commit();
// These next two lines are used to test the PHP files on the SHC server by determining if PHP is set up correctly.
prefEditor.putString(lastpacketsPHP, "\* PHP file location goes here. */");
prefEditor.commit();
dialog = new runDialog(this, api, new runDialog.OnDataLoadedListener()
{
public void dataLoaded(String textViewString)
{
TextView infoTV = (TextView)findViewById(shc_BalloonSat.namespace.R.id.info);
infoTV.setText(textViewString);
assignInfoToInfoTextView();
assignInfoToHistoryTextView();
}
});
dialog.execute();
}
}
void viewLast10Packets()
{
if (!isNetworkConnected(this))
{
showAlert();
}
else
{
historyTV.setText("");
userDefinedCount = 10;
//prefEditor.putString(lastpacketsPHP, "\* PHP file location goes here. */");
//prefEditor.commit();
// These next two lines are used to test the PHP files on the SHC server by determining if PHP is set up correctly.
prefEditor.putString(lastpacketsPHP, \* PHP file location goes here. */");
prefEditor.commit();
dialog = new runDialog(this, api, new runDialog.OnDataLoadedListener()
{
public void dataLoaded(String textViewString)
{
TextView infoTV = (TextView)findViewById(shc_BalloonSat.namespace.R.id.info);
infoTV.setText(textViewString);
assignInfoToInfoTextView();
assignInfoToHistoryTextView();
}
});
dialog.execute();
}
}
void viewLast20Packets()
{
if (!isNetworkConnected(this))
{
showAlert();
}
else
{
historyTV.setText("");
userDefinedCount = 20;
//prefEditor.putString(lastpacketsPHP, "\* PHP file location goes here. */");
//prefEditor.commit();
// These next two lines are used to test the PHP files on the SHC server by determining if PHP is set up correctly.
prefEditor.putString(lastpacketsPHP, "\* PHP file location goes here. */");
prefEditor.commit();
dialog = new runDialog(this, api, new runDialog.OnDataLoadedListener()
{
public void dataLoaded(String textViewString)
{
TextView infoTV = (TextView)findViewById(shc_BalloonSat.namespace.R.id.info);
infoTV.setText(textViewString);
assignInfoToInfoTextView();
assignInfoToHistoryTextView();
}
});
dialog.execute();
}
}
public void viewKML()
{
if (!isNetworkConnected(this))
{
showAlert();
}
else
{
map.openKML();
}
}
}
My thought is that
private CheckBox altitudeCheckBox = (CheckBox) findViewById(R.id.altitudeCheckbox);
private CheckBox latitudeCheckbox = (CheckBox) findViewById(R.id.latitudeCheckbox);
private CheckBox longitudeCheckbox = (CheckBox) findViewById(R.id.longitudeCheckbox);
private CheckBox velocityCheckbox = (CheckBox) findViewById(R.id.velocityCheckbox);
are called BEFORE your dialog's constructor so they are null because findViewById doesn't find the layout views. Try to change them in:
private CheckBox altitudeCheckBox = null;
private CheckBox latitudeCheckbox = null;
private CheckBox longitudeCheckbox = null;
private CheckBox velocityCheckbox = null;
and then add the following just after the this.setContentView(R.layout.custompreferences) line in your constructor:
altitudeCheckBox = (CheckBox) findViewById(R.id.altitudeCheckbox);
latitudeCheckbox = (CheckBox) findViewById(R.id.latitudeCheckbox);
longitudeCheckbox = (CheckBox) findViewById(R.id.longitudeCheckbox);
velocityCheckbox = (CheckBox) findViewById(R.id.velocityCheckbox);
Hope this helps...
The easiest to find the reason for your NullPointerException is to look at the debug logcat output. It will show you exactly the line where the problem occured.
Just look for the first line starting with your package name, that should be it.
ps you need to take the catch out of your code so the code crashes
Or post the log if you can't find it.
From a cursory inspection of your code, it seems like you never initialized listener, so when you do listener.onSettingsSaved(); it crashes.
EDIT:
Dude, you still NEVER set it:
public CheckPreferences(Context context, CheckPreferencesListener l)
{
super(context);
shc = context;
this.setContentView(R.layout.custompreferences);
this.setCancelable(false);
this.setCanceledOnTouchOutside(false);
this.setTitle("Data View Settings");
pref = shc.getSharedPreferences("shared_prefs", 1);
prefEditor = pref.edit();
initOnClick();
}
You're missing this.listener = l;!

Categories

Resources