从android中的服务接收广播时出现NULL对象引用错误

时间:2015-11-14 01:33:43

标签: java android android-intent android-service android-broadcast

我创建了一个简单的活动服务Android应用程序,我使用alarmmanager定期调用该服务。在服务中,我从accelerometer传感器和light sensor捕获值,将它们放入广播并广播意图。在我的MainActivity中,我收到广播并尝试显示传感器值。但我一直在NUll Obect Reference Error。我LOGCAT服务中的传感器值来检查是否正在捕获传感器值并获得输出。只有当我尝试通过主活动中返回的意图访问它时,我才会收到错误。我试图调试它很多,但真的无法理解我的逻辑出错的地方。以下是相关的代码示例:

MainActivity.java

    // Define the callback for what to do when data is received
    private BroadcastReceiver testReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(LOG_TAG,"onReceive");
//            int resultCode = intent.getIntExtra("resultCode", RESULT_CANCELED);
            Intent returnIntent = getIntent();
            Bundle results = returnIntent.getExtras();
            float accelValue = results.getFloat("accelVal");
            float lightValue = results.getFloat("lightVal");
            Toast.makeText(MainActivity.this, accelValue + " " + lightValue, Toast.LENGTH_SHORT).show();
//            if (resultCode == RESULT_OK) {
//                String accelValue = results.getString("accelVal");
//                String lightValue = results.getString("lightVal");
//                Toast.makeText(MainActivity.this, accelValue + " " + lightValue, Toast.LENGTH_SHORT).show();
//            }
        }
    };

Service.java

public class MyService extends Service implements SensorEventListener{
    private static final String LOG_TAG = "MyService::";
    public static final String ACTION = "com.example.tyagi.smartalarm.MyService";
    int count=0;
    public MyService() {
    }

    private SensorManager sensorManager;    // this instance of SensorManager class will be used to get a reference to the sensor service.
    private Sensor mSensor,lSensor;         // this instance of Sensor class is used to get the sensor we want to use.
    private float[] mGravity;
    private float mAccel;
    private float mAccelCurrent;
    private float mAccelLast;
    float l;

    Intent in = new Intent(ACTION); // create an intent to broadcast.
    Bundle bundle = new Bundle();

    public void onAccuracyChanged(Sensor sensor,int accuracy){

    }

    //    // if sensor value is changes, change the values in the respective textview.
    public void onSensorChanged(SensorEvent event){
        Log.d(LOG_TAG, "onSensorChanged.");

//        in.putExtra("resultCode",Activity.RESULT_OK);
        /* check sensor type */
        if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
            Log.d(LOG_TAG, "onSensorChanged,accelerometer");
            count+=1;
            Log.d(LOG_TAG,"count :"+count);

            mGravity = event.values.clone();
            // assign directions
            float x=event.values[0];
            float y=event.values[1];
            float z=event.values[2];

            float x1=event.values[0];
            float y1=event.values[1];
            float z1=event.values[2];
            mAccelLast = mAccelCurrent;
            mAccelCurrent = (float)Math.sqrt(x*x + y*y + z*z);      // we calculate the length of the event because these values are independent of the co-ordinate system.
            float delta = mAccelCurrent - mAccelLast;
            mAccel = mAccel*0.9f + delta;

            if(mAccel >= 0)
            {
                bundle.putFloat("accelVal", mAccel);
//                in.putExtra("accelVal",Float.toString(mAccel));
            }
        }
        if(event.sensor.getType()==Sensor.TYPE_LIGHT)
        {
            l = event.values[0];
            bundle.putFloat("lightVal", l);
//            in.putExtra("lightVal",Float.toString(l));
        }
        in.putExtras(bundle);
        Log.d(LOG_TAG, "mAccel : " + Float.toString(mAccel));
        Log.d(LOG_TAG,"lightsensr : "+Float.toString(l));

        if(count ==2) {
            LocalBroadcastManager.getInstance(this).sendBroadcast(in);
            stopSelf();
        }

    }


    @Override
    public void onCreate() {
        super.onCreate(); // if you override onCreate(), make sure to call super().
        // If a Context object is needed, call getApplicationContext() here.
        Log.d("MyService", "onCreate");
        sensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);          // get an instance of the SensorManager class, lets us access sensors.
        mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);    // get Accelerometer sensor from the list of sensors.
        lSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);            // get light sensor from the list of sensors.
        sensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, lSensor, SensorManager.SENSOR_DELAY_NORMAL);
        mAccel = 0.00f;
        mAccelCurrent = SensorManager.GRAVITY_EARTH;
        mAccelLast = SensorManager.GRAVITY_EARTH;

    }

    public int onStartCommand(Intent intent, int flags, int startId){
        Log.d("MyService", "onStartCommand");

        return START_STICKY;
    }


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


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

Service.java中使用的count变量只是为了在传播值之前传感器运行两次。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

您应该检查Intent传入onReceive()的额外内容,而不是Intent返回的getIntent()

public void onReceive(Context context, Intent intent) {
    Log.d(LOG_TAG,"onReceive");

    //Intent returnIntent = getIntent();
    Bundle results = intent.getExtras();
    ...
}

getIntent()方法是Activity类的成员,通常会返回用于启动当前Intent的{​​{1}}。 (您的匿名Activity类位于BroadcastReceiver的范围内,因此可以访问该方法。)

传入Activity方法的Intent是您使用所有附加内容广播的方法。