Running an IntentService in BroadcastReceiver usin

2019-09-10 11:31发布

问题:

I want to call a Service in my Receiver class which extends BroadcastReceiver but the service didn't start and I got this error:

FATAL EXCEPTION: main java.lang.RuntimeException: Unable to
    start receiver com.example.ahmed.service.AlarmReceiver: 
    java.lang.NullPointerException: Attempt to invoke virtual 
    method 'java.lang.String 
    android.content.Context.getPackageName()' on a null 
    object reference

In my MainActivity, I call the alarm manager:

 // Calendar settings for AlarmReceiver
        Calendar cur_cal = new GregorianCalendar();
        cur_cal.setTimeInMillis(System.currentTimeMillis());//set the current time and date for this calendar
        Calendar cal = new GregorianCalendar();
        cal.add(Calendar.DAY_OF_YEAR, cur_cal.get(Calendar.DAY_OF_YEAR));
        cal.set(Calendar.HOUR_OF_DAY, 8);
        cal.set(Calendar.MINUTE, 07);
        cal.set(Calendar.SECOND, cur_cal.get(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND, cur_cal.get(Calendar.MILLISECOND));
        cal.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
        cal.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));

        // Retrieve a PendingIntent that will perform a broadcast
        alarmIntent = new Intent(this, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);

        AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30 * 1000, pendingIntent);


// When you click Start sensing button
    public void onSensingButtonClickedToStart(final View view) {
        if (!SensorEvent.isSensing) {
            SensorEvent.isSensing = true;

            manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            int interval = 10000;
            manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
            Toast.makeText(this, "Sensing On", Toast.LENGTH_SHORT).show();
        }
    }

    // when you click Stop sensing button
    public void onSensingButtonClickedToStop(final View view) {
        if (SensorEvent.isSensing) {

            manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            manager.cancel(pendingIntent);
            Toast.makeText(this, "Sensing Off", Toast.LENGTH_SHORT).show();
            SensorEvent.isSensing = false;
        }
    }

My Service

public class Sense8 extends IntentService {

    public static Accelerometer accelerometer;
    public static Gyroscope gyroscope;
    public static Light light;
    public static Magnetometer magnetometer;
    Context context;

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     */
    public Sense8(String name) {
        super(name);
    }

    public Sense8(){
        super("Sense8");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        Log.d("accelerometer.isSensing", SensorEvent.isSensing + "");
        if (accelerometer.isSensing) {
            accelerometer = new Accelerometer(context);
            gyroscope = new Gyroscope(context);
            light = new Light(context);
            magnetometer = new Magnetometer(context);
            Toast.makeText(context, "I'm running instead of some sensors being captured", Toast.LENGTH_SHORT).show();
            Log.d("toast", "I'm running instead of some sensors being captured");
            startSensing();
        }
    }

    public static void startSensing() {
        accelerometer.start();
        gyroscope.start();
        light.start();
        magnetometer.start();
    }

    public void stopSensing() {
        accelerometer.stop();
        gyroscope.stop();
        light.stop();
        magnetometer.stop();

    }
}

In my Receiver class, I only call the IntentService:

 @Override
    public void onReceive(Context c, Intent intent) {


        Intent service = new Intent(c, Sense8.class);
        c.startService(service);
}

But in vain, it doesn't even start and hit me directly with the above error

What am I doing wrong? Can someone help me implement this the right way.

EDIT

the guys gave me the right solution for the first problem but now I get the same error after pushing the sensing button

Here is the SensorEvent:

public class SensorEvent implements SensorEventListener {

    public static boolean isSensing;
    SensorManager mSensorManager;
    Sensor mSensor;
    DataWriter fileWriter;
    Constants.SensorType sensorType;
    Context context;


    private SensorEvent()
    {}

    private static SensorEvent INSTANCE = null;

    public static SensorEvent getInstance()
    {
        if (INSTANCE == null)
        {   INSTANCE = new SensorEvent();
        }
        return INSTANCE;
    }

    public static SensorEvent getInstance(Context context, Constants.SensorType sensorType)
    {
        if (INSTANCE == null)
        {   INSTANCE = new SensorEvent(context, sensorType);
        }
        return INSTANCE;
    }


    public SensorEvent(Context context, Constants.SensorType sensorType) {
        this.sensorType = sensorType;

        this.context = context;
        this.mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        this.mSensor = mSensorManager.getDefaultSensor(sensorType.getType());
      //  this.isSensing = true;
    }


    public void start() {
        isSensing = true;
        fileWriter = new DataWriter(sensorType);
        mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void stop() {
        try {
            fileWriter.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }
        isSensing = false;
    }


    @Override
    public void onSensorChanged(android.hardware.SensorEvent event) {

        try {
            if (isSensing) {
                fileWriter.append(event);

            } else {
                fileWriter.finish();
                mSensorManager.unregisterListener(this);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }


}

回答1:

just change :

 @Override 
    public void onReceive(Context c, Intent intent) {


        Intent service = new Intent(context, Sense8.class);
        context.startService(service);
} 

to

 @Override 
    public void onReceive(Context c, Intent intent) {


        Intent service = new Intent(c, Sense8.class);
        c.startService(service);
} 

You haven't assigned you context to parameter c. So you are trying to start service on null reference.