我创建了一个简单的活动服务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
变量只是为了在传播值之前传感器运行两次。
任何帮助表示赞赏。
答案 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
是您使用所有附加内容广播的方法。