【问题标题】:Running an IntentService in BroadcastReceiver using AlarmManager使用 AlarmManager 在 BroadcastReceiver 中运行 IntentService
【发布时间】:2016-06-25 08:02:51
【问题描述】:

我想在扩展BroadcastReceiverReceiver 类中调用Service,但服务没有启动,我收到了这个错误:

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

在我的 MainActivity 中,我调用了警报管理器:

 // 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;
        }
    }

我的服务

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();

    }
}

在我的 Receiver 类中,我只调用IntentService

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


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

但徒劳无功,它甚至没有启动并直接以上述错误打击我

我做错了什么?有人可以帮助我以正确的方式实现这一点。

编辑

他们给了我第一个问题的正确解决方案,但现在按下感应按钮后我得到了同样的错误

这里是 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) {

    }


}

【问题讨论】:

  • 在您的BroadcastReceiver 中,您显然使用了在onReceive() 方法之外声明的空Context 引用。而是使用传递给onReceive()Context。也就是说,将两行上的context 更改为c

标签: android broadcastreceiver alarmmanager intentservice


【解决方案1】:

只是改变:

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


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

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


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

您尚未将context 分配给参数c。所以你试图在空引用上启动服务。

【讨论】:

  • 是的,这是一个愚蠢的错误,我很抱歉。现在应用程序打开了,但在我点击 onSensingButtonClickedToStart 按钮后,应用程序开始感应,我没有得到以下 toast Toast.makeText(context, "I'm running instead of some sensors being captured", Toast.LENGTH_SHORT).show(); 如果您允许我将编辑我的问题并为您提供与正确的班级。我的目标是在给定的时间间隔内捕获传感器数据,我正在尝试实现 IntentService,因为 StackOverflow 上的某个人说,即使应用程序关闭,这也允许运行服务
  • @ahmedhamed 在你解释清楚之前,我不知道你在这里写了什么。一个问题不会在这里得到答案,直到你无法理解其他人的情况。我认为这是有道理的。使用完整的堆栈跟踪和日志,正确解释您在做什么、为什么以及遇到的错误。
  • 你是对的,好吧,我有一个收集传感器的应用程序,将它们写入 SD 卡,然后通过 FTP 发送它们。该应用程序使用警报管理器和传感器管理器以及所有适当的类,它可以正常工作并按照间隔中指定的每 10 或 20 秒生成一个文件。问题在于活动生命周期,当我按下主页按钮时它会继续工作,这很好,但是当我关闭应用程序时它会停止收集数据。这就是为什么我必须实现 IntentService 但现在一旦我按下开始发送按钮它会停留几秒钟然后我得到 应用程序已停止
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多