Sibel Tahta
Sibel Tahta

Reputation: 63

Android Calling Service from BroadcastReceiver

I need to listen screen_on and screenof_action.

I m using BroadcastReceiver with Service. But Im getting error. How can I fix my code?

this is my broadcastreceiver class :

public class BroadcastReceiver extends android.content.BroadcastReceiver {
    public static boolean screenOff = true;
    @Override
    public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
        screenOff = true;
       // System.out.println("System ON OLDU ON ON ON ON ON ON");
       Intent i = new Intent(context, MyNewService.class);
       i.putExtra("screen_state", true);
       context.startService(i);
    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
        screenOff = false;
        Intent i = new Intent(context, MyNewService.class);
        i.putExtra("screen_state", false);
        context.startService(i);
       // System.out.println("System OFFFF OLDU OFFFF OFFFF OFFFF OFFFF");
    }
}
}

this is my service class :

public class MyNewService extends Service {
    BroadcastReceiver locker;
    public static boolean screenOn = true;

    public void onCreate(){
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        locker=new BroadcastReceiver();
        registerReceiver(locker, filter);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
        Log.i("START", "onStart");
        screenOn = intent.getBooleanExtra("screen_state", false);
        if(screenOn){
           // startActivity(new Intent(this, MainActivity.class));
            Log.i("SCREEN", "SCREEN OFFFFFFFFFFFFFFFF");
        }   else {
            Log.i("SCREEN", "SCREEN OF FFFFFFFFFFFFFFFFFFFFFFFFF");
        }
    // If the screen is off then the device has been locked
    }

    @Override
    public void onDestroy(){
        unregisterReceiver(locker);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }
}

this is my error code :

    :19:52.696  32141-32141/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
       Process: com.codeexamples.app, PID: 32141
       java.lang.RuntimeException: Unable to start service  com.codeexamples.app.MyNewService@42672530 with Intent { cmp=com.codeexamples.app/.MyNewService }: java.lang.NullPointerException
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2705)
            at android.app.ActivityThread.access$2100(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException

     at com.codeexamples.app.MyNewService.onStart(MyNewService.java:25)
              at android.app.Service.onStartCommand(Service.java:450)
              at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2688)
                at android.app.ActivityThread.access$2100(ActivityThread.java:135)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:136)
                at android.app.ActivityThread.main(ActivityThread.java:5001)
                at java.lang.reflect.Method.invokeNative(Native Method)

this is my manifest permisson :

for service :

    <service
        android:name="com.codeexamples.app.MyNewService"
        android:enabled="true" />

for broadcast :

    <receiver android:name="com.codeexamples.app.BroadcastReceiver" >
    </receiver>

for permission :

<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>

When I m checking error in the logcat shows me this line :

screenOn = intent.getBooleanExtra("screen_state", false);

Always show this line, I think something wrong in this line.

Upvotes: 2

Views: 3149

Answers (3)

Sibel Tahta
Sibel Tahta

Reputation: 63

thanks for all, Finally I found solution :

this line :

boolean screenOn = intent.getBooleanExtra("screen_state", false);

must be work in the try/catch, finally I did like this, and its work completely

try {
    boolean screenOn = intent.getBooleanExtra("screen_state", false);
} catch 
(Exception e) {}

Upvotes: 1

Lei Guo
Lei Guo

Reputation: 2550

I tried you code and find a solution for you problem.

1.remove the following code from your manifest.xml

    <receiver android:name="com.codeexamples.app.BroadcastReceiver" >
   </receiver>

Since you registered your BroacastReceiver in your code, you should not register it in your menifest.xml. I have tried to register it in the menifest instead of code, but it can't work, don't know why.

2.Start you Service in your Activity initially to register your BroadcastReceiver, code as this:

private void startMyService() {
    Intent intent = new Intent(this, MyNewService.class);
    startService(intent);
}

Or you can move your code for registering your BroadcastReceiver to your Activity, thus you don't need to start your service initially.

3.Change your onStart() method to onStartCommand() method as this:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    // Here paste your code in your onStart() method.

    return START_STICKY;
}

Update:

Notice this in the document(http://developer.android.com/reference/android/app/Service.html#START_STICKY):

Constant to return from onStartCommand(Intent, int, int): if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance; if there are not any pending start commands to be delivered to the service, it will be called with a null intent object, so you must take care to check for this.

So, If you did nothing wrong in your code, you should check the null intent yourself.

Upvotes: 0

Mike Laren
Mike Laren

Reputation: 8178

Android might call your onStart() method without an intent. You can read more about this behavior in the Service Javadocs.

The best approach would be to override both onStart() and onStartCommand() methods (the former has been deprecated since API version 5) as described in the Javadocs, making sure that you cater for the case where the intent is null.

Upvotes: 0

Related Questions