2

I have this broadcast receiver declared in the Manifest:

<receiver android:name="classes.VoiceLaunchReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.USER_PRESENT" />
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

My receiver Class:

public class VoiceLaunchReceiver extends android.content.BroadcastReceiver {
    @Override
    public void onReceive(Context ctx, Intent intent) {     
        Intent service = new Intent(ctx, VoiceLaunchService.class);
     //   service.putExtra(action, true);
        Log.i("joscsr","Incoming Voice Launch Broadcast...");  

        if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
            Log.e("joshcsr", "***********\nCSR Resumed (BC)\n************");
            ctx.startService(service);
            }
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Log.e("joshcsr", "***********\nCSR STOPPED by SCREEN (BC)\n************");
            ctx.stopService(service);
            }
        }
}

I registered the SCREEN_OFF intent in the onCreate method of a service:

@Override
public void onCreate() {
    super.onCreate();
    //Register screen OFF BroadCast
    IntentFilter mIntentFilter=new IntentFilter(Intent.ACTION_SCREEN_OFF);
    registerReceiver(speechBroadcastReceiver, mIntentFilter);
    }

It does its thing whenever the user unblocks and turns on the screen. It works perfectly in Jellybean 4.3 and lower: my Logcats inside my Broadcast receiver are shown whenever the screen is locked pr unlocked. Why won't this exact code won't work in Lollipop? Are there new Intents that I must listen to instead?

(I already know that the systems send that intent, what I want is to detect it with my receiver)

Josh
  • 6,251
  • 2
  • 46
  • 73
  • post ur java code too – Shakeeb Ayaz Mar 17 '15 at 09:03
  • wont work? what shown in your logcat? – Randyka Yudhistira Mar 17 '15 at 09:05
  • @ShakeebAyaz Hi guys, I added the broadcast receiver's code and the register code for the Screen_OFF intent. You can see the logcats I am trying to show in Lollipop. – Josh Mar 17 '15 at 09:22
  • ACTION_SCREEN_OFF only works WHILE service is still running. Check if your service gets killed or something. – velis Mar 17 '15 at 09:23
  • @velis I see your point, but Intent.ACTION_USER_PRESENT is not caught in the first place. – Josh Mar 17 '15 at 09:30
  • Just to try it: I have android.intent.action.ACTION_USER_PRESENT (note the additional "ACTION_") in my manifest. Sometimes I don't know which of these constants is the correct one :( – velis Mar 17 '15 at 11:20
  • @velis Sorry, it did not work :( I saw a clue on the logcat that may hint a solution, because I now that Screen Lock security is tighter in lollipop. The intent is sent by the system, but it seems something is missing to capture it: UserPresentBroadcastReceiver(2446): Received Intent { act=android.intent.action.USER_PRESENT flg=0x24000010 cmp=com.google.android.gms/.auth.trustagent.UserPresentBroadcastReceiver }. – Josh Mar 17 '15 at 11:51
  • Ok, after much struggling, I found a solution to this problem, see the answer below. – Josh Mar 17 '15 at 15:38
  • Same issue http://stackoverflow.com/questions/29081414/why-wont-this-broadcast-receiver-work-in-lollipop – OneWorld Feb 12 '16 at 09:15

1 Answers1

1

I had the same problem and I fixed it (tested on 4.3 and 5.1). I was able to declare "android.intent.action.USER_PRESENT" inside the manifest, as long as you have the READ_PHONE_STATE permission, it is OK!! My mini app consists of a Broadcast receiver that reacts to the screen ON/OFF state, and runs a background service that does continuous voice recognition. If the screen is off, the recognition is turned off.

Here is the code, enjoy: MANIFEST:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/> <receiver android:name="classes.VoiceLaunchReceiver" >
            <intent-filter>                
                <action android:name="android.intent.action.USER_PRESENT" />    
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

BROADCAST RECEIVER:

public class VoiceLaunchReceiver extends BroadcastReceiver {
    @Override  
    public void onReceive(Context ctx, Intent intent) {     
        Intent service = new Intent(ctx, VoiceLaunchService.class);
     //   service.putExtra(action, true);
        Log.i("joscsr","Incoming Voice Launch Broadcast...");  

        if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
            Log.i("joshcsr", "************\nCSR Resumed (BC)\n************");
            ctx.startService(service);
            }
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Log.i("joshcsr", "************\nCSR STOPPED by SCREEN (BC)\n************");
            ctx.stopService(service);  
            }
        }  
}

As you can imagine, my USER_PRESENT broadcast receiver is not registered anywhere else. I do register ACTION_SCREEN_OFF and ON in the onCreate method of my service, who was triggered by my receiver.

@Override
public void onCreate() {
    super.onCreate();
    //Register screen ON/OFF BroadCast
    launcher=new VoiceLaunchReceiver();
    IntentFilter i=new IntentFilter(Intent.ACTION_SCREEN_OFF);
    i.addAction(Intent.ACTION_SCREEN_ON);               
    registerReceiver(launcher,i);
    Log.d("joshcsr","VoiceLaunch Service CREATED"); 
    }

Finally I unregister the screen on/off in the onDestroy() of my service:

@Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(launcher);}
Abu Yousuf
  • 5,729
  • 3
  • 31
  • 50
Josh
  • 6,251
  • 2
  • 46
  • 73
  • I did not need the permission nor the category. I had to remove `exported="false"` from the receiver though. Tested on stock Android 5 – OneWorld Feb 12 '16 at 09:14
  • I did not add exported=false to begin with... @OneWorld – Josh Feb 16 '16 at 10:19