Disable automatic screen turn-off in Android during call - android

I have a service which launches a "BroadcastReceiver" after the user has finished booting (ACTION_BOOT_COMPLETED) and when the device goes to sleep (ACTION_SCREEN_OFF). My "BroadcastReceiver" checks when an incoming call is received (TelephonyManager.CALL_STATE_RINGING) and launches a "Service" that records the call. It is working but the problem is that my device turn off display during call when I put the phone to my ear, so the service launches again the "BroadcastReceiver". Is there someone who knows how to solve it?
public class MyService extends Service {
private BroadcastReceiver mReceiver;
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}

This should'nt be possible, because the telephone app is in the forground and is triggering the display if it detects an proximity near event. You can maybe set a wakelock and release this afterwards.

Related

onReceive in BroadcastReceiver doesn't get called sometimes

I registered receiver in onCreate, but onReceive sometimes get called, sometimes not.
public class MyReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.v("receiver","get called");
}
}
Here is how I register receiver in onCreate
PROCESS_RESPONSE = getBaseContext().getResources().getString(R.string.serviceResponse);
IntentFilter filter = new IntentFilter(PROCESS_RESPONSE);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new MyReceiver();
registerReceiver(receiver, filter);
Here is how I send broadcast:
Intent broadcastIntent = new Intent();
PROCESS_RESPONSE=getBaseContext().getResources().getString(R.string.serviceResponse);
broadcastIntent.setAction(PROCESS_RESPONSE);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(broadcastIntent);
Try this:
broadcastIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
The reason it sometimes works and doesn't work is
because Android 3.0 introduced a launch control security measure that prevents components of stopped applications from being launched via an intent. An application is considered to be in a stopped state if the application has either just been installed and not previously launched, or been manually stopped by the user using the application manager on the device. To get around this, however, a flag can be added to the intent before it is sent to indicate that the intent is to be allowed to start a component of a stopped application.
Quote source
So when you try a fresh install (launching from IDE) the application is considered in the stop state for a while, then later is not. So it sometimes doesn't work when you try to broadcast. Let me know if this works, and of course ensure you have registered the BroadcastReciever (I'm sure you have if it works, at least some of the time).

Dynamically registered BroadCastReceiver cannot Receive Broadcasts after its process is died why?

I am creating widget app that sync data with server i am registering BroadCastReceiver dynamically for receiving SCREEN_ON and SCREEN_OFF broadcasts i registered my BroadCastReceiver in class that extends Application, but the problem is that if the process is running it app receive SCREEN_ON and SCREEN_OFF broadcasts but if process is died then application would not be able to get receive broadcast why? in BroadCastReceiver theory they says app will receive broadcast even if it is not running.
public class ThisApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Utils.logCat("ThisApplication", "onCreate()");
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(new ScreenOnOffReceiver(), intentFilter);
}
}
public class ScreenOnOffReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Utils.logCat("Screen ScreenOnOffReceiver", "SCREEN is ON");
}
else
{
Utils.logCat("Screen ScreenOnOffReceiver", "SCREEN is OFF");
}
}
}
1 - You forgot to add the context to your new ScreenOnOffReceiver()
Change it to new ScreenOnOffReceiver(this).
2 - I guess you have an onPause(); method containing unregisterReceiver()?
This makes sure that when your app closes the BroadcastReceiver gets closed or unregistered as well. So it would be better to register your receiver directly using the manifest file. If for some reason you do HAVE to register it dynamically:
Use an if statement to check if your receiver is listening. If it is don't create another one. If it is not create one. If you want to know how(the code) comment below and I will do so)
BroadcastReceiver registered in the AndroidManifest.xml will receive broadcasts even if the process is not running
BroadcastReceiver registered during runtime only exist while the VM is running and will not be called if the process dies.
That is the rule, that is the indented behavior, it is always been like that, you cannot change it.
Said that:
if you want a you can during runtime enable/disable a BroadcastReceiver that is registered in the manifest like in this answer:
Enable and disable a Broadcast Receiver

A service will always receive the Broadcast Action that registered for?

I have created a service which is supposed to receive the android.bluetooth.device.action.ACL_DISCONNECTED/ACL_CONNECTED events.
I am aware that services in android may be restarted/stopped when android decides.
However, I am wondering whether a service is always guaranteed to receive the events it registered for, even it has been killed by android?
I assume this means that android will need to restart a killed service which has registered to listen to events when that event takes place.
Is the above assumption correct ?
Thank you very much for the quick reply.
Let me give some more information, sample of the code follows:
public class my_service extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
IntentFilter filterDisconnected = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
this.registerReceiver(mReceiverDisconnected, filterDisconnected);
...
}
private final BroadcastReceiver mReceiverDisconnected = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
...
}
}
...
}
So with this code the BroadcastReceiver is implemented within the service class.
This code is working fine under normal cirmustances but are you saying that this is not proper and a different class (BroadcastReceiver ) is needed ?
If the above is proper, i am wondering if this service class is stopped for any reason, when the relevant event is raised, the class will be restarted and the BroadcastReceiver will get the event.
Hi all, i have created a service which is supposed to receive the android.bluetooth.device.action.ACL_DISCONNECTED/ACL_CONNECTED events.
That should not be possible. Those are documented as being broadcast actions; if true, then they can only be picked up by a BroadcastReceiver.
However, i am wondering whether a service is always guaranteed to receive the events it registered for, even it has been killed by android ?
Again, services should never "receive" those events directly.
However, if you create a BroadcastReceiver and put it in the manifest with an <intent-filter> for your desired broadcasts, then that BroadcastReceiver is "guaranteed to receive the events it registered for", and that BroadcastReceiver can call startService() to send a command to an IntentService if desired.

Keep widget BroadcastReceiver alive even if not instantiated from Manifest

i have a widget which needs to listen to BATTERY_CHANGED event, however, since this event is protected and cannot be declared from the manifest i create a new BroadcastReceiver from the Application constructor:
public void onCreate() {
super.onCreate();
if (DEBUG) Log.d(TAG, "onCreate()");
// Register receivers
if (receiver == null) {
receiver = new MYReceiver(this);
}
// Create new intentfilter
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, intentFilter);
}
Then, from the Receiver i call a static method of the AppWidgetProvider which actually update the widget using RemoteViews. Everything works flawlessy until 1 hour as passed, after that time my Receiver disappears and the widget does not update anymore. I'm testing this on a Droid with 2.2.1 firmware-
What i'm doing wrong? Is this the correct way to update the widget (i just need that event so i don't want to have a service if its not needed). Should i use an AlarmManager to be sure from time to time that my receiver is still there? I can i do this?
Thanks.
I don't have a clue why your receiver got lost after an hour but what about using the AlarmManager to check periodically if it is still there? So you can re-register it if it got lost.

Android - detect phone unlock event, not screen on

Is there a way to detect when a user unlocks the phone? I know about ACTION_SCREEN_ON and ACTION_SCREEN_OFF, but these seem to be fired when the screen switches on/off when pressing the power button, but not actually when the phone gets unlocked when pressing the Menu button...
I am trying to detect the unlock/lock while an activity is running, and I want to resume the activity once unlocked.
Here's what to do:
Say you want to detect the unlock event and do something in your activity when the phone is unlocked. Have a Broadcast Receiver for ACTION_SCREEN_ON, ACTION_SCREEN_OFF and ACTION_USER_PRESENT.
onResume of the activity will be called when ACTION_SCREEN_ON is fired. Create a handler and wait for ACTION_USER_PRESENT. When it is fired, implement what you want for your activity.
Credit goes to CommonsWare's answer here: Android -- What happens when device is unlocked?
After struggling with this for a while, I've found that the best way to do this is to register a BroadcastReceiver on the "android.intent.action.USER_PRESENT" action.
"Broadcast Action: Sent when the user is present after device wakes up (e.g when the key-guard is gone)."
To distinguish between cases where the user has turned on phone screen when it wasn't locked, and when they actually unlocked it use the KeyguardManager to check the security settings.
Code example:
Add this to your activity:
registerReceiver(new PhoneUnlockedReceiver(), new IntentFilter("android.intent.action.USER_PRESENT"));
Then use this class:
public class PhoneUnlockedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
KeyguardManager keyguardManager = (KeyguardManager)context.getSystemService(Context.KEYGUARD_SERVICE);
if (keyguardManager.isKeyguardSecure()) {
//phone was unlocked, do stuff here
}
}
}
public class PhoneUnlockedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
Log.d(TAG, "Phone unlocked");
}else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
Log.d(TAG, "Phone locked");
}
}
}
register receiver by this statement
receiver = new PhoneUnlockedReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(receiver, filter);
Didn't test it but try the following:
Wait for ACTION_SCREEN_ON.
(After screen is on,) Wait for ACTION_MAIN with category CATEGORY_HOME (Which launches the home screen) - This is probably what is sent after the phone gets unlocked.
The 1st step is needed to filter out regular HOME key presses.

Categories

Resources