Remote Service läuft nicht im Hintergrund weiter!

  • Antworten:14
Frank Runte
  • Forum-Beiträge: 4

01.06.2013, 08:24:29 via Website

Hallo zusammen, ich bin neu hier und auch neu bei der App Programmierung unter Java. Ich habe bisher hauptsächlich unter VB.NET und VBA gearbeitet, habe also schon Erfahrungen sammeln können.

Für das was ich mit dieser App realisieren möchte benötige ich einen Hintergrundprozess mit dem ich die Sensoren aufzeichen möchte (Datenlogger). Ich habe nun ein Beispiel gefunden und rumexperimentiert, es funktioniert soweit einwandfrei, aber wenn das Smartphone einschläft hört der Remoteprozess auch auf, er soll aber weiterlaufen.
Wie kann ich das ändern?

Es wäre total klasse wenn mir jemand auf die Sprünge helfen könnte.

Wenn ihr noch Informationen benötigt liefere ich diese natürlich.

Vielen Dank vom Frank ;-)).

Hier mal die drei wichtigsten Dateien.
Das Manifest
1<?xml version="1.0" encoding="utf-8"?>
2<manifest xmlns:android="htt://schemas.android.com/apk/res/android"
3 package="com.collabera.labs.sai"
4 android:versionCode="1"
5 android:versionName="1.0">
6 <application android:icon="@drawable/icon" android:label="@string/app_name">
7 <activity android:name=".RemoteServiceClient"
8 android:label="@string/app_name">
9 <intent-filter>
10 <action android:name="android.intent.action.MAIN" />
11 <category android:name="android.intent.category.LAUNCHER" />
12 </intent-filter>
13 </activity>
14 <service android:name="com.collabera.labs.sai.RemoteService" android:process=":remote">
15 <intent-filter>
16 <action android:name="com.collabera.labs.sai.IMyRemoteService" />
17 </intent-filter>
18 </service>
19
20 </application>
21 <uses-sdk android:minSdkVersion="3" />
22</manifest>

Der Remoteservice:
1package com.collabera.labs.sai;
2
3import android.app.Service;
4import android.content.Intent;
5import android.hardware.Sensor;
6import android.hardware.SensorEvent;
7import android.hardware.SensorEventListener;
8import android.hardware.SensorManager;
9import android.os.Handler;
10import android.os.IBinder;
11import android.os.RemoteException;
12import android.util.Log;
13
14public class RemoteService extends Service implements SensorEventListener{
15
16 private SensorManager mSensorManager;
17 private Sensor mAccelerometer;
18 private Handler serviceHandler;
19 private int Angle;
20 private int MaxAngleRight;
21 private int MaxAngleLeft;
22 //private string Angles;
23 private Task myTask = new Task();
24
25 public void SensorActivity() {
26 }
27 @Override
28 public IBinder onBind(Intent arg0) {
29 Log.d(getClass().getSimpleName(), "onBind()");
30 return myRemoteServiceStub;
31 }
32
33 private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
34 public int getAngle() throws RemoteException {
35 return Angle;
36 }
37
38 @Override
39 public int getMaxAngleRight() throws RemoteException {
40 // TODO Auto-generated method stub
41 return MaxAngleRight;
42 }
43
44 @Override
45 public int getMaxAngleLeft() throws RemoteException {
46 // TODO Auto-generated method stub
47 return MaxAngleLeft;
48 }
49 };
50
51 @Override
52 public void onCreate() {
53 super.onCreate();
54 Log.d(getClass().getSimpleName(),"onCreate()");
55 }
56
57 @Override
58 public void onDestroy() {
59 super.onDestroy();
60 serviceHandler.removeCallbacks(myTask);
61 serviceHandler = null;
62 Log.d(getClass().getSimpleName(),"onDestroy()");
63 }
64
65 @Override
66 public void onStart(Intent intent, int startId) {
67 super.onStart(intent, startId);
68 MaxAngleRight=0;
69 MaxAngleLeft=0;
70 serviceHandler = new Handler();
71 serviceHandler.postDelayed(myTask, 1000L);
72 mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
73 mAccelerometer= mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
74 mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
75 Log.d(getClass().getSimpleName(), "onStart()");
76 }
77
78 class Task implements Runnable {
79 public void run() {
80 serviceHandler.postDelayed(this,1000L);
81
82 Log.i(getClass().getSimpleName(), "Incrementing counter in the run method");
83 }
84 }
85
86 @Override
87 public void onAccuracyChanged(Sensor arg0, int arg1) {
88 // TODO Auto-generated method stub
89
90 }
91
92 @Override
93 public void onSensorChanged(SensorEvent arg0) {
94 // TODO Auto-generated method stub
95 //counter=arg0.timestamp;
96 Angle=(int) arg0.values[2];
97
98 if (Angle *-1 > MaxAngleRight){
99 MaxAngleRight=Angle*-1;
100 }
101
102 if (Angle > MaxAngleLeft){
103 MaxAngleLeft=Angle;
104 }
105
106 }
107}

Die Activity:
1package com.collabera.labs.sai;
2
3import android.app.Activity;
4import android.content.ComponentName;
5import android.content.Context;
6import android.content.Intent;
7import android.content.ServiceConnection;
8import android.os.Bundle;
9import android.os.IBinder;
10import android.os.RemoteException;
11import android.util.Log;
12import android.view.View;
13import android.view.View.OnClickListener;
14import android.widget.Button;
15import android.widget.TextView;
16import android.widget.Toast;
17
18public class RemoteServiceClient extends Activity {
19
20 private IMyRemoteService remoteService;
21 private boolean started = false;
22 private RemoteServiceConnection conn = null;
23
24 /** Called when the activity is first created. */
25 @Override
26 public void onCreate(Bundle savedInstanceState) {
27 super.onCreate(savedInstanceState);
28 setContentView(R.layout.remoteserviceclient);
29
30 Button start = (Button)findViewById(R.id.startButton);
31 Button stop = (Button)findViewById(R.id.stopButton);
32 Button bind = (Button)findViewById(R.id.bindButton);
33 Button release = (Button)findViewById(R.id.releaseButton);
34 Button invoke = (Button)findViewById(R.id.invokeButton);
35
36 start.setOnClickListener(new OnClickListener() {
37 public void onClick(View v){
38 startService();
39 }
40 });
41
42 stop.setOnClickListener(new OnClickListener() {
43 public void onClick(View v){
44 stopService();
45 }
46 });
47
48 bind.setOnClickListener(new OnClickListener() {
49 public void onClick(View v){
50 bindService();
51 }
52 });
53
54 release.setOnClickListener(new OnClickListener() {
55 public void onClick(View v){
56 releaseService();
57 }
58 });
59
60 invoke.setOnClickListener(new OnClickListener() {
61 public void onClick(View v){
62 invokeService();
63 }
64 });
65
66
67 }
68
69 private void startService(){
70 if (started) {
71 Toast.makeText(RemoteServiceClient.this, "Service already started", Toast.LENGTH_SHORT).show();
72 } else {
73 Intent i = new Intent();
74 i.setClassName("com.collabera.labs.sai", "com.collabera.labs.sai.RemoteService");
75 startService(i);
76 started = true;
77 updateServiceStatus();
78 Log.d( getClass().getSimpleName(), "startService()" );
79 }
80
81 }
82
83 private void stopService() {
84 if (!started) {
85 Toast.makeText(RemoteServiceClient.this, "Service not yet started", Toast.LENGTH_SHORT).show();
86 } else {
87 Intent i = new Intent();
88 i.setClassName("com.collabera.labs.sai", "com.collabera.labs.sai.RemoteService");
89 stopService(i);
90 started = false;
91 updateServiceStatus();
92 Log.d( getClass().getSimpleName(), "stopService()" );
93 }
94 }
95
96 private void bindService() {
97 if(conn == null) {
98 conn = new RemoteServiceConnection();
99 Intent i = new Intent();
100 i.setClassName("com.collabera.labs.sai", "com.collabera.labs.sai.RemoteService");
101 bindService(i, conn, Context.BIND_AUTO_CREATE);
102 updateServiceStatus();
103 Log.d( getClass().getSimpleName(), "bindService()" );
104 } else {
105 Toast.makeText(RemoteServiceClient.this, "Cannot bind - service already bound", Toast.LENGTH_SHORT).show();
106 }
107 }
108
109 private void releaseService() {
110 if(conn != null) {
111 unbindService(conn);
112 conn = null;
113 updateServiceStatus();
114 Log.d( getClass().getSimpleName(), "releaseService()" );
115 } else {
116 Toast.makeText(RemoteServiceClient.this, "Cannot unbind - service not bound", Toast.LENGTH_SHORT).show();
117 }
118 }
119
120 private void invokeService() {
121 if(conn == null) {
122 Toast.makeText(RemoteServiceClient.this, "Cannot invoke - service not bound", Toast.LENGTH_SHORT).show();
123 } else {
124 try {
125 int AkAngle = remoteService.getAngle();
126 int MaxAngleRight = remoteService.getMaxAngleRight();
127 int MaxAngleLeft = remoteService.getMaxAngleLeft();
128 String Angles = "Aktuell:"+Integer.toString(AkAngle)+" Max Links:"+Integer.toString(MaxAngleLeft)+" Max Rechts:"+Integer.toString(MaxAngleRight);
129
130 TextView t = (TextView)findViewById(R.id.notApplicable);
131 t.setText(Angles );
132 Log.d( getClass().getSimpleName(), "invokeService()" );
133 } catch (RemoteException re) {
134 Log.e( getClass().getSimpleName(), "RemoteException" );
135 }
136 }
137 }
138
139
140 class RemoteServiceConnection implements ServiceConnection {
141 public void onServiceConnected(ComponentName className,
142 IBinder boundService ) {
143 remoteService = IMyRemoteService.Stub.asInterface((IBinder)boundService);
144 Log.d( getClass().getSimpleName(), "onServiceConnected()" );
145 }
146
147 public void onServiceDisconnected(ComponentName className) {
148 remoteService = null;
149 updateServiceStatus();
150 Log.d( getClass().getSimpleName(), "onServiceDisconnected" );
151 }
152 };
153
154 private void updateServiceStatus() {
155 String bindStatus = conn == null ? "unbound" : "bound";
156 String startStatus = started ? "started" : "not started";
157 String statusText = "Service status: "+
158 bindStatus+
159 ","+
160 startStatus;
161 TextView t = (TextView)findViewById( R.id.serviceStatus);
162 t.setText( statusText );
163 }
164
165 protected void onDestroy() {
166 super.onDestroy();
167 releaseService();
168 Log.d( getClass().getSimpleName(), "onDestroy()" );
169 }
170
171}

Antworten
Frank Runte
  • Forum-Beiträge: 4

02.06.2013, 08:30:35 via Website

Danke für die Antwort.

Ich glaube du hast mein anliegen falsch interpretiert !
Ich möchte nicht verhindern das das gerät in den Standby modus wechselt,
das ist sogar eher gewünscht, aber der Prozess soll weiter laufen.
Ähnlich einem MP3 Player der auch im Hintergrund weiter macht.

Vieleich hat ja sonst noch jemand eine Idee.
Ist das vom Aufbau überhaupt ein Remoteprozess mit IPC und RCP oder ist es eine Localprozsstruktur?

Vielen Dank vom Frank.

Antworten
Andy N.
  • Forum-Beiträge: 3.112

02.06.2013, 12:28:37 via Website

Das ist aber genau Dein Problem. Der Service kann nicht weiter laufen, wenn der CPU in Standby geht, bzw. Android schließt alle unnötigen Prozesse.

Auch der MediaPlayer wird im Standby unterbrochen, wenn man es nicht explicit verhindert:
http://developer.android.com/reference/android/media/MediaPlayer.html#setWakeMode(android.content.Context, int)

— geändert am 02.06.2013, 12:28:49

Antworten
Frank Runte
  • Forum-Beiträge: 4

04.06.2013, 09:21:18 via Website

Entschuldigt bitte meine vorschnelle Antwort.
Wenn man um Hilfe bittet sollte man die Anwort erstmal verstehen befor man diese kommentiert. Sorry !

Wenn ich das richtig verstehe, bedeutet Remoteprozess nur das dieser auch ohne Activity also Oberfläche weiterlläuft.
Um diesen über den Standby hinaus am leben zu erhalten muss man diese Wake Lock funktion verwenden.

Das habe ich nun verstanden.
Dummerweise verstehe ich noch nicht wie ich diese Wake Lock funktion verwenden muss.

Was mir auch noch auffgefallen ist, die Sensoren werden im Standby ebenfalls abgeschaltet.
Werden diese über Wake Lock mit am leben erhalten oder schalten die trotzdem ab ? bzw. wie kann ich sie aktiv halten.

Vielen dank für eure gedult.

Gruß Frank.

— geändert am 04.06.2013, 12:49:26

Antworten
Michele
  • Forum-Beiträge: 1.525

04.06.2013, 14:46:50 via Website

Frank...

Erst Google, dann fragen. Das tue ich auch.

Ich habe dir was gezeigt.
http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
Dann hättest du danach suchen können.

1PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
2PowerManager.WakeLock wakeLock = pm.newWakeLock(
3 pm.SCREEN_DIM_WAKE_LOCK, "My wakelook");
4// This will make the screen and power stay on
5// This will release the wakelook after 1000 ms
6wakeLock.acquire(1000);
7
8// Alternative you can request and / or release the wakelook via:
9// wakeLock.acquire(); wakeLock.release();

1Any application using a WakeLock must request the android.permission.WAKE_LOCK permission in an <uses-permission> element of the application's manifest.



LG

— geändert am 04.06.2013, 14:53:02

Antworten
Michele
  • Forum-Beiträge: 1.525

04.06.2013, 15:05:22 via Website

Aber eins muss ich dazu sagen.

Er will es im Standby am leben halten.

WakeLock ist doch nur dafür da das der Screen nicht ausgeht. Also dauerhaft an.

Also tut doch der WakeLock das garnicht was er eigentlich will.

Habe den WakeLock eben auch mal getestet usw.

EDIT: Ok vielleicht reicht es doch dafür aus
Denn:
1PARTIAL_WAKE_LOCK = CPU ON, SCREEN OFF, KEYBOARD OFF
1*If you hold a partial wake lock, the CPU will continue to run, regardless of any display timeouts or the state of the screen and even after the user presses the power button. In all other wake locks, the CPU will run, but the user can still put the device to sleep using the power button.


LG

— geändert am 04.06.2013, 15:10:51

Antworten
impjor
  • Forum-Beiträge: 1.793

04.06.2013, 15:28:49 via App

Wakelock zu verwenden, um den Screen nicht auszuschlachten ist Ressourcen schädlich. Da lieber FLAG_KEEP_SCREEN_ON benutzten.

Aber das will der TE ja gar gar nicht, oder?

Gruß

— geändert am 04.06.2013, 15:29:21

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Antworten
Michele
  • Forum-Beiträge: 1.525

04.06.2013, 15:37:34 via Website

Naja wie ich eben geschrieben habe kannste auch den Screen ausgehen lassen.
Aber der CPU bleibt IMMER an.

1PARTIAL_WAKE_LOCK = CPU ON, SCREEN OFF, KEYBOARD OFF

Also müsste das reichen für Ihn.


LG

Antworten
Frank Runte
  • Forum-Beiträge: 4

04.06.2013, 21:04:42 via Website

Hallo zusammen,
schön das eine solche Beteiligung entstanden ist.
@Michele: Ich habe geGoogled aber ich habe es nicht verstanden und mein Englisch ist leider auch nicht das beste was beim lesen von Englischen Examples nicht hilft. Mittlerweile habe ich probiert / experimentiert und habe es im groben verstanden.

So mancher von euch Cracks setzt etwas viel vorraus, wenn ich alles könnte würde ich nicht fragen.
Und gerade wenn es hardware nah wird, wird es oft auch komplzierter.

So wie mein nächstes Problem.
Die Sensoren werden im Standby anscheined abgeschaltet.
Ich habe folgendes gefunden,

h t t p s://sites.google.com/a/bug-br.org.br/android/technical-documents/sensors-and-standby-mode

aber irgendwie bekomme ich es nicht implementiert. Scheint aber ein Syntaxfehler zu sein.
Ich werde noch etwas rumbasteln und wenn ich nicht weiterkomme mach ich einen neuen Thread auf.

Vielen Dank an alle die sich beteiligen.
Gruß Frank

Antworten
Michele
  • Forum-Beiträge: 1.525

04.06.2013, 21:07:48 via Website

Mein Englisch ist auch nicht so gut.

Aber sogar Google lässt es gerne für dich übersetzen :D
Sowas solltest du wissen.


LG

Antworten