简体   繁体   中英

Android: Broadcasting Sensor data from a Service to an Activity

I am trying to learn Android app development and wrote a very simple app consisting of an activity that calls a service. The service broadcasts measured acceleration to the activity. The problem is that the service runs ok but it does not send data back to the activity. ie, onReceive on my receiver is never called. Also, when the activity ends, there is an exception saying that my receiver has not been registered. Below is my code for the service, activity and manifest.xml. Any help would be very much appreciated.

Activity calling service:

package com.practice;
import com.practice.SimpleService;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;

public class ServiceActivity extends Activity {
MyReceiver myReceiver=null;
Intent i;
static final String LOG_TAG = "ServiceActivity";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    Log.d( LOG_TAG, "onCreate" );
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.main);

    //Start service 
    i= new Intent(this, com.practice.SimpleService.class);
    Log.d( LOG_TAG, "onCreate/startService" );  
}
@Override 
public void onResume(){
    super.onResume();
    Log.d( LOG_TAG, "onResume/registering receiver" );  
    //Register BroadcastReceiver to receive accelerometer data from service
    //if (myReceiver == null){
        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();      
        intentFilter.addAction(SimpleService.MY_ACTION);
        startService(i);  
        registerReceiver(myReceiver, intentFilter);
    //}     
}

@Override 
public void onPause(){
    super.onPause();
    Log.d( LOG_TAG, "onPause/unregistering receiver" ); 
    stopService(i);

    if (myReceiver != null)unregisterReceiver(myReceiver);      
}

@Override
protected void onStop(){
    super.onStop();
    Log.d( LOG_TAG, "onStop" );
    if (myReceiver != null) unregisterReceiver (myReceiver);
    stopService(i);
}

private class MyReceiver extends BroadcastReceiver{
    static final String Log_Tag = "MyReceiver";
    @Override
    public void onReceive(Context arg0, Intent arg1){
        Log.d( LOG_TAG, "onReceive" );
        String measurement = arg1.getStringExtra("measurement");        
        System.out.println("I am here");
    }

}   

}

Service getting sensor data:

package com.practice;
import java.util.List;
import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.util.Log;
import android.widget.TextView;

public class SimpleService extends Service implements SensorEventListener{
 final static String MY_ACTION = "MY_ACTION";
   private TextView output;
   private String reading;
   private SensorManager mgr;
   private List<Sensor> sensorList;
   static final String LOG_TAG = "SimpleService";
   Intent intent = new Intent("com.practice.SimpleService.MY_ACTION");

   @Override
   //public void onStartCommand() {
   public void onCreate() {
      Log.d( LOG_TAG, "onStartCommand" );
      mgr = (SensorManager) getSystemService(SENSOR_SERVICE);
      sensorList = mgr.getSensorList(Sensor.TYPE_ACCELEROMETER);
      for (Sensor sensor : sensorList) {
         mgr.registerListener(this, sensor,
                 SensorManager.SENSOR_DELAY_NORMAL);
      }
   }

   @Override
   public void onDestroy() {
        Log.d( LOG_TAG, "onDestroy" );
        mgr.unregisterListener(this);       
        super.onDestroy();
   }

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // TODO Auto-generated method stub      
}

@Override
public void onSensorChanged(SensorEvent event) {
      Log.d( LOG_TAG, "onSensorChanged" );
      StringBuilder builder = new StringBuilder();

      for (int i = 0; i < event.values.length; i++) {
         builder.append("   [");
         builder.append(i);
         builder.append("] = ");
         builder.append(event.values[i]);
         builder.append("\n");
      }

      reading=builder.toString();

      //Send back reading to Activity
      intent.putExtra("measurement", reading);
      sendBroadcast(intent);        
}

}

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.practice"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="8" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".ServiceActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".SimpleService" ></service>
    </application>
</manifest>

Create a Custom Intent :

final static String MY_ACTION = "com.practice.SimpleService.MY_ACTION";

In Manifest.xml

<receiver android:name=".MyReceiver" android:enabled="true">
  <intent-filter>
     <action android:name="com.practice.SimpleService.MY_ACTION"></action>
  </intent-filter>
</receiver>

for more information for Custom Broadcast see Custom Intents and Broadcasting with Receivers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM