简体   繁体   English

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

[英]NULL object reference error on receiving broadcast from a service in android

I have created a simple activity-service android app in which I call the service periodically using alarmmanager . 我创建了一个简单的活动服务android应用程序,在其中我使用alarmmanager定期调用该服务。 In the service, I capture values from accelerometer sensor and light sensor , put them in a broadcast and broadcast the intent. 在服务中,我从accelerometer传感器和light sensor捕获值,并将它们放到广播中并广播意图。 In my MainActivity , I receive the broadcast and try to show the sensor values. MainActivity ,我收到广播并尝试显示传感器值。 But I keep getting a NUll Obect Reference Error . 但是我一直收到NUll Obect Reference Error I LOGCAT the sensor values in the service to check if the sensor values are being captured and I get a output. LOGCAT传感器值在服务检查,如果被捕捉的传感器值,我得到一个输出。 Is is only when I try to access them via a returned intent in the main activity I get the error. 仅当我尝试通过主活动中返回的意图访问它们时,才出现错误。 I have tried to debug it a lot but really can't fathom where my logic is going wrong. 我已经尝试了很多调试,但是真的无法理解我的逻辑出了什么问题。 Following are the relevant code samples : 以下是相关的代码示例:

MainActivity.java 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 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");
    }
}

The count variable used in the Service.java is just so that the sensor runs twice before broadcasting the values. Service.java中使用的count变量仅仅是为了使传感器在广播值之前运行两次。 Any help is appreciated. 任何帮助表示赞赏。

You should be checking the Intent passed into onReceive() for your extras, not the Intent returned by getIntent() . 您应该检查的Intent传递到onReceive()您的演员,而不是Intent通过返回getIntent()

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

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

The getIntent() method is a member of the Activity class, and normally returns the Intent used to start the current Activity . getIntent()方法是Activity类的成员,并且通常返回用于启动当前ActivityIntent (Your anonymous BroadcastReceiver class is in the Activity 's scope, and therefore has access to that method.) (您的匿名BroadcastReceiver类在Activity的范围内,因此可以访问该方法。)

The Intent passed into the onReceive() method is the one that you broadcast with all your extras. 传递给onReceive()方法的Intent是您与所有附加内容一起广播的Intent

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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