double-wert errechnen und in Intent übergeben

  • Antworten:12
Elisabeth R.
  • Forum-Beiträge: 9

19.11.2012, 16:30:32 via Website

Hallo,

ich schreibe gerade an meiner ersten App. Es ist ein BMI-Rechner, mit 3. Activitys.

In der SecondActivity.java berechne ich den BMI-Wert (Code siehe unten), in der ThirdActivity soll dieser BMI-double-Wert (auf 2. Nachkommastellen gerundet) dann in einem TextView mit "%1$s" eingefügt werden.

Ich habe nun mittlerweile raus bekommen, dass man komplexe Datentypen am besten mit Parcelable übergibt. Hier habe ich eine Klasse "DoubleValue implements Parcalable" geschrieben, aber so ganz verstanden hab ich die Hintergründe noch nicht.
Muss ich in der DoubleValue-Klassedie Berechnung für den BMI-Wert durchführen, oder kann ich es wie bereits getan in der SecondActivity machen und dann einfach an "DoubleValue implements Parcelable" übergeben.

Ich hoffe jemand macht sich die Mühe und schaut mal fix drüber.. :) (sieht viel aus, ist es aber nicht)

Hier mein Code für die erwähnten Klassen: SecondActivity, ThirdActivity und Double Value

Im Moment kommt die Fehlermeldung: java.lang.RuntimeException: Unable to start activity Component Info ... ThirdActivity

Danke erstmal!!

1package com.example.bmirechner;
2
3import java.text.DecimalFormat;
4import java.text.NumberFormat;
5
6import android.os.Bundle;
7import android.annotation.SuppressLint;
8import android.app.Activity;
9import android.content.Intent;
10import android.util.Log;
11import android.view.View;
12import android.view.View.OnClickListener;
13import android.widget.Button;
14import android.widget.EditText;
15import android.widget.TextView;
16
17public class SecondActivity extends Activity {
18
19
20 private EditText ageEdit, heightEdit, weightEdit;
21 private Button buttonBMI;
22 public TextView bmiValue, name_gruss;
23 public String bmi;
24 public static double bmi2, height, weight;
25 public String bmiString;
26
27
28
29 private static final String TAG = MainActivity.class.getSimpleName();
30
31 @Override
32 public void onCreate(Bundle savedInstanceState) {
33 super.onCreate(savedInstanceState);
34 setContentView(R.layout.second_main);
35 Intent in = getIntent();
36
37 name_gruss = (TextView) findViewById(R.id.name_gruss);
38 name_gruss.setText(getString(R.string.begruessung, in.getStringExtra("Name")));
39
40
41 // wenn kein Zwischenspeicher vorliegt > folgende Ausgabe im View LogCat
42 // if-Abfrage um NullpointerException zu vermeiden
43 if (savedInstanceState == null) {
44 Log.d(TAG, "savedInstanceState war null");
45 //sobald einer Zwischenspeicher vorliegt, auch wenn Bildschirm nur gedreht wurde
46 } else {
47 Log.d(TAG,
48 "wurde vor "
49 + (System.currentTimeMillis() - savedInstanceState
50 .getLong(TAG)) + " Millisekunden beendet");
51 }
52
53 buttonBMI = (Button) findViewById(R.id.buttonBMI);
54 buttonBMI.setText(R.string.buttonBMI);
55
56 ageEdit = (EditText) findViewById(R.id.ageEdit);
57 heightEdit = (EditText) findViewById(R.id.heightEdit);
58 weightEdit = (EditText) findViewById(R.id.weightEdit);
59
60
61 buttonBMI.setOnClickListener(new OnClickListener() {
62
63
64
65
66
67
68 @SuppressLint({ "NewApi", "UseValueOf" })
69 public void onClick(View v) {
70
71 if ((ageEdit.getText().length() == 0) || (weightEdit.getText().length() == 0) || (heightEdit.getText().length() == 0) )
72 {
73 System.out.println("popup");
74 } else {
75
76 double age = Double.valueOf(ageEdit.getText().toString());
77 double height = Double.valueOf(heightEdit.getText().toString());
78 double weight = Double.valueOf(weightEdit.getText().toString());
79
80 System.out.println(age);
81 System.out.println(height);
82 System.out.println(weight);
83
84 double bmi1 = height * height;
85
86 System.out.println(bmi1);
87 double bmi2 = weight/bmi1 * 10000;
88
89 bmiString = (new Double(bmi2).toString());
90
91 }
92
93 Intent thirdA = new Intent(getApplicationContext(), ThirdActivity.class);
94
95 thirdA.putExtra("DoubleValue", bmi2);
96 startActivity(thirdA);
97 }
98 });
99
100 }
101
102 @Override
103 // überschreiben der Methode onSaveInstanceState um beim Beenden der
104 // Activity Daten in einem Bundle abzulegen
105 protected void onSaveInstanceState(Bundle outState) {
106 // Aufruf der Elternmehtode um Inhalte z.B. in Textfeldern beim erneuten
107 // Wiederaufruf zu sichern
108 super.onSaveInstanceState(outState);
109 // mit put-Methode auf Bundle-Referenz "outState" werden beim Beenden
110 // einer Activity Daten in einem Bundle abgelegt
111 outState.putLong(TAG, System.currentTimeMillis());
112 }
113}

1package com.example.bmirechner;
2
3import android.os.Parcel;
4import android.os.Parcelable;
5
6public class DoubleValue implements Parcelable {
7
8 public double bmiValue =SecondActivity.bmi2;
9
10 // Constructor
11 public DoubleValue(double bmiValue){
12 this.bmiValue = bmiValue;
13 }
14
15 //Parcelling part
16 public DoubleValue(Parcel in) {
17 bmiValue = in.readDouble();
18 }
19
20 public double getBmiValue() {
21 return this.bmiValue;
22 }
23
24 public void setBmiValue(double bmiValue) {
25 this.bmiValue = bmiValue;
26 }
27
28 @Override
29 public int describeContents() {
30 return 0;
31 }
32
33 @Override
34 public void writeToParcel(Parcel dest, int flags) {
35 dest.writeDouble(this.bmiValue);
36
37
38// dest.writeStringArray(new String[] { this.id, this.name, this.grade });
39 }
40
41 @SuppressWarnings("rawtypes")
42 public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
43 public DoubleValue createFromParcel(Parcel in) {
44 return new DoubleValue(in);
45 }
46
47 public DoubleValue[] newArray(int size) {
48 return new DoubleValue[size];
49 }
50 };
51}
I



1import android.app.Activity;
2import android.content.Intent;
3import android.os.Bundle;
4import android.util.Log;
5import android.widget.TextView;
6
7public class ThirdActivity extends Activity {
8
9 private static final String TAG = ThirdActivity.class.getSimpleName();
10 private TextView bmiValue;
11 DoubleValue doubleValue;
12
13 @Override
14 public void onCreate(Bundle savedInstanceState) {
15 super.onCreate(savedInstanceState);
16 setContentView(R.layout.third_main);
17 Bundle data = getIntent().getExtras();
18 doubleValue = data.getParcelable("DoubleValue");
19 Intent thirdAct = getIntent();
20
21 bmiValue = (TextView) findViewById(R.id.bmiValue);
22 bmiValue.setText(getString(R.string.bmiValue,thirdAct.getStringExtra("DoubleValue")));
23
24
25
26 // wenn kein Zwischenspeicher vorliegt > folgende Ausgabe im View LogCat
27 // if-Abfrage um NullpointerException zu vermeiden
28 if (savedInstanceState == null) {
29 Log.d(TAG, "savedInstanceState war null");
30 // sobald einer Zwischenspeicher vorliegt, auch wenn Bildschirm nur
31 // gedreht wurde
32 } else {
33 Log.d(TAG,
34 "wurde vor "
35 + (System.currentTimeMillis() - savedInstanceState
36 .getLong(TAG)) + " Millisekunden beendet");
37
38 }
39 }
40}

Antworten
Christian
  • Forum-Beiträge: 307

19.11.2012, 19:59:15 via Website

Hi Elisabeth R.,

Hab ich dich richtig verstanden du möchtest einen double-Wert einer Activity übergeben?
Wozu brauchst du dann die Klasse "DoubleValue"?

java.lang.RuntimeException: Unable to start activity Component Info ... ThirdActivity

ich vermute mal der Fehler entsteht hier:
1doubleValue = data.getParcelable("DoubleValue");

du über gibst in der "SecondActivity" einen einfachen double Wert nicht deine Klasse "DoubleValue".
1Intent thirdA = new Intent(getApplicationContext(), ThirdActivity.class);
2//bmi2 ist vom Datentyp double nicht von der Klasse DoubleValue.
3thirdA.putExtra("DoubleValue", bmi2);
4startActivity(thirdA);

in der "ThirdActivity" musst du jetzt nur noch das hier machen:
1doubleValue = data.getDouble("DoubleValue");

mfg Christian

P.s. die if Abfrage in der onclick-Funktion in der Klasse "SecondActivity" solltest du dir vielleicht nochmal ansehen

Antworten
Elisabeth R.
  • Forum-Beiträge: 9

19.11.2012, 20:48:16 via Website

Hallo Christian,

danke für die schnelle Antwort. :bashful:
Du hast recht ich muss die Klasse "DoubleValue" übergeben. Das hatte ich dann vor lauter Bäumen gar nicht mehr gesehen. Danke!

Jetzt lässt er mich wenigstens auf die ThirdActivity... wo vorher die genannte Fehlermeldung kam.
Trotzdem bekomme als Wert null. (Auf der ThirdAcitivity ist ein TextView platziert, mit dem Platzhalter für den DoubleWert). - Dein BMI-Wert beträgt %1$s -
Heißt in der DoubleValue-Klasse funktioniert irgendwas nicht. Da hier eben null übergeben wird.

Die DoubleValue benutze ich deshalb weil nur das Interface Parcelable es ermöglicht Double-Werte über ein Intent an eine Activity zu übergeben.

Ich hatte erst versucht den DoubleWert in einen String umzuwandeln, funktionierte auch soweit, aber die Übergabe ans Intent dann nicht mehr

Ich finde im Netz auch nirgends ein Beispiel wo diese Art von Übergabe schonmal erläutert wurde.

In meiner if-Abrage, meinst du das System.out.println()?
Oder die Berechnung?
Weiß noch nicht genau auf was du mich aufmerksam machen willst.. Kleiner Tipp? :bashful:

Da hätte ich gleich noch eine Frage, wie kann ich ein Popup aufkommen lassen (z.B. bei einer Fehleingabe) ? Geht das, oder muss man dazu wieder eine neue Activity anlegen?

LG
Elisabeth

Antworten
Christian
  • Forum-Beiträge: 307

19.11.2012, 21:24:41 via Website

Hi,


Die DoubleValue benutze ich deshalb weil nur das Interface Parcelable es ermöglicht Double-Werte über ein Intent an eine Activity zu übergeben.

meinst du den Datentype "double" --> double tmp = 2.31123123;
oder die Klasse Double --> Double d = new Double(234.65) ?

Weil in deinen Code arbeitest du mit dem Datentyp double und für diesen brauchst du kein "Parcelable" um den an eine Activity zu übergeben.
Deshalb versteh ich nicht warum du mit einer extra Klasse arbeitest.


In meiner if-Abrage, meinst du das System.out.println()?
Oder die Berechnung?
Ich meine eher das egal wie die Abfrage ausgeht es wird auf jeden Fall der Intent aufgerufen wird.
Ist halt jetzt die Frag ob das von dir beabsichtigt ist.

Da hätte ich gleich noch eine Frage, wie kann ich ein Popup aufkommen lassen (z.B. bei einer Fehleingabe) ? Geht das, oder muss man dazu wieder eine neue Activity anlegen?
Dialogs

Mfg Christian

Antworten
Elisabeth R.
  • Forum-Beiträge: 9

19.11.2012, 22:57:59 via Website

meinst du den Datentype "double" --> double tmp = 2.31123123;
oder die Klasse Double --> Double d = new Double(234.65) ?

Ja war natürlich doof, ich habe esjetzt geändert. Und so sieht die Klasse DoubleValue jetzt aus:

1package com.example.bmirechner;
2
3import android.os.Parcel;
4import android.os.Parcelable;
5
6public class DoubleValue implements Parcelable {
7
8 public Double bmiValue = SecondActivity.bmi2;
9
10 // Constructor
11 public DoubleValue(Double bmiValue){
12 this.bmiValue = bmiValue;
13 }
14
15 //Parcelling part
16 public DoubleValue(Parcel in) {
17 bmiValue = in.readDouble();
18 }
19
20 public double getBmiValue() {
21 return this.bmiValue;
22 }
23
24 public void setBmiValue(double bmiValue) {
25 this.bmiValue = bmiValue;
26 }
27
28 @Override
29 public int describeContents() {
30 return 0;
31 }
32
33 @Override
34 public void writeToParcel(Parcel dest, int flags) {
35 dest.writeDouble(this.bmiValue);
36
37
38// dest.writeStringArray(new String[] { this.id, this.name, this.grade });
39 }
40
41 @SuppressWarnings("rawtypes")
42 public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
43 public DoubleValue createFromParcel(Parcel in) {
44 return new DoubleValue(in);
45 }
46
47 public DoubleValue[] newArray(int size) {
48 return new DoubleValue[size];
49 }
50 };
51}

in der SecondActivity sage ich dann:

1public Double Value dblValue;

1Intent thirdA = new Intent(getApplicationContext(), ThirdActivity.class);
2 thirdA.putExtra("DoubleValue", dblValue);
3 startActivity(thirdA);

Aber es wird immer noch null übermittelt. >_>

Weil in deinen Code arbeitest du mit dem Datentyp double und für diesen brauchst du kein "Parcelable" um den an eine Activity zu übergeben.
Deshalb versteh ich nicht warum du mit einer extra Klasse arbeitest.

Wenn ich in der SecondActivity die Berechnung durchführe habe ich als Ergebnis einen double-Wert, diesen double-Wert kann ich dann aber nicht an eine nächste Activity übergeben. Man kann nur Strings, evtl. noch int-Werte übergeben. So habe ich es jetzt mehrfach gelesen.
Deshalb dachte ich ich muss eine Extra Klasse (DoubleValue) schreiben die Parcelable implementiert.
Ist diese Überlegung falsch?
Ich hatte auch versucht den double-Wert in der SecondActivity in einen String zu parsen und diesen dann übers Intent an ThirdActivity zu übergeben. Aber das klappt nicht.
Ich denke das in DoubleValue irgendetwas schief läuft. Was daran liegen mag, dass ich den Code darin nicht wirklich verstehe. Bin noch nicht richtig fit in Android und Java..

Danke und vielleicht finden wir ja noch das Problem.
LG

Antworten
Elisabeth R.
  • Forum-Beiträge: 9

20.11.2012, 14:37:33 via Website

Also es hat geklappt. Ohne Parcelable, ohne Extra-Klasse. Ich hab lediglich das Ergebnis in einen String umgewandelt (was ich ja auch schonmal versucht hatte, und da klappte es nicht) Aber jetzt! Naja wer weiß... :rolleyes:

Komisch ist aber dennoch, dass der double-Wert nicht übergeben wird.

Hier der Code der funktioniert:

1buttonBMI.setOnClickListener(new OnClickListener() {
2
3 @SuppressLint({ "NewApi", "UseValueOf" })
4 public void onClick(View v) {
5
6 if ((ageEdit.getText().length() == 0) || (weightEdit.getText().length() == 0) || (heightEdit.getText().length() == 0))
7 {
8 System.out.println("popup");
9 } else {
10
11 double age = Double.valueOf(ageEdit.getText().toString());
12 double height = Double.valueOf(heightEdit.getText().toString());
13 double weight = Double.valueOf(weightEdit.getText().toString());
14
15 System.out.println(age);
16 System.out.println(height);
17 System.out.println(weight);
18
19
20 DecimalFormat f = new DecimalFormat("#0.00");
21
22 double bmi1 = height * height;
23 System.out.println(bmi1);
24
25 double bmi2 = weight/bmi1 * 10000;
26 System.out.println(bmi2);
27 System.out.println(f.format(bmi2));
28 String d2 = f.format(bmi2);
29
30
31 bmiString = (new Double(bmi2).toString());
32 System.out.println(bmiString);
33
34 Intent thirdA = new Intent(getApplicationContext(), ThirdActivity.class);
35 thirdA.putExtra("DoubleValue", b2);
36 startActivity(thirdA);
37 }
38 }
39 });
40 }


Wenn ich jedoch
1thirdA.putExtra("DoubleValue", bmi2);
übergebe will, gibt er wieder "null" auf der nächsten Activity aus.

Also ist die Überlegung das double-Werte nicht übergeben werden können nun richtig oder nicht?
Wann benutzt man Parcelable?

Lieben Dank nochmal Christian!:)

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

20.11.2012, 15:40:02 via Website

Nicht richtig! Ich übergebe in vielen meiner Apps permanent double Werte per putExtra und lese die mit getDouble wieder aus.

Du solltest mal mit dem Debugger durch die Zeilen wandern, mir wurde bei dem Wust etwas schwindelig.

Parcelable verwendet man für alles was kein native ist.

Das muss klappen:

1Intent intent = new Intent(this, DeineActivity.class);
2intent.putExtra("ADOUBLE", (double) 1.0);
3startActivity(intent);
4
5
6@Override
7public void onCreate(Bundle bundle) {
8 super.onCreate(bundle);
9
10 // ...
11
12 Bundle bundleExtras = getIntent().getExtras();
13 if (bundleExtras != null) {
14 double d = bundleExtras.getDouble("ADOUBLE");
15 }
16}

Antworten
Elisabeth R.
  • Forum-Beiträge: 9

20.11.2012, 17:24:40 via Website

bei mir klappt es nur so:

1DecimalFormat f = new DecimalFormat("#0.00");
2 double bmi1 = height * height;
3 double bmi2 = weight/bmi1 * 10000;
4 String dblbmi = f.format(bmi2);
5
6 Intent thirdA = new Intent(getApplicationContext(), ThirdActivity.class);
7 thirdA.putExtra("DoubleValue", dblbmi);
8 startActivity(thirdA);

1Intent thirdAct = getIntent();
2
3 bmiValue = (TextView) findViewById(R.id.bmiValue);
4 bmiValue.setText(getString(R.string.bmiValue,thirdAct.getStringExtra("DoubleValue")));

Wie gesagt, wenn ich "bmi2" übergeben will, was ja ein double-Wert ist, wirds nix..
Aber ich glaube dir, dass es prinzipiell möglich ist, nur in meinem Fall, warum auch immer, nicht.

Und wenn ich z.B. "this" im Intent angebe, so wie du es machst, bekomme ich eine Fehlermeldung..
ich muss mit getApplicationContext() arbeiten...:wacko:

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

20.11.2012, 18:31:11 via Website

"this" ist die Activity aus der die zweite Activity gestartet wird. Da fast alles Wichtige (Activity, Service, etc.) von Context erbt müsste "this" zum Starten einer Activity überall funktionieren wo es wichtig ist. Wo genau und in welchem Kontext startest Du die zweite Activity?

Nachtrag: Ich sehe gerade das Du in einem Listener bist. Da geht das mit "DeineActivity.this".
.
Nachtrag2: Du machst definitiv etwas falsch wenn bei Dir keine nativen double per putExtra übergeben werden können. Ich übertrage tausende Location-Updates per putExtra während einer Streckenaufzeichnung - und das sind alles doubles.

— geändert am 20.11.2012, 18:34:34

Antworten
Christian
  • Forum-Beiträge: 307

21.11.2012, 12:14:41 via Website

Hi Elisabeth R.,


Wenn ich in der SecondActivity die Berechnung durchführe habe ich als Ergebnis einen double-Wert, diesen double-Wert kann ich dann aber nicht an eine nächste Activity übergeben. Man kann nur Strings, evtl. noch int-Werte übergeben. So habe ich es jetzt mehrfach gelesen.

Keine Ahnung wo du das gelesen hast aber wie du wahrscheinlich schon selbst gemerkt hast ist das Blödsinn.

Da scheinbar dein Code immer noch nicht richtig funktioniert habe ich mal ein kleines Beispielprogramm geschrieben.
Da bei AndroidPit die Source Code Darstellung nicht wirklich toll ist hab ich die ganze Sache mal bei GitHub:gist veröffentlicht.

Link: https://gist.github.com/4124437
Projekt: http://www.file-upload.net/download-6837968/DataSend.7z.html

mfg Christian

— geändert am 21.11.2012, 12:31:27

Antworten
Elisabeth R.
  • Forum-Beiträge: 9

26.11.2012, 16:44:39 via Website

Hallo Harald,

sorry für die späte Antwort.

Nachtrag: Ich sehe gerade das Du in einem Listener bist. Da geht das mit "DeineActivity.this".

ja das ging.. aber es ist ja nicht so dass ich es zuvor nicht so ausprobiert hätte. Komische Sache manchmal..

Nachtrag2: Du machst definitiv etwas falsch wenn bei Dir keine nativen double per putExtra übergeben werden können. Ich übertrage tausende Location-Updates per putExtra während einer Streckenaufzeichnung - und das sind alles doubles.

Das glaube ich dir, aber den Grund dafür kann ich momentan noch nicht erkennen...:wacko:

Danke Harald aber zunächst für deine Hilfe!

Antworten
Elisabeth R.
  • Forum-Beiträge: 9

26.11.2012, 16:49:39 via Website

Hi Christian,

leider kann ich hier keine Links einfügen, sonst hätte ich dir meine "Quelle" gepostet.

Deinen Code muss ich mir erstmal noch ansehen...
Komm heute erst wieder dazu mal was zu machen.
Erstmal liebe Dank für deine Mühen!!

ich melde mich wieder..:)

Antworten
Elisabeth R.
  • Forum-Beiträge: 9

26.11.2012, 17:17:48 via Website

Ok, ich hab es jetzt etwas besser verstanden.

Also wenn ich einen Double, Boolean etc.-Wert übergeben möchte muss ich dies mit einem Bundle erledigen.
Mit "getIntent()" (Intent intent = getIntent();)
kann ich nur String-Werte holen?
den auf "intent" kann ich z.B. "getDouble();" nicht aufrufen.. also brauch ich ein Bundle.

Da ich meinen Double-Wert noch auf 2 Nachkommastellen runden muss, hab ich meinen Double-Wert (bmi2)
noch mithilfe:
1String dblbmi = f.format(bmi2);

in einen String übegewandelt.

Und dann übergebe ich mit:

1Intent thirdA = new Intent(SecondActivity.this, ThirdActivity.class);
2 thirdA.putExtra("DoubleValue", dblbmi);
3 startActivity(thirdA);
an die nächste Activity.

Hier hol ich ihn dann wieder;

1Intent thirdAct = getIntent();
2
3 bmiValue = (TextView) findViewById(R.id.bmiValue);
4 bmiValue.setText(getString(R.string.bmiValue,thirdAct.getStringExtra("DoubleValue")));

Hier allerdings mit getStringExtra();

Vor der Umwandlung, also der reine double-Wert, hätte mit Bundle geholt werden müssen.
Richtig?

Man kann die Rundung auf die 2 Nachkommastellen sicherlich auch in der "zweiten Activity" machen. Gibt es da noch ein elegantere Lösung als die meine?

Ich hoffe es war nicht wieder zu kauderwelschich...

Antworten