Broadcast receiver highest priority not working - android

I'm doing an application using ACTION_MEDIA_BUTTON handler, but it appears it is always intercepted by MX Player or Apollo and I get no Intent
I've tried both 1000 and 2147483647 priority set in tag and directly after constructor with setPriority
Applications works when no MX Player or Apollo is present
I've also tried using Headset Interceptor app from google play, I tried to deny events to MX Player with Autostarts application - nothing helps
in onCreate:
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.setPriority(1000);
registerReceiver(receiver, filter);
in Receiver
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
// NEVER REACHES HERE WHEN MX PLAYER PRESENT. WORKS IF NOT
in manifest
<receiver
android:name="BCreceiver"
android:enabled="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>

Refer to the line "The value must be greater than -1000 and less than 1000." from below link, highest priority is 999 not 1000.
http://developer.android.com/guide/topics/manifest/intent-filter-element.html

Even though this a little old question, I am adding my findings, so that it will help new visitors.
To receive Intent.ACTION_MEDIA_BUTTON broadcast registering intent from code is not required. Documentation says intent has to be registered in the manifest. Could not get it working from registering from code.
Use registerMediaButtonEventReceiver
Setting priority in manifest android:priority="<int value>" works. I used 2147483647 and was even able to override the stock player. I read winamp is using the highest priority.
Hope this helps.

To capture headset button one should register receiver in media too in onCreate in Activity
AudioManager manager = (AudioManager) getSystemService(AUDIO_SERVICE);
manager.registerMediaButtonEventReceiver(new ComponentName(getPackageName(), BCreceiver.class.getName()));

First of all, you shouldn't register the receiver in code if it's already mentioned in the manifest. Then, the name of the receiver is invalid, it should either be a full class name, or the shorthand, which will be appended to the application package name. In case if BCreceiver is in the main package, the attribute value should be ".BCreceiver". Last mention is that you shouldn't really change the priority, there is no such thing as intercepting a broadcast in Android (as far as I know), so all BroadcastReceivers subscribed to an action will receive the broadcast when it's fired. Try these fixes and update your question.

Related

Android BroadcastReciever - Concept

I tried to wrap my head around Android BroadcastReceiver but with no success. I'm trying to implement something simple:
Listen to an incoming SMS
Check if the number is saved
If it is saved do something
So far I registered / created the BroadcastReceiver and I'm able to catch the incoming messages. I did this in the following way:
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
//do things
}
}
}
I registered the receiver in the Manifest file in the following way:
<receiver
android:name=".SmsReceiver"
android:permission="android.permission.BROADCAST_SMS"
android:exported="true">
<intent-filter android:priority="2147483647" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Everything fine until now.
But, and here is the big BUT: I also created a class called 'UserManager' with a few basic tasks, for example: adding a new user, deleting a user, checking if the user exists, etc.
I store the users in a HashMap (phoneNumber, Name).
My questions are:
How can I pass an Object to my BroadcastReceiver? ( I want to be able to access the HashMap from the "UserManager" class)
I found a lot of topics regarding BroadcastReceivers. Some of them said that there are a couple ways of declaring a broadcast receiver. For example you could do it the way I did ( declaring it in Manifest), or you could do something more uhm... context based? Like declaring it BroadcastReceiver br = new MyBroadcastReceiver() and registering intentFilters to it. What is the difference? Which one should I use?
Is there something called "good practice"? What should I pay attention to? Do you know any material which explains clearly the different ways of using a broadcastReceiver?
You can use dependency injection. Or just hold reference to a class in you Application, that can be accessed by getApplicationContext
Difference is - for receivers declared in manifest you can receiver messages even if you app is in destroyed state. If you broadcast receiver is created manually, well, you must create it before message will be delivered. Also Android forces some restriction on receivers declared in manifest.

Android - How to detect if user rejected an incoming call?

I'm making an Android app with incoming calls.
Is there any way in my app, to know if user rejected any incoming call before answering it?
First, you have to add a permission in manifest file.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Then you have to register a broadcast receiver in the manifest file.
<receiver android:name=".YourReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
Then write in your broadcast receiver's onReceive method:
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
//If the phone is **Ringing**
}else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK){
//If the call is **Received**
}else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
//If the call is **Dropped** or **Rejected**
}
}
If the state changes from TelephonyManager.EXTRA_STATE_RINGING to TelephonyManager.EXTRA_STATE_IDLE, then it will be a missed call.
Like this you have to check the conditions.
Please put a log in those conditions. Then see the logs. I think you will get your answer.
It's been a while since you asked, but I think it might be useful for future reference for others.
If you extract data from Android's calllog (e.g to XML or in your case to a variable in your app) you have two fields of interest:
1) numbertype e.g 1 for Incoming, 2 for Outgoing, 3 for missed
2) duration (in seconds)
Rejected number is (as you correctly mentioned) treated as numbertype=1. However if you combine numbertype=1 AND duration=0 (since any call answered will have duration>0) then this hopefully solves your problem.
I'm using Android 6, not sure if the types changed since then, but with me the above method works 99.9% of the time. Never managed to hang up the phone in less than a second :)

Google Awareness Api events while app isn't running

I would like either a BroadcastReceiver or IntentService (depending on how long my eventual processing takes) to start when a Google Awareness API "fence" fires. For example, perhaps I want to know how many times I activate a set of beacon fences over the course of the day (assuming I keep my phone with me). All the examples I've found show registering broadcast receivers in code, but my understanding is that I would need to register a broadcast receiver in the manifest in order for the OS to send the broadcast to it if my app isn't running. What's more, the intent ID appears to be a custom one, so I would guess I'd have to register it with the OS at least once via code?
I'm guessing I'm going to have to create one or more test apps to figure this out by trial and error, but would sure appreciate hearing from anyone who has tried this and would like to share your results!
It is just enough if you specify BroadCastReceiver in your Manifest file.
Its not a must that you need to register it in the code even after declaring the Manifest <receiver> entry. Just think about how the platform is able to handle Activities you register it only in the Manifest file(if not we get ActivityNotFoundException) the same way Broadcasts can also be register only in the Manifest file.
You need to declare the receiver like:
<receiver android:name=".MyFenceReceiver" >
<intent-filter>
<action android:name="android.intent.action.FENCE_RECEIVER_ACTION" />
</intent-filter>
</receiver>
Extend the BroadcastReceiver class.
public class MyFenceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
FenceState fenceState = FenceState.extract(intent);
if (TextUtils.equals(fenceState.getFenceKey(), "geofence")) {
switch(fenceState.getCurrentState()) {
case FenceState.TRUE:
break;
case FenceState.FALSE:
break;
case FenceState.UNKNOWN:
break;
}
}
}
}
More info in https://developer.android.com/guide/topics/manifest/receiver-element.html

Android receivers being ignored when activity is not active

I have a background service which has a receiver for connectivity change which only seems to be received if the activity is active.
#Override
public void onCreate() {
mContext = this;
IntentFilter connectivityChangeFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver, connectivityChangeFilter);
I've set it up in the manifest as follows:
<service
android:name="com.myservice.TimeService"
android:label="com.myservice.TimeService" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</service>
I have another receiver for boot completed which works ok, which is registered as a receiver in the manifest (unlike this one).
Is the intent filter not enough to run a broadcast? I would want the receiver to call a method on the service so it needs to be able to access methods of the service but I don't think receivers can bind to services.
-- Update
In a nutshell, I want to know if I can statically declare a receiver that interacts with a service. Dynamic declaration works only if the app is active.
Use android sticky intent
A normal broadcast Intent is not available anymore after is was send and processed by the system. If you use the sendStickyBroadcast(Intent) method, the Intent is sticky, meaning the Intent you are sending stays around after the broadcast is complete.
example code here:

android.intent.action.SCREEN_ON doesn't work as a receiver intent filter

I'm trying to get a BroadcastReceiver invoked when the screen is turned on. In my AndroidManifest.xml I have specified :
<receiver android:name="IntentReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON"></action>
</intent-filter>
</receiver>
However it seems the receiver is never invoked (breakpoints don't fire, log statements ignored). I've swapped out SCREEN_ON for BOOT_COMPLETED for a test, and this does get invoked.
This is in a 1.6 (SDK level 4) project.
A Google Code Search revealed this, I downloaded the project and synced it, converted it to work with latest tools, but it too is not able to intercept that event.
http://www.google.com/codesearch/p?hl=en#_8L9bayv7qE/trunk/phxandroid-intent-query/AndroidManifest.xml&q=android.intent.action.SCREEN_ON
Is this perhaps no longer supported?
Previously I have been able to intercept this event successfully with a call to Context.registerReceiver() like so
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// ...
}
}, new IntentFilter(Intent.ACTION_SCREEN_ON));
However this was performed by a long-living Service. Following sage advice from CommonsWare I have elected to try to remove the long-living Service and use different techniques. But I still need to detect the screen off and on events.
Following sage advice from CommonsWare
I have elected to try to remove the
long-living Service and use different
techniques.
Actually, I believe my advice was more of a light blue... :-)
But I still need to detect the screen
off and on events.
There are certain events that Android does not want to start up new processes for, so the device does not get too slow from all sorts of stuff all having to run at once. ACTION_SCREEN_ON is one of those. See this previous question for light blue advice on that topic.
So, you need to ask yourself, "Self, do I really need to get control on those events?". The core Android team would like it if your answer was "no".
This is the best example I've found http://androidexample.com/Screen_Wake_Sleep_Event_Listner_Service_-_Android_Example/index.php?view=article_discription&aid=91&aaid=115
Actullay i was faceing this issue but i resolve it succeessfully
1) start service from your main activity
Intent i = new Intent(MainActivity.this, UpdateService.class);
startService(i);
2) register reciver in service class.
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReciever();
registerReceiver(mReceiver, filter);
}
3) Done

Categories

Resources