Daten an die Service Klasse übergeben?

T

the_time

Ambitioniertes Mitglied
0
Hallo,
ich versuche gerade JSON string an die PostData klasse von - onLocationChanged() der inneren Klasse "MyLocationListener" in der MainActivity- zu übergeben mithilfe von Intent aber ich kriege null für "jSONString" in der onHandleIntent() methode. weißt jemand was noch fehlt um es hinzubekommen?
Das sind die Daten in der Variable "String jSONString = convertToJSON(pLong, pLat, formatted);" drin:

PHP:
{"latitude":50.86898824,"longitude":15.66546405,"formatted":"23.04.2015 16:36:11","route":4}
Dieser Teil vom Code wird in der onLocationChanged()- MyLocationListener (inner class)- MainActivity aufgerufen:

PHP:
                String jSONString = convertToJSON(pLong, pLat, formatted);        
                Intent intent3 = new Intent(MainActivity.this, PostData.class);
                intent3.putExtra("json_data", jSONString);
                PendingIntent pintent3 = PendingIntent.getService(getApplicationContext(), 0, intent3, 0);
                AlarmManager alarm3 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                Calendar cal = Calendar.getInstance();
                // for 30 mint 60*60*1000
                alarm3.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                        1000, pintent3);
                startService(intent3);
PostData Klasse:

PHP:
public class PostData extends IntentService {


    public PostData() {
        super("some");

    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // TODO Auto-generated method stub
        String jSONString = intent.getStringExtra("json_data");
        try {
            // This is the ip address of my laptop wifi because I am running the
            // app in my device and I want to send the data to the localhost
            // server(WAMP).
            URL myUrl = new URL("http://192.168.x.x/webservice");
            HttpURLConnection myConnection = (HttpURLConnection) myUrl
                    .openConnection();
            myConnection.setRequestMethod("POST");
            myConnection.setDoOutput(true);
            myConnection.setUseCaches(false);
            myConnection.setConnectTimeout(10000);
            myConnection.setReadTimeout(10000);
            myConnection.setRequestProperty("Content-Type", "application/json");
            myConnection.connect();
            // create data output stream
            DataOutputStream wr = new DataOutputStream(
                    myConnection.getOutputStream());
            // write to the output stream from the string
            wr.writeBytes(jSONString);
            wr.close();
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

}
 
ich kenne mcih nciht gut aus deswegen bitte um nachsicht....
aber kann es sein dass vllt etwas fehlschlägt weil du evtl. sachen die nciht serialisiert werden können versucht zu serialisieren eben?
 
Eigentlich die daten habe ich mit GSon bibliothek serialuiert und ich kann sie in der jSONString variable sehen. Ich habe eben versucht es zu debugen und ich sehe die daten im "jSONString " aber wenn der debugger unten bei der startService(intent3) ist, hat intent3 immer noch null!
 
ok ich hab mir mal die API angesehen
und ->string - Android Intent.getStringExtra() returns null - Stack Overflow

also dein json string ist ja ein String deswegen ist es richtig

die methode

intent3.putExtra("json_data", jSONString);

sollte diesen string auch rein packen, da du die value richtig angezeigt bekommst des jsonstrings, soltle da auch alles in ordnung sein...warum dein intent immer noch null ist kann ich auch nciht verstehen....

intent3=intent3.putExtra(...); wäre quatsch oder?
 
Kann es sein das
Code:
intent3.putExtra("json_data", jSONString); << noch da
PendingIntent pintent3 = PendingIntent.getService(getApplicationContext(), 0, intent3, 0); << danach weg ?

pintent3 deutet daraufhin, das du mehrere PendingIntent hast ? Wenn ja,
mach die mal "eindeutig" (brauchst du wirklich verschiedene, oder unterscheiden die sich nur im "Extra" ?):
Code:
PendingIntent pintent3 = PendingIntent.getService(getApplicationContext(), [B][U][COLOR="Red"]3[/COLOR][/U][/B], intent3, 0);

Aus der Doku:
A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen.

Könnte mir vorstellen, das du immer erwartest, ein anderes Intent zu bekommen, tatsächlich aber immer
das gleiche bekommst (das ?evtl. überschrieben? wird / ?nicht initialisiert? ist)

Ich hab in einer App mal 4 PendingIntents gebraucht und mich auch gewundert, warum da immer "nix" ankam.
Ist schlecht dokumentiert, hab dann irgendwo bei Stackoverflow mal den richtigen Tipp gelesen, das man denen einen unterschiedlichen Requestcode mitgeben muss, sonst überbügelt man scheinbar immer den selben.
 
Zuletzt bearbeitet:
Sorry ich habe mich geirrt die Daten sind in Intent3-mExtra-mMap-[1] drin :) aber wieso kriege ich in onHandelIntent() für jSOnString null?

Der ursprüngliche Beitrag von 18:13 Uhr wurde um 18:46 Uhr ergänzt:

Ich habe diese Zeile so geändert aber es macht keinen Unterschied und ich benutze PendingIntent hier weil ich es irgendwo bei stackoverflow mit im code gefunden habe :)
PHP:
 PendingIntent pintent3 = PendingIntent.getService(getApplicationContext(), 3, intent3, 0);

wenn ich ich intent3 vor startService ausgebe, kriege ich null raus. Ich weiß nicht ob die Daten jetzt richtig drin sind oder nicht aber wie gesagt die sind im intent3- mextra-mMap-mArray-[1] drin und ich kann sie sehen.
 
Also, mir ist noch nicht so richtig klar geworden, was du eigentlich machen willst.
Willst du nun deine Postdata direkt per startservice() aufrufen oder via Alarmmanager zu einem späterem Zeitpunkt ?
Scheint mir irgendwie doppelt gemoppelt ?
du solltest erstmal rauskriegen, ab wann dein jsonstring weg ist.
Ich würde mal diese Zeilen
Code:
PendingIntent pintent3 = PendingIntent.getService(getApplicationContext(), 0, intent3, 0);
AlarmManager alarm3 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
// for 30 mint 60*60*1000
alarm3.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1000, pintent3);
auskommentieren und dann debuggen und den Haltepunkt auf
Code:
public int onStartCommand(Intent intent, int flags, int startId) {

        return super.onStartCommand(intent, flags, startId);
    }
die returnzeile setzen. Kommt da dann der String im Intent an ?
 
Ich will die Daten an der Server jede 60 Sekunden schicken, darum benutze ich hier den AlarmManager. Ich habe die Zeilen auskommentiert(es hat nicht geholfe) aber nachdem ich mein Projekt gecleant habe, kommen die Daten in "onHandleIntent()" an aber was ich gemerkt habe dass sich die Daten sie jede 10 sekunden von null auf "jSONString-Daten" änderen darum habe ich den Code dort in diese if Bedingung if(jSONString != null){// der code}else{System.out.println("There is no Data available!");}gepackt und ich kriege in der Logcat den JSONString und "There is no Data available!" an derselben Zeit jede 10 sekunden!? was hat das zu bedeuten ?

hier ist ein Beispiel von der Logcat:

PHP:
04-23 23:44:37.632: I/System.out(28460): There is no Data available!
04-23 23:44:37.642: I/System.out(28460): JSONSString output bla bla bla: {"latitude":55.86907815,"longitude":14.66554789,"formatted":"23.04.2015 18:37:49","route":4}

Es hört sich blöd an aber wenn ich den JSON string an die onHandelIntent() methode übergebe, kriege ich immer einen alten festen TimeStamp diesen hier "23.04.2015 18:37:49" also der formatted string ändert sich im JSON string !!! aber wenn ich hier "startService(intent3);" bin, ist die Zeit im intent3 noch richtig.
 
Zuletzt bearbeitet:
Ich kriege jetzt den JSON string im onHandleIntent aber da kriege ich einmal von mit der aktuellen Zeit "24.04.2015 11:21:36" und danach sofort einmal mit diesem timeStamp "23.04.2015 18:37:49" ich glaube es liegt an dem Service von intent Service. Kann man die queue irendwie löschen damit man die neuest JSON string bekommt?
 
wenn du also alle 60 sekunden an den server senden willst, warum rufst du denn dann
startService() manuell auf ? Ich könnte mir vorstellen, das sich da der Alarm
und dein manueller Start überlagern.

Ich kenn/mach das etwas anders:
1) wie du, pending event erstellen und in alarmmanger packen/Alarm setzen
2) Alarmreceiver-klasse erstellen, die eigentlich nur im onreceive den Alarm auswertet und
3) aus dem onreceive dann den Service starten

etwa so:
Alarm setzen:
Code:
final static int TypAutostart = 1;
long interval = AlarmManager.INTERVAL_DAY;
....

Intent aiAutostart = new Intent(getApplicationContext(), AlarmReceiver.class);
aiAutostart.putExtra("Extraname", extra);
piAutostart = PendingIntent.getBroadcast(getApplicationContext(), TypAutoStart, aiAutostart, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), interval, piAutostart);


Alarmreceiver (im Manifest registrieren!!)
Code:
public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

       Intent service1 = new Intent(context, AlarmService.class);
       service1 = new Intent(context, AlarmService.class);
       service1.putExtra("Extraname", intent.getStringExtra("Extraname"));
       context.startService(service1);
    }
}

Alarmservice (auch im Manifest reg. !!)
Code:
 ...
@Override
    public int onStartCommand(Intent intent, int startflag, int startId) {
        super.onStartCommand(intent, startflag, startId);

        if (intent.hasExtra("Extraname")) {
            // Aufgabe abarbeiten
        }
        return Service.START_NOT_STICKY;
}
...

ich mach im Receiver noch weitere Auswertungen des übergebenem Intent's,
und starte meinen Service auch nur einmal am Tag, aber
das Prinzip ist dasselbe und die obige Lösung funktioniert bei mir 1a.
 
ich habe deine Änderung umgesetzt aber ich kriege jetzt nur den alten timeStamp "23.04.2015 18:37:49" in der Ausgabe. Ich habe im Manifest folgendes:

PHP:
          <service android:name=".PostData" /> 
          
          <receiver android:name=".AlarmReceiver" >

Wäre es nicht besser die onHandleIntent() zu überschreiben?
 
Zuletzt bearbeitet:
1) feuert dein Alarm alle 60 sek ? (also, kommt alle 60 sek was beim service an ?
2) wann/wo befüllst du den json neu ? direkt nach dem befüllen den alarm feuern müsste klappen ?
Ich würd sagen, mach dir eine Methode "setzeAlarm(String jsondata)" (oder wie auch immer du die nennen willst),
in der du den Alarm setzt und "jsondata" ins Extra des Intents legst.
dann dort, wo du befüllst
Code:
String jSONString = convertToJSON(pLong, pLat, formatted);
setzeAlarm(jSONString);

ich hab gerade noch mal "von vorn" gedacht:
hab ich das richtig, das du immer bei Locationchange gleich die änderung an den Server posten willst ?
Evtl. ist da der ganze Weg mit Alarmmanager, Receiver, PendingIntent, Service viel zu umständlich/fummelig ?
Das wäre evtl. besser mit AsyncTask zu erledigen ?

Code:
public class UploadJson extends AsyncTask<String, Void, String> {

.....
    @Override
    protected String doInBackground(String... urls) {
        try {
            // This is the ip address of my laptop wifi because I am running the
            // app in my device and I want to send the data to the localhost
            // server(WAMP).
            URL myUrl = new URL("http://192.168.x.x/webservice");
            HttpURLConnection myConnection = (HttpURLConnection) myUrl
                    .openConnection();
            myConnection.setRequestMethod("POST");
            myConnection.setDoOutput(true);
            myConnection.setUseCaches(false);
            myConnection.setConnectTimeout(10000);
            myConnection.setReadTimeout(10000);
            myConnection.setRequestProperty("Content-Type", "application/json");
            myConnection.connect();
            // create data output stream
            DataOutputStream wr = new DataOutputStream(
                    myConnection.getOutputStream());
            // write to the output stream from the string
            wr.writeBytes(jSONString);
            wr.close();
        } catch (IOException e) {

            e.printStackTrace();
        }
    }

....

}

startest du dann mit
Code:
UploadJson uj= new UploadJson ();

...

uj.execute(jsondata);

so ungefähr, hab den async nur aus dem kopf geschrieben, aber ich denk, das wäre evtl. der einfachere/bessere weg, deinen json an den server zu senden ?
 
Ja eigentlich habe ich das mit AsyncTask und timer vorgestern gemacht und esklappt alles sehr gut aber ich habe irgendwo gelesen dass es besser so was r mit service und AlarmManager zu unmsetzen ist aber ich bleibe jetzt bei AsynTask :) Danke für eure Hilfe.
 

Ähnliche Themen

FabianDev
Antworten
5
Aufrufe
575
swa00
swa00
A
Antworten
10
Aufrufe
1.029
swa00
swa00
M
Antworten
8
Aufrufe
960
deek
D
Zurück
Oben Unten