Problem mit Android Service

  • Antworten:3
Michael H.
  • Forum-Beiträge: 17

12.11.2012, 16:24:41 via Website

Hallo zusammen,

ich habe eine App in der ich eine Netwzwerkverbindung in einer Activtiy aufbaue. Ich möchte in jeder anderen Activity nicht neu verbinden müssen, sondern die Referenz auf die bestehende Verbindung erhalten. Diese Referenz ist in einer Variable
1m_netLinkIp
abgespeichert.

Aktuell baue ich die Verbindung über einen AsyncTask in jeder Activity auf, der Verbindungsaufbau dauert aber ca. 20 Sekunden und ist daher so nicht akzeptabel.

Ich habe nun herausgefunden, dass wohl die beste Lösung ein Android Service ist. Leider habe ich massive Probleme bei der Implementierung, momentan sieht er so aus:

1package de.bertrandt.bertrandtknx;
2
3import de.bertrandt.bertrandtknx.Controls.Dimmer;
4import tuwien.auto.calimero.link.KNXNetworkLinkIP;
5import tuwien.auto.calimero.process.ProcessCommunicator;
6import android.app.ProgressDialog;
7import android.app.Service;
8import android.content.Intent;
9import android.net.wifi.WifiInfo;
10import android.net.wifi.WifiManager;
11import android.os.AsyncTask;
12import android.os.IBinder;
13import android.os.RemoteException;
14import android.util.Log;
15import android.widget.Toast;
16
17public class ConnectionService extends Service {
18
19 private static final String TAG = "ConnectionService";
20 private static KNXNetworkLinkIP m_netLinkIp = null;
21 private static ProcessCommunicator m_pc = null;
22 private static boolean connection_ok;
23
24 @Override
25 public IBinder onBind(Intent intent) {
26 return null;
27 }
28
29 @Override
30 public void onCreate() {
31 //code to execute when the service is first created
32 new Connect().execute();
33 }
34
35 @Override
36 public void onDestroy() {
37 //code to execute when the service is shutting down
38 new Disconnect().execute();
39 }
40
41 @Override
42 public void onStart(Intent intent, int startid) {
43 //code to execute when the service is starting up
44 }
45
46 /**
47 * Connect Async
48 * */
49 private class Connect extends AsyncTask<String, Void, String> {
50 ProgressDialog dialog;
51 boolean ok;
52 @Override
53 protected String doInBackground(String... params) {
54 try {
55 //get local IP address
56 String ipAddress = getIpAddr();
57 System.out.println("WiFi address is " + ipAddress);
58
59 m_netLinkIp = Calimero.Util.connect(ipAddress, "192.168.0.2");
60
61 if (m_netLinkIp == null){
62
63 System.out.println("Can not connect to Demobard");
64 ok = false;
65 }
66 else{
67 System.out.println("Connected to Demoboard");
68 ok = true;
69
70 }
71 } catch (Exception e) {
72 e.printStackTrace();
73 }
74 return null;
75 }
76
77 @Override
78 protected void onPostExecute(String result) {
79 //dialog.dismiss();
80 Toast.makeText(getApplicationContext(),
81 "Verbindung mit Demoboard " +
82 ((ok == true) ? "hergestellt" : "fehlgeschlagen"), Toast.LENGTH_LONG).show();
83 if(ok == false){
84 //show reconnect dialog
85 //reconnect_dialog();
86 }
87 }
88
89 @Override
90 protected void onPreExecute() {
91 // Setup Progress Dialog
92 dialog = new ProgressDialog(Dimmer.this);
93 dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
94 dialog.setMessage("Bitte warten, verbinde mit KNX-Board");
95 dialog.setIndeterminate(true);
96 dialog.show();
97 }
98 }
99
100 /**
101 * GetIPAddress Async
102 * */
103 public String getIpAddr() {
104 WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
105 WifiInfo wifiInfo = wifiManager.getConnectionInfo();
106 int ip = wifiInfo.getIpAddress();
107
108 String ipString = String.format(
109 "%d.%d.%d.%d",
110 (ip & 0xff),
111 (ip >> 8 & 0xff),
112 (ip >> 16 & 0xff),
113 (ip >> 24 & 0xff));
114
115 return ipString.toString();
116 }
117
118 /**
119 * Disconnect Async
120 * */
121 private class Disconnect extends AsyncTask<String, Void, String> {
122 @Override
123 protected String doInBackground(String... params) {
124 try {
125 Calimero.Util.disconnect(m_netLinkIp);
126 } catch (Exception e) {
127 e.printStackTrace();
128 }
129 return null;
130 }
131
132 }
133
134}

Nun meine Fragen:

1.) Wie ruf ich den Service in meiner MainActivity auf und erhalte eine Referenz auf die
1m_netLinkIp
Variable? Im Moment ruf ich den Service so auf:
1Intent(this, ConnectionService.class));

2.) Mein AsyncTask beinhaltet einen Dialog, der den Context auf eine Activity benötigt? Wie erhalte ich die innerhalb des Services? Ich meine diese Zeile:
1dialog = new ProgressDialog(Dimmer.this);

3.) Gibt es eine einfachere Lösung als den Service für mein Problem?

Vielen Dank!

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

12.11.2012, 17:42:31 via Website

* Im Service solltest Du keinen Dialog verwenden. Ein Service ist ein Programmteil welcher üblicherweise im Background werkelt - und das auch ohne eine gerade sichtbare Activity.

* Zur Referenz auf den Service: Ich bin mir nicht 100% sicher was Du benötigst. Normalerweise reicht ein Bound-Service aus. Es kann aber Fälle geben in denen zum Beispiel die Activity eine Methode im Service aufrufen will und ein Ergebnis bekommen möchte. Ich habe das bisher erst einmal benötigt und habe das in einer Activity wie folgt gelöst:

Die Lösung ist "dreckig" und bestimmt nicht fein - aber sie funktioniert. Da der Start eines Service etwas Zeit beansprucht wird die Abfrage der Service-Instanz mit einer Sekunde Verzögerung gequeued.

1// Im Service
2 public class MyService extends Service {
3 public static final String TAG = "aa.bb.cc.MyService";
4
5 private static MyService instance;
6
7 public static MyService getInstance() {
8 return instance;
9}
10
11 @Override
12 public void onCreate() {
13 instance = this;
14 }
15
16 @Override
17 public void onDestroy() {
18 instance = null;
19
20 super.onDestroy();
21 }
22 }
23 }
24
25
26// in der Activity
27private MyService service;
28
29 Intent intent = new Intent(this, MyService.class);
30 intent.addCategory(MyService.TAG);
31 startService(intent);
32
33 new Handler().postDelayed(new Runnable() {
34
35 @Override
36 public void run() {
37 service = MyService.getInstance();
38 }
39 }, 1000);
40 }

— geändert am 12.11.2012, 17:44:54

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.11.2012, 17:43:03 via Website

Du kannst da nicht einfach drauf zugreifen! Aber z.b die die IP mittels Broadcast zusenden. Oder im Application Object speichern (schlechte wahl, da kaum zu handhaben).


Du kannst dir die sache aber auch einfacher machen und einen IntentService benutzen!

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Michael H.
  • Forum-Beiträge: 17

12.11.2012, 18:12:35 via Website

Danke erstmal! ich habe die 1.Frage so gelöst:
1public static KNXNetworkLinkIP m_netLinkIp = null;
und in den einzelne Activities kann ich mit
1startService(new Intent(this, ConnectionService.class));
2 m_netLinkIp= ConnectionService.m_netLinkIp;
drauf zugreifen!

Leider habe ich immer noch das Problem mit dem ProgressDialog.... Also muss ich diesen in der Activity erzeugen, aber woher weiß die Activity dann wann der Dialog beendet werden muss?

Antworten