Why is my BroadcastReceiver receiving ACTION_USER_PRESENT twice? - android

My application needs to make a toast when the user unlocks the screen, so I registered a BroadcastReceiver to pick up the intent ACTION_USER_PRESENT in the manifest, like so:
<receiver
android:name=".ScreenReceiver" >
<intent-filter>
<action
android:name="android.intent.action.USER_PRESENT"/>
</intent-filter>
</receiver>
And then I defined a class like this:
package com.patmahoneyjr.toastr;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOn;
private static final String TAG = "Screen Receiver";
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
screenOn = true;
Intent i = new Intent(context, toastrService.class);
i.putExtra("screen_state", screenOn);
context.startService(i);
Log.d(TAG, " The screen turned on!");
} else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOn = false;
}
}
}
But for some reason, the Log statement is printed twice, and my service makes two toasts instead of one. Does anyone know why this might be happening, and what I can do to stop it? Am I overlooking something silly?
EDIT: I'm terribly sorry everyone, but I found the problem myself... the bug was that in the service class that was supposed to receive the broadcast, I had instantiated a new ScreenReceiver and it too was picking up the intent. I misunderstood the class and thought that to receive the intent I had to have one there, but after removing that block, I only receive the intent once. Android wasn't sending the intent twice, it was just getting picked up twice... Thank you for your help everyone!

Try This:
1. Simply create your broadcast reciever.
BroadcastReceiver reciever_ob = new BroadcastReceiver(
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(Intent.ACTION_USER_PRESENT)){
//DO YOUR WORK HERE
}
}
}
2. Register your receiver before sending broadcast with above broadcast object. you can also add multiple actions.
IntentFilter actions = new IntentFilter(Intent.ACTION_USER_PRESENT);
registerReciever(reciever_ob, actions);
3. Send broadcast
Intent intent = new Intent(Intent.ACTION_USER_PRESENT);
SendBroadcast(intent);
now you can remove all your stuff which you have declared in your xml-manifest file I dont know exactly but i think it should work.

Related

How to call IntentService from WakefulBroadcastReceiver

I have an IntentService defined as below:
<service android:name=".service.AppService" android:process=":app_process" android:icon="#mipmap/ic_launcher" />
I have a WakefulBroadcastReceiver that receives some data and I would like to call my already running service above. The service above is always running, even if it is killed, it restarts. How can I pass messages to that?
I read the following:
http://www.mysamplecode.com/2011/10/android-intentservice-example-using.html
http://www.truiton.com/2014/09/android-service-broadcastreceiver-example/
http://developer.android.com/guide/components/services.html
I tried to do a startService, PendingIntent among other things and nothing seems to work.
First of all, remember that an IntentService works in a different worker thread, there for it's not possible to have intercommunication with the Activity that invoked it. That's why mostly we use them for synchronization on background where feedback to the user is not needed. However, if you want to pass some information to the Activity, you have to use a BroadcastReceiver as you said, and from there create the Intent that will send "data" to the Activity.
Going back to your question, you have to add the service and the receiver in your AndroidManifest.xml inside the <application> tag
<service android:name=".AppService"
android:enabled="true"/>
<receiver android:name=".WakefulBroadcastReceiver" >
</receiver>
Then in your Activity launch the service like this (whenever you need it, in the onCreate, or in a button listener)
IntentFilter filter = new IntentFilter(WakefulBroadcastReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
WakefulBroadcastReceiver broadcastReceiver = new WakefulBroadcastReceiver();
registerReceiver(broadcastReceiver, filter);
In your BroadcastReceiver you override the onReceive() method like this:
#Override
public void onReceive(Context context, Intent intent) {
// HERE IS WHERE YOU RECEIVE THE INFORMATION FROM THE INTENTSERVICE, FROM HERE YOU CAN START AN ACTIVITY OR WHATEVER YOU AIM
Toast.makeText(context, "IntentService Broadcasting", Toast.LENGTH_SHORT).show();
}
Also in the same BroadcastReceiver add this variable that identifies the intentfilter:
public static final String ACTION_RESP = "MY_FILTER_NAME"
In your IntentService class you have to override the onHandleIntent() method like this:
#Override
protected void onHandleIntent(Intent intent) {
String msg = intent.getStringExtra("MSG");
Intent broadcast = new Intent();
broadcast.setAction(WakefulBroadcastReceiver.ACTION_RESP);
broadcast.addCategory(Intent.CATEGORY_DEFAULT);
broadcast.putExtra("MSG", resultTxt);
// HERE IS WHERE YOU SEND THE INFORMATION YOU LOADED TO THE APP
sendBroadcast(broadcast);
}
I have a demo project in my GitHub account here, where I use bound and unbound services and IntentServices:
https://github.com/isaacurbina/PermissionsAndServices
I hope it helps.
Kind regards!
You can write this in your class that extends WakefulBroadcastReceiver :
#Override
public void onReceive(Context context, Intent intent) {
Intent gcmIntent = new Intent(context, MessageService.class);
gcmIntent.putExtras(intent.getExtras());
startWakefulService(context, gcmIntent);
setResultCode(Activity.RESULT_OK);
}
And write this in your class that extend IntentService :
#Override
protected void onHandleIntent(Intent intent) {
Bundle bundle = intent.getExtras();
//do sth with that data
MessageReceiver.completeWakefulIntent(intent);
}

open activity when power button pressed android

I am trying to make a Lock Screen App, that is why I want to start my app every time the Screen is turned on. Currently I found a solution where a Receiver for Screen on/off and the methods onPause() and onResume() are used. This is the Link of the Example: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/#comment-4777
I am using the example of the activity and not the service.
I am actually getting Feedback in the LogCat when the screen is turned off and on and the app is already running. The problem is that the app doesn't start when I am turning the screen on (even if it is shown under recently used apps).
I am not sure but I think the example works fine and I am just missing to add the essential code.
I hope someone can help !!
Thanks for the quick answer. I have tried to run your code but it is still not working. I am not sure what is wrong. There is no error message. The application just runs normally but won't start when the screen goes on.
To make it easier to help me here is my code ;)
This is my Receiver:
package com.example.screenlocker;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class StartMyServiceAtBootReceiver extends BroadcastReceiver {
public static boolean screenOff = true;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = true;
Intent i = new Intent(context,LockService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = false;
}
}
and this my Service:
package com.example.screenlocker;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
public class LockService extends Service {
public void onCreate(){
IntentFilter filter=new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver locker=new StartMyServiceAtBootReceiver();
registerReceiver(locker, filter);
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if(screenOn){
startActivity(new Intent(this, MainActivity.class));
}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
Maybe you know what is wrong.
The following things need to be done in order to achieve this.
1.When your application starts you must start a service for registering the SCREEN_TURN_ON and SCREEN_TURN_OFF events.
REASON If you won't start a service to register these events and just register it inside an activity.Then when activity gets destroyed it stops registering for the screen on/off events.Making a service causes it to outlive the activity's or your application's lifetime.
2.Now you need to put some code in your service (inside the onCreate method)
IntentFilter filter=new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
locker=new startLockActivity();
registerReceiver(locker, filter);
3.Make a BroadCastReciever and check for the Screen ON/OFF events and perform actions accordingly.
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = true;
Intent i = new Intent(context,Locker.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = false;
}
4.Now in your service onStartCommand method put some code to get the flag sent via the receiver and start your lock activity.
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if(screenOn){
startActivty(this,yourLockActivity.class);
}
Hope it helps you out.

broadcastreceiver onReceive problem ACTION_MEDIA_BUTTON Android

I've found a lot of pages about this in the web, but none of them helped me. I've been for hours stucked in this problem. That's why i decided to make my own question.
What I want to do is an application that receives an intent of the type ACTION_MEDIA_BUTTON and the method onReceive() of the Broadcastreceiver does something.
My Activity is like this:
public class MusicControlActivity extends Activity {
private MediaButtonIntentReceiver receiver = new MediaButtonIntentReceiver();
#Override
public void onCreate(Bundle p_SavedInstanceState) {
super.onCreate(p_SavedInstanceState);
setContentView(R.layout.main);
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
filter.setPriority(1000);
registerReceiver(receiver,filter);
}
#Override
public void onDestroy()
{
unregisterReceiver(receiver);
}
And my broadcastreceiver as follow:
public class MediaButtonIntentReceiver extends BroadcastReceiver {
public MediaButtonIntentReceiver()
{
super();
}
#Override
public void onReceive(Context context, Intent intent)
{
String v_IntentAction = intent.getAction();
if (!Intent.ACTION_MEDIA_BUTTON.equals(v_IntentAction)) {
return;
}
KeyEvent v_Event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (v_Event == null) {
return;
}
int v_Action = v_Event.getAction();
if (v_Action == KeyEvent.ACTION_DOWN) {
// do something
Toast.makeText(context, "BUTTON PRESSED!", Toast.LENGTH_SHORT).show();
}
abortBroadcast();
}
}
The problem is that it doesn't work, no matter what I do. I've tried registering it dynamically with registerReceiver as in the code above. Also I've tried statically in the AndroidManifest.xml like this:
<receiver android:name=".MediaButtonIntentReceiver" android:enabled="true">
<intent-filter android:priority="10000000">
<action android:name="android.intent.action.ACTION_MEDIA_BUTTON" />
</intent-filter>
</receiver>
And as you can see I've set the priority to a high level and even though it doesn't work.
I've been on this for the whole day and I don't know what to do. The method onReceive from the broadcastreceiver isn't called anytime.
Does anyone know what should I do?
Use android.intent.action.MEDIA_BUTTON Instead in your manifest. Check : http://developer.android.com/training/managing-audio/volume-playback.html
First, you should stop using Toast as your diagnostic test. Use the Log class to log to LogCat, or breakpoints, or something.
Next, you should get rid of your MediaButtonIntentReceiver constructor, as it is not needed.
Then, I would dump the if (!Intent.ACTION_MEDIA_BUTTON.equals(v_IntentAction)) block, since it is also not needed.
Next, I would make sure that your media button actually works. Does it control other applications, like a music player? It may be that your media button is not Android-compliant or something.

Intent and Broadcast Receiver trouble

I'm having trouble sending and receiving an intent. The relevant code is below... I can't find anything wrong with it. I'm not positive what to put there... Right now the intent is broadcasted and the receiver never catches the permissions one. The Sms works fine however. Could it possibly be the manifest? I'm thinking it has something to do with the action...
PS. I know the spelling mistake in my naming... lol
In a service:
public final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
textFilter = new IntentFilter(SMS_RECEIVED);
textFilter.addAction("ADD_NUMBER_TO_PERMISSIONS");
registerReceiver(incomingReciever,textFilter);
BroadcastReceiver incomingReciever = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent _intent) {
if(_intent.getAction().equals(SMS_RECEIVED)) {
//do some stuff
}
if(_intent.getAction().equals("ADD_NUMBER_TO_PERMISSIONS")) {
//do some stuff
}
}
}
};
Then in a different activity.
Intent resultIntent = new Intent("ADD_NUMBER_TO_PERMISSIONS");
resultIntent.putExtra("NameAndNumber", contact);
setResult(Activity.RESULT_OK, resultIntent);
sendBroadcast(resultIntent);
Make sure you are registering your broadcast in onResume() and unregistering it in onPause() of your activity.
Also you may need the following code after in your manifest.
<uses-permission android:name="android.permission.RECEIVE_SMS">
</uses-permission>

Why doesn't my BroadcastReceiver receive broadcasts from another app?

App A has this BroadcastReceiver in its manifest (within <application>):
And this receiver:
public class RemoteControl extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.w(TAG, "Look what I did!");
}
}
I'm trying to trigger this from App B:
public void onClick(View v) {
Log.w(TAG, "Sending stuff");
Intent i = new Intent("app.a.remotecontrol");
i.setData("http://test/url");
sendBroadcast(i);
}
For whatever reason, the onReceive() in App A is never triggered even though it's broadcasted from App B. What can be the cause of this?
EDIT & SOLUTION: I forgot to write that I used setData() on the Intent before broadcasting it. That was indeed the problem: as soon as I removed setData(), the broadcast worked as intended.
Originally I forgot to write that I used setData() on the Intent before broadcasting it. That was indeed the problem: as soon as I removed setData(), the broadcast worked as intended.
I've switched to use putExtra() instead for the Intent metadata:
Intent i = new Intent("app.a.remotecontrol");
i.putExtra("url", "http://test/url");
sendBroadcast(i);

Categories

Resources