Can I get a reason why screen is on when I use BroadcastReciever for SCREEN_ON?(It is user have pressed on/off button on phone, or it is some app for example alarmclock ringing)?
PowerManagerNotifier(Notifier.java) is where the ACTION_SCREEN_ON is being broadcasted whenever the system turns on the screen.
https://code.google.com/p/android-source-browsing/source/browse/services/java/com/android/server/power/Notifier.java?repo=platform--frameworks--base
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
As you can see it from the above, the broadcasted intent does not contain any info on the reason for being turned on. So, you are not able to distinguish the reason from the BroadcastReciever for ACTION_SCREEN_ON.
Related
Is it feasible to make our Android application completely transparent (as if its not active at all) and work on the other apps?
My Requirement:
First last an app and after some few settings, make it transparent. Once its transparent, the user will not know that this app is active, however, our app should respond to only specific controls.
This is because of the Broadcast receiver limitation, I will have to use the Volume button for some actions in my application. But, this button doesn't broadcast. So, currently I am using Power button which is not the requirement.
Please throw some light on this. I did some research but, couldnt find any. :(
This is because of the Broadcast receiver limitation, I will have to use the Volume button for some actions in my application. But, this button doesn't broadcast.
I am not sure it this is right. If you read Android BroadCastReceiver for volume key up and down question, it seems that you can detect it in BroadCastRceiver. I've never tried but it might be worth a try. Do something like following:
In your BroadcastReceiver onReceive function, do something like following:
public void onReceive(Context arg0, Intent intent) {
if (intent!=null){
int volume = (Integer)intent.getExtras().get("android.media.EXTRA_VOLUME_STREAM_VALUE");
// Get the old volume from the SharedPOreferences
// volume variable contains the current volume
// Compare it to the old value saved. If it is greater than old value then user pressed the UP Volume button else DOWN volume.
}
}
Also I am not sure that you can make it transparent and still keep it running. You can have a background of an activity as transparent though. How do I create a transparent Activity on Android?. Hope it helps.
I have more or less been able to understand and implement all these concepts in parts but somehow totally confused as what to put where and how do they fit together.
In short this is what I am trying to achieve on a non-rooted android phone
Have an SMS broadcast receiver listen for incoming SMS with secret code
Lock the screen if sms has keyword lock.
How do BroadCastReceivers and DeviceAdminRecivers go hand in hand?
Eg. I have the working code for intercepting an SMS. A switch case which calls a dummy(empty) lockScreen() function. Now where should I put DeviceAdminReceiver's code so that I can lock the screen (a new Activity with a password box with HOME and other menu buttons disabled) ?
So basically its from BroadcastReceiver -> Device Admin -> Activity.
Please help me.
The easiest way would be to create a custom HOME screen and add features mentioned below so that it looks like a custom lock screen :
Remove Notification/Status bar from the custom LockScreen activity
Catch and Disable HOME/MENU button clicks when LockScreen activity is visible
Have and SMS broadcast receiver call the custom LockScreen activity when secret "LOCK PHONE" sms is received.
Have a PhoneBroadstReceiver to make the LockScreen reappear with some delay(100ms) so that the incoming call system default screen doesn't push your lockScreenActivity to the background
P.S : DeviceAdmin can be used to lock your phone and show up the system default lock screen if the password has been set
I don't believe you can create a custom lock screen on a non-rooted phone, because as far as I know, disabling the Home button is impossible from within an app.
Well, I wasn't aware of these lock-screen apps, but upon further research it seems that this would be the way to go:
1) Have your app register for the necessary SMS intent broadcasts.
2) Upon receiving the broadcast, check for the lock keyword
3) If lock keyword exists, programatically lock the phone using:
private void lockScreen(){
KeyguardManager mgr = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = mgr.newKeyguardLock(KEYGUARD_SERVICE);
lock.reenableKeyguard();
}
Of course, this doesn't use your custom lock screen, but it might not be necessary. If you do desire your own lock screen, then you should follow this guide
http://developer.android.com/guide/topics/admin/device-admin.html
to create one.
The code:
KeyguardManager mgr = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = mgr.newKeyguardLock(KEYGUARD_SERVICE);
lock.reenableKeyguard();
will NOT lock the screen. It just enables the keyguard lock. When you run with
lock.disableKeyguard();
and press lock button on the device it will not lock the keyguard.
To lock the screen programatically you have to refer to Device Admin and use locknow() method to lock immediately.
What I want to achieve is to give user a button saying 'Start broadcast receiving' and another one saying 'Stop broadcast receiving'.
I'm registering BroadcastReceiver for "android.provider.Telephony.SMS_RECEIVED" intent ('Start broadcast receiving' functionality):
incomingSmsReceiver = new IncomingSmsReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
getApplicationContext().registerReceiver(incomingSmsReceiver, filter);
Then I'm using unregisterReceiver() for 'Stop broadcast receiving':
getApplicationContext().unregisterReceiver(incomingSmsReceiver);
As you can see it's using the same reference (private static BroadcastReceiver incomingSmsReceiver;).
The problem is:
This works fine as long as my app's process is not terminated. When user click 'Start receiving broadcast' and after that my app is been killed by Android I'm loosing incomingSmsReceiver reference (when I run my app next time it's set to null by default). There's no way for user to stop receiving broadcast as the reference is lost.
How to persist this reference? And how to make it possible to call getApplicationContext().unregisterReceiver(incomingSmsReceiver); after recreating app's process by Android?
I've found better solution for such problem: Enable and disable a Broadcast Receiver (CommonsWare's answer).
The solution is to register BroadcastReceiver in AndroidManifest file. Then to use PackageManager.setComponentEnabledSetting(...) to enable / disable this component.
AFAIK, you don't need to hold on to the exact same BroadcastReciever reference. Create a new reference in the exact same way in which you would create one normally and pass it to unregisterService.
How can I know if the screen is ON/OFF?
If you simply wish to poll the current state you can do so this way.
pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
boolean screen = pm.isScreenOn();
If you are looking to be notified when the state changes you'll have to register a Broadcast Reciver to listen for ACTION_SCREEN_OFF and ACTION_SCREEN_ON. For this particular intent you must set your Intent Filter from java code. Doing so in the Manifest does not seem to work.
I have a broadcast receiver that listens for incoming calls, then displays a popup. The popup is a dialog type of theme and has FLAG_NOT_FOCUSABLE and FLAG_NOT_TOUCHABLE - basically, it's an informational window that goes away after x seconds, and is not meant to interfere or take focus over anything else.
The issue is that the incoming call intent, built into android, is getting the broadcast after my intent. This is causing that window to be stacked in front of mine. How to I get my window to always be on top?
Thanks!
A hack but solution that I ended up doing is to wait for a second or two after getting the broadcast. At that point, I know the incoming caller intent has processed and displayed the call window and can call my intent.