eingabe per postrequest im AsyncTask versenden

  • Antworten:25
Marc Schumacher
  • Forum-Beiträge: 14

23.10.2012, 10:40:08 via Website

Hallo ich hab ein Problem und zwar will ich per Buttonklick die Eingabe die ich im Eingabefeld gemacht habe an unsere php seite schicken.
Dieses per Post. ich weiß mittlerweile das ich die postmethode per asynctask aufrufen muss damit die app nicht abstürzt oder halt gefreezt wird.
ich habe die MainActivity so aufgebaut :

1public class MainActivity extends Activity {
2
3
4 private EditText Feld1;
5 private EditText Feld2;
6
7
8
9
10 MyTask task = new MyTask<String, Void, Boolean>() {
11 @Override
12 protected void onPostExecute(Boolean... params) {
13 String msg = "";
14 if(params == null || params.length == 0) {
15 msg = "Generic error!";
16 } else if(!params[0]) {
17 msg = this.getOccurredProblem() != null ? this.getOccurredProblem().getErrorMessage() : "Something bad happened!";
18 } else {
19 msg = "Success";
20 }
21
22 Feld2.setText(msg);
23 }
24
25
26
27
28
29 @Override
30 public boolean onCreateOptionsMenu(Menu menu) {
31 getMenuInflater().inflate(R.menu.main, menu);
32 return true;
33 }
34
35 @Override
36 public void onCreate(Bundle savedInstanceState) {
37 super.onCreate(savedInstanceState);
38 setContentView(R.layout.main);
39 String c;
40 Feld1 = (EditText)findViewById(R.id.zahl1);
41 Feld2 = (EditText)findViewById(R.id.zahl2);
42 c = Feld1.getText().toString();
43
44
45 }
46
47
48
49 public void ButtonClick (View v){
50
51
52 String c;
53
54 Feld1 = (EditText)findViewById(R.id.zahl1);
55 c = Feld1.getText().toString();
56
57
58 task.execute(c);
59
60 }
61 ; }

Hier habe ich allerdings ganz zum schluss iwo einen syntax fehler den ich einfach nicht wegbekomme... weiß zufällig einer woran das liegt?


meine 2te klasse die ich gemacht habe heißt MyTask und ist so aufgebaut:

1public class MyTask extends AsyncTask<String, Void, Boolean> {
2 private Throwable occurredProblem;
3
4 public Throwable getProblem() {
5 get occurredProblem;
6 }
7
8 @Override
9 protected Boolean doInBackground(String... params) {
10 if(params == null || params.length == 0) {
11 occurredProblem = new IllegalArgumentException("MyTask needs a valid String param!");
12 return false;
13 } else {
14 return postRequest(params[0]);
15 }
16 }
17
18 public boolean postRequest(String c){
19 occurredProblem = null;
20 HttpClient client = new DefaultHttpClient();
21 HttpPost httppost = new HttpPost("meineseitephp");
22 try {
23
24
25 ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
26 nameValuePairs.add(new BasicNameValuePair("var", c));
27 httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
28
29 client.execute(httppost);
30
31 } catch (ClientProtocolException e) {
32 occurredProblem = e;
33 } catch (IOException e) {
34 occurredProblem = e;
35 }
36
37 return occurredProblem != null;
38}}

an für sich sollte das doch eigentlih funktionieren ... wo liegt mein fehler?

Liebe grüße Marc

Antworten
Maximilian O
  • Forum-Beiträge: 990

23.10.2012, 11:38:33 via App

Bist du denn schon einmal mit dem Debugger durchgegangen?
LG Maximilian

Vergiss nie wieder Geburtstage, oder viel schlimmer, deinen Hochzeitstag - Birthdays Download

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

23.10.2012, 13:35:12 via Website

Also ich hab jetzt eifnach mal etwas Code entfernt, damit er überhaupt etwas sendet weil das will mein chef undbedingt sehen. bin azubi im 2ten lehrjahr und das sind meine ersten versuche mit programmeiren und apps. also sry wenn ich blöde fragen stelle. meine main Klasse ist jetzt

1public class MainActivity extends Activity {
2
3
4 private EditText Feld1;
5 private EditText Feld2;
6
7
8
9
10 MyTask task = new MyTask();
11
12
13 @Override
14 public boolean onCreateOptionsMenu(Menu menu) {
15 getMenuInflater().inflate(R.menu.main, menu);
16 return true;
17 }
18
19 @Override
20 public void onCreate(Bundle savedInstanceState) {
21 super.onCreate(savedInstanceState);
22 setContentView(R.layout.main);
23 // String c;
24 Feld1 = (EditText)findViewById(R.id.zahl1);
25 Feld2 = (EditText)findViewById(R.id.zahl2);
26
27
28
29 }
30
31
32
33 public void ButtonClick (View v){
34
35
36 String c;
37
38 Feld1 = (EditText)findViewById(R.id.zahl1);
39 c = Feld1.getText().toString();
40
41
42 task.execute(c);
43
44 }
45 ; }



und meine 2te Klasse fürs Netzwerk ist.

1public class MyTask extends AsyncTask<String, Void, Boolean> {
2 private Throwable occurredProblem;
3
4
5
6
7
8 @Override
9 protected Boolean doInBackground(String... params) {
10 if(params == null || params.length == 0) {
11 occurredProblem = new IllegalArgumentException("MyTask needs a valid String param!");
12 return false;
13 } else {
14 return postRequest(params[0]);
15 }
16 }
17
18 public boolean postRequest(String c){
19 occurredProblem = null;
20 HttpClient client = new DefaultHttpClient();
21 HttpPost httppost = new HttpPost("meineseitephp");
22 try {
23
24
25 ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
26 nameValuePairs.add(new BasicNameValuePair("var", c));
27 httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
28
29 client.execute(httppost);
30
31 } catch (ClientProtocolException e) {
32 occurredProblem = e;
33 } catch (IOException e) {
34 occurredProblem = e;
35 }
36
37 return occurredProblem != null;
38}}

Ich kann es ohne Probleme Aufn Handy starten auch 1 mal senden geht. die daten kommen auch an. wenn ich allerdings ein 2tes mals enden will freezt die app wieder ein. muss ich die 2te klasse also die Netzwerkklasse in eine endlosschleife reinpacken? oder wie kann ich verhindern das es beim erneuten senden freezt?

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

23.10.2012, 14:39:24 via Website

Du musst den AsyncTask für jeden Lauf neu instanzieren (new MyTask). Also schieb die folgende Zeile noch in den Click Handler:

1MyTask task = new MyTask();

Hier noch der entsprechende Auszug aus der Doku:

The task can be executed only once (an exception will be thrown if a second execution is attempted.)

— geändert am 23.10.2012, 14:40:50

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

23.10.2012, 16:39:53 via Website

danke :) funktioniert ma schaun was mein chef die tage sagt :) und wo ihm iwas noch nich passt :D

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

30.10.2012, 14:12:28 via Website

so ich habe 2 Fragen. die erste geht wieder im die post methode. ich Möchte 3 String werte übergeben und habe es bis jetzt so in meiner netzklasse stehen :

1public class LogbookTask extends AsyncTask<String, Void, Boolean> {
2 private Throwable occurredProblem;
3
4
5
6
7
8 @Override
9 protected Boolean doInBackground(String... params) {
10 if(params == null || params.length == 0) {
11 occurredProblem = new IllegalArgumentException("MyTask needs a valid String param!");
12 return false;
13 } else {
14 return postRequest(params[0], null, null);
15 }
16 }
17
18 public boolean postRequest(String a, String b, String c){
19 occurredProblem = null;
20 HttpClient client = new DefaultHttpClient();
21 HttpPost httppost = new HttpPost("meineseite.php");
22 try {
23
24
25 ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
26 nameValuePairs.add(new BasicNameValuePair(a, b));
27 nameValuePairs.add(new BasicNameValuePair("km: ", c));
28 httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
29
30 client.execute(httppost);
31
32 } catch (ClientProtocolException e) {
33 occurredProblem = e;
34 } catch (IOException e) {
35 occurredProblem = e;
36 }
37
38 return occurredProblem != null;
39}}

ich befürchte das die protected Boolean doInBackground sache in zeile 18 nicht richtige mit 3 string werten funktioniert :/ allerdings habe ich keine ahnung wie ich die sache jetzt richtig angehe. es kommt kein fehler er sendet zwar daten aber nicht meine strings die eigentlich übermittelt werden sollten.

weiß da jemand vielleicht irgendetwas?



Meine 2te Frage is eigentlich nur eine Frage zum aufbau einer app. ich habe 3 layouts und wollte eigentlich zu jeden layout eine klasse machen. allerdings gibt es wenn ich den button vom 2ten layout auch in der extra klasse schreibe beim asufrühren später einen fatal error weil er die button methode in der Main klasse sucht. Wenn ich einfach den code für den button aus der 2ten klasse in die Main packe geht es natürlich. Komme ich da nicht drum herrum das in die main zu packen?


liebe grüße Marc

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

02.11.2012, 11:25:11 via Website

hm okay aber wie genau seztzt ich das um.. also in meiner main hab ich ejtzt soweit ich das verstanden haben umgesetzt und zwar so.

1import android.os.Bundle;
2import android.app.Activity;
3import android.view.KeyEvent;
4import android.view.Menu;
5import android.view.View;
6import android.widget.Button;
7import android.widget.EditText;
8import android.widget.Spinner;
9
10public class Main extends Activity {
11
12 boolean mainisopen = true;
13
14 private Spinner spinner1, spinner2 ;
15 private EditText feld1;
16 private String c;
17 private String b;
18 private String a;
19
20public void ButtonSend(View v)
21
22 spinner1 = (Spinner) findViewById(R.id.spinner1);
23 spinner2 = (Spinner) findViewById(R.id.spinner2);
24 feld1 = (EditText)findViewById(R.id.zahl1);
25
26 c = feld1.getText().toString();
27 a = spinner1.getContext().toString();
28 b = spinner2.getContext().toString();
29
30 logbooktask.execute(a,b,c);
31 }

so und das will ich ja in meiner asynctask klasse aufrufen.

1public class LogbookTask extends AsyncTask<String, Void, Boolean> {
2 private Throwable occurredProblem;
3
4
5
6
7 @Override
8 protected Boolean doInBackground(String args[]) {
9 Main variable = new Main ();
10 return null;
11
12 }
13
14
15 public boolean postRequest(String a, String b, String c){

ohman das is mir echt peinlich hier schon wieder herrumzufragen :D
Ich weiß das meine protected Boolean funktion immernoch fehlerhaft ist. Aber wo liegt mein fehler gerade :/

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

02.11.2012, 11:56:58 via Website

Guck mal in meine Code Snippets zum Thema AsyncTask zwei Bretter weiter. Dort nutze ich immer einen Konstruktor im AsyncTask.

Nachtrag: Die relevanten Zeilen folgen hier. Zunächst der Konstruktor im AsyncTask. Diesen musst Du natürlich an Deine Bedürfnisse anpassen (Parameter). Diese stehen Dir dann in der gesamten Klasse - auch im doInBackground zur Verfügung:

1public MyAsyncTask(int task_id, Context context, OnAsyncTaskCompletedListener listener) {
2 super();
3
4 this.context = context;
5 this.task_id = task_id;
6 this.listener = listener;
7}

Und hier der Aufruf - auch hier die Parameter an Deine Bedürfnisse anpassen:

1task = new MyAsyncTask(1, this, this);
2task.execute();

— geändert am 02.11.2012, 12:01:07

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

09.11.2012, 09:46:31 via Website

gut soweit klappt alles. Das Post-Feld soll nun folgenden Aufbau haben :
terminalData=1;5;<Variable1>;<Variable2>;<Variable3>;<Variable4>[,(ein oder mehrere weitere Datensätze]

Hierfür benutze ich doch am besten ein JSON Array um das Postfeld so aufzubauen oder habe ich da etwas falsch verstanden?

imoment benutze ich ja :
nameValuePairs
meine daten die momentan auf der seite ankommen die ich verschike sehen ja noch so aus :
06.11.2012 12:55:59 >>

Array
(
[privat] => Beginn
[km:] => 123434
)

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

09.11.2012, 10:52:13 via Website

also ich habe nur die angaben von meinen mitarbeiter bekommen das halt nur Daten aus einem Post request agenommen werden. und das der das Post-Feld den allgemeinen Aufbau hat der so ausehen soll :
terminalData=1;5;<Variable1>;<Variable2>;<Variable3>;<Variable4>[,(ein oder mehrere weitere Datensätze]


mehr infos hab ich leider auch nich bekommen da der kollege seit mittwoch die restliche woche Urlaub hat^^
und soweit ich mich infomiert habe soll ja angeblich ein JSON Array helfen, da ich das noch nich sooo verstehe wollte ich aber erstmal nachfragen ob ich da auf dem richtigen weg bin bevor ich mir das den restlichen tag anschaue und probiere^^

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

09.11.2012, 10:59:40 via Website

Ach so, das sind nur zwei Variablen - was spricht gegen die ValuePairs? Das ist für Dich als Versender die einfachste Lösung. Ob das geschickt ist wäre dann eine andere Frage. Aber das würde ich mit Deinem Mitarbeiter besprechen.

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

09.11.2012, 11:15:55 via Website

nene also variablen habe ich momentan 4. ich habe 2 eingabefelder und 2 spinner die ich als String an meine Netzwerkmethode weitergebe.

mich irritiert der aufbau nur ein wenig^^
: terminalData=1;5;<Variable1>;<Variable2>;<Variable3>;<Variable4>[,(ein oder mehrere weitere Datensätze]

wenn so der postfeld aufbau sein soll geht doch eig kein namevaluepair weil dort doch immer nur

a => b
c => d

Ich dachte ich muss iwie ein array machen zb al

al.add(a);
al.add(b);
al.add(c);
al.add(d);

und das dann er post req versenden. da das aber so nicht ging hab ich ein wenig gegooglet und bin halt auf JSON gestoßen aber dann war das wohl die falsche richtung und ich warte lieber erstmal bis montag.

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

09.11.2012, 11:45:33 via Website

terminalData=1;5;<Variable1>;<Variable2>;<Variable3>;<Variable4>[,(ein oder mehrere weitere Datensätze]

Ich hatte da irrtümlich ein zweites '=' gesehen - deshalb vermutete ich zwei Parameter:

1terminalData=1;5
2irgendetwasanderes=<Variable1>;<Variable2>;<Variable3>;<Variable4>[,(ein oder mehrere weitere Datensätze]

Protokolle werden immer von zwei Seiten ausgehandelt. Deine zweite Seite hat gerade Urlaub. Es macht meines Erachtens wenig Sinn darüber zu diskutieren was das sein soll und wie es gehen sollte ohne die Gegenstelle zu fragen. Wir beide wissen nicht was die Gegenstelle bereits implementiert hat und wie viel Aufwand es bedeutet das zu ändern.

Meine Empfehlung: Warte ab bis die Gegenstelle wieder erreichbar ist.

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

13.11.2012, 13:50:53 via Website

Die Daten vom Terminal werden im POST-Feld terminalData vom CarBeacon an den
Server gesendet. Das Feld hat den folgenden allgemeinen Aufbau:

terminalData=1;5;<RFID>;<K-Stand>;<K-Stelle>;<Purpose>;
<Login>[,(ein oder mehrere weitere Datensätze)]

Wird mehr als ein Datensatz im POST-Feld übertragen, so wird dieser durch ein
Komma vom vorherigen Datensatz getrennt.

Bedeutung der einzelnen Datenfelder für TeminalTyp 1

Feld-Nr. = Beschreibung
xxxxx = Kennung
K-Stand = Kilometerstand(variable)
k-Stelle = Kostenstelle(variable)
purpose = Fahrtgrund(mein ersrter spinner)
Login = Arbeitsbeginn/ende(Mein 2ter spinner

Beispiel mit einem Datensatz:

terminalData=1;5;834BA42DCF;118236;123456;3;1


das habe ich nun geschcikt bekommen

— geändert am 13.11.2012, 13:52:29

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

16.11.2012, 09:17:39 via Website

das ist ja jetzt 1 einzgier strang der halt aus mehreren variablen besteht richtig?:D also kein namevaluepair.



und als 2te Frage. kann ich beim Programmieren die IMEI oder MAC Adresse iwie auslesen und die auch als Variable Speichern und versenden?
das die gegenstelle sofort sieht ah da sendet benutzer xy?

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

16.11.2012, 11:32:58 via Website

aber wenn ich bei
nameValuePairs.add(new BasicNameValuePair(a, b, c)); eingebe zb kommt ja : The constructor BasicNameValuePair(String, String, String) is undefined
und er will es wieder auf (string , String) setzen wie soll man mit namevaulepairs einen datenstrang hinbekommen mit 4 variable ohne es so zu machen
: nameValuePairs.add(new BasicNameValuePair(a, b));
nameValuePairs.add(new BasicNameValuePair(c, d));

Antworten
Marc Schumacher
  • Forum-Beiträge: 14

16.11.2012, 11:42:29 via Website

ja das is mir schon klar deswegen dachte ich aj das ich etwas anderes bentuzen muss um den datenstrang so zu basteln wie er vorgegeben ist:

terminalData=1;5;<RFID>;<K-Stand>;<K-Stelle>;<Purpose>;
<Login>[,(ein oder mehrere weitere Datensätze)]


also sollte ich den strang einfach mit valuepairs nutzen zb :
nameValuePairs.add(new BasicNameValuePair("1","5"));
nameValuePairs.add(new BasicNameValuePair(RFID, K-Stand));
nameValuePairs.add(new BasicNameValuePair(K-Stelle, Purpose));

Antworten