0

I am trying to run some code every 3 seconds using AlarmManager and BroadcastReceiver.

Here is the manifest:

< manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="crm.app">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>

    <application ...>
        <receiver android:name=".crm.app.utilities.DeviceReceiver">
    ...
    <activity
            android:name=".activities.SettingsActivity"
            android:label="@string/title_activity_settings"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar" />
    </application>

SettingsActivity

public void startAlarm(View view) {
    String action = btn.getText().toString();
    if(action.equals("Enabled")){
        // kill alarm task
    }else{
        // start alarm task
        Long time = 3000L;
        Intent intentAlarm = new Intent(this, DeviceReceiver.class);

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        alarmManager.set(AlarmManager.RTC_WAKEUP,time, PendingIntent.getBroadcast(this, 1, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
        Toast.makeText(this, "Alarm Started", Toast.LENGTH_LONG).show();
    }
}

DeviceReceiver

public class DeviceReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
            Toast.makeText(context, "I'm running after device booted", Toast.LENGTH_SHORT).show();
        }
        Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
    }
}

So far the Alarm gets started but the app will crash after approximately 3 seconds with the message: "Unfortunately, app has stopped." Again after 3-20 seconds I will get this message.

So it seems like the Alarm is working but is failing when it tries to call the receiver.

What do I need to do to get the Alarm to trigger the receiver and display the Toast?

Edit: This is the relevant stack trace

FATAL EXCEPTION: main
Process: crm.geoalertapp, PID: 15845
java.lang.RuntimeException: Unable to start receiver crm.app.crm.app.utilities.DeviceReceiver: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
 at android.app.ActivityThread.handleReceiver(ActivityThread.java:2732)
 at android.app.ActivityThread.-wrap14(ActivityThread.java)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:148)
 at android.app.ActivityThread.main(ActivityThread.java:5417)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
 at crm.app.crm.app.utilities.DeviceBootReceiver.onReceive(DeviceReceiver.java:17)
 at android.app.ActivityThread.handleReceiver(ActivityThread.java:2725)
 at android.app.ActivityThread.-wrap14(ActivityThread.java) 
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
 at android.os.Handler.dispatchMessage(Handler.java:102) 
 at android.os.Looper.loop(Looper.java:148) 
 at android.app.ActivityThread.main(ActivityThread.java:5417) 
 at java.lang.reflect.Method.invoke(Native Method) 
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
crmepham
  • 4,676
  • 19
  • 80
  • 155
  • What does your logcat say? It will contain the full details of the crash. – Bryan Herbst Feb 17 '16 at 15:06
  • "I am trying to run some code every 3 seconds using AlarmManager and BroadcastReceiver" -- please don't. "but the app will crash" -- use LogCat and examine the Java stack trace associated with your crash: https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this – CommonsWare Feb 17 '16 at 15:06
  • @CommonsWare Thsi is just to test it works. How do I view the LogCat for stacktrace in Android Studio? – crmepham Feb 17 '16 at 15:07
  • That is covered in the linked-to question and answers. LogCat appears in the Android Monitor tool. – CommonsWare Feb 17 '16 at 15:08
  • Do you test on android 6 device ? On android 6 it s a new way to treat permissions – Raluca Lucaci Feb 17 '16 at 15:10
  • here one of the best solution to use AlarmerManager http://stackoverflow.com/questions/4459058/alarm-manager-example – user2934536 Feb 17 '16 at 15:13
  • I posted the stacktrace. – crmepham Feb 17 '16 at 15:15
  • You aren't setting an action on the `intentAlarm` so it is throwing a `NullPointerException` when you try to compare the null action string from the `intent` in the `onReceive` method. You should set an action to handle and you can also reverse the equals check to avoid the exception if there is a null action `Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) ` – George Mulligan Feb 17 '16 at 15:30

1 Answers1

0

You create the intent explictly:

        Intent intentAlarm = new Intent(this, DeviceReceiver.class);

you didn't add action for it,so you shouldn't call getAction() like

intent.getAction().equals("android.intent.action.BOOT_COMPLETED")

,intent.getAction() will return null.

so to resolve your problem,just remove this code:

if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
        Toast.makeText(context, "I'm running after device booted", Toast.LENGTH_SHORT).show();
}
starkshang
  • 8,228
  • 6
  • 41
  • 52
  • This is also an elegant way of performing this check without a NULL check: http://stackoverflow.com/a/15049016/734758 - i.e. do: if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { ... } – Scottie Feb 17 '16 at 15:32
  • @Scottie,yes,constant object should be placed in left to avoid NPE. – starkshang Feb 18 '16 at 01:18