Receive volume key press events when phone is in deep sleep - java

I'm trying to catch Volume Up/Down pressing events when phone is in deep sleep mode. I have read several articles and here what I have done.
In Activities onCreate method I set a WakeLock
PowerManager mgr = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wakeLock.acquire();
I have read that even if my screen is locked if I set this my application will respond to events. Also I have added permission in to Android Manifest.
<uses-permission android:name="android.permission.WAKE_LOCK" />
Then in the onCreate method I declare my Broadcast Receiver
VolReceiver volumeBroadcastReceiver = new VolReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.media.VOLUME_CHANGED_ACTION");
registerReceiver(volumeBroadcastReceiver, filter);
This all works pretty good then application is in foreground or background, but then I lock my phones screen by pressing on a power button application stop receiving broadcast events, I think that PowerManager must solve this issue but it doesn't. So please help me, provide some information.

I'm trying to catch Volume Up/Down pressing events when phone is in deep sleep mode.
By definition, that is impossible.
In Activities onCreate method I set a WakeLock
Then you are not in sleep mode.
then I lock my phones screen by pressing on a power button application stop receiving broadcast events
There are a few possibilities here. One is that your process was terminated, as it is no longer needed. Once you no longer have any foreground activities, your process is eligible to be terminated to free up memory for other apps, and that can happen at any point. Another possibility is that Android simply does not send that broadcast when the screen is off.

I did pretty much the same thing, but i achieved it by changing the source codes. i have explained that below.
whenever your phone goes to sleep , your MediaPlaybackService.java will not listen to keyEvents, but MediaButtonIntentReceiver.java will, so receive the intent here of volume up and down, and broadcast an intent and receive it in MediaPlaybackService.java, but keep one thing in mind you can't change the UI from here , so you can broadcast another intent from the service and make your MediaPlaybackActivity.java receive it , this will change the UI as soon as your screen wakes up.
FYI: when the screen is off, the PhoneWindowManager.java queues all the continuous intents and as soon as you release the button it will apply all the intents at once.

Related

Background app best practices

Is Service and Notification the correct way to implement a background app with the following behavior?
1- User open the app, make some configurations and touch in a "run" button;
2- The main activity must be closed and a background service will be started;
3- A fixed notification will be displayed with some buttons ("stop" to finish the service and "Reconfigure");
thank you
I did an app that at short intervals (1 to 10 sec) acquires constantly data from a remote TCP server, even on the background also with the screen off.
In the Main Activity onStop I acquire a Partial WakeLock and I start the Service with STARTFOREGROUND_ACTION intent, the Service calls startForeground and shows the Notification.
On Activity onResume the WakeLock is released, the Service stops with STOPFOREGROUND_ACTION intent and the Service itself calls stopForeground & stopSelf.
I don't have buttons in the notification, if user touches the notification the Activity is shown.
It works very well I tested it with hours of continuous operation.

Listen for NFC while device asleep

I try to make an app which will catch NFC rfid, start app, and show some data.
It works well as long as the phone is awake.
Now I find one way - don`t allow the phone to sleep. The app runs constantly with brightness set to 0, and when it detects an NFC signal, brightness goes to 100.
But this is not good for battery. I want to just turn off the screen, but don`t sleep, because I need listen NFC, and wakeup.

Android: turn off display without destroying or pausing activity

i have a mediaplayer in an activity, i want to implement a feature in which when a user clicks a button, the screen display goes off, but the video continues to play in that activity.
Acording to the life cycle of the Android activity, when an activity becomes background, onPause is called, however, from now on, the system can kill the activity by its will, ie. the system requires more memory.
It'S the system that decides to kill the activity or not, not the developers. In general, It'S because more memory are needed.
Understand the Lifecycle Callbacks
You need to implement a Service. Start at this link on how to do it: https://developer.android.com/guide/topics/media/mediaplayer.html#mpandservices
activity should be paused
you can override the procedure onPause() and onResume() to check the event
when pause, you pause the media, when resume you resume the media
the media is playing the other thread and draw the activity. when the activity is pause, but the media thread is working.

How do i start activity when screen goes off?

I have an application which is doing its work only when devices screen goes off. I have set up broadcast receiver (Intent.ACTION_SCREEN_OFF) and it works fine. I got record in my LOGCAT always when devices screen goes off. So far so good.
My onReceive code from ACTION_SCREEN_OFF uses some code calculating stuff, and all executes fine (When screen goes off). So far so good.
At the end of my onReceive code i'm starting new activity, but the onCreate of targeting activity is NOT always executing. (For example on my HTC Desire 2.3.7 works fine. On HTC Wildfire S 2.3.5, Xperia Arc S 2.3.4 it does not execute, and on Samsung Galaxy ACE 2.2.1 , it depends. Sometimes is executing sometimes isn't). My LOGCAT shows that onReceive executed till the end but Activity was not started. I'm using following code to starting this activity:
Intent startH_Activity = new Intent(getApplicationContext(), HandleActivity.class);
startH_Activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startH_Activity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(startH_Activity);
The important things to note:
I said that on some phones mentioned above it doesn't work. Well its not working immediately, like it should (when SCREEN_OFF fires ). Always activity starts like.. 10-15 minutes after screen went off (which is not acceptable)
When screen goes off and activity does not start , if I press POWER button on device it immediatelyfires off my target activity and app is working like normal. (again this is not acceptable. It should fire automatically).
When ANY device is connected to the PC it works like it should. Activity starts immediatelyafter screen goes off.
After reading a lot of Stack Overflow I realized that this is because MAYBE device goes to sleep. That's why it works like normal if i press POWER button, or Wakes up automatically after 10-15min because it synchronizes or something. So I used WAKELOCK.
//OnCreate Service
powMan = (PowerManager) getSystemService(POWER_SERVICE);
wake = powMan.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
//OnReceive (screen goes off)
wake.acquire();
But still without a success. (Am i doing wrong?) Even wake lock is acquired my activity won't show up on these devices.
Basically what I'm asking. How do i open usual activity when screen goes off? Or at least how to turn screen ON if activity won't start (remember, pressing on power button shows up my activity
I would really need some help now, because I'm getting really frustrated about this. Thank you for help.
You should be starting Service instead of Activity when screen goes off.
I would register yet another broadcast receiver and start the Activity when screen goes on (Intent.ACTION_SCREEN_ON).
Two issues:
1) How do you pass data from one receiver to another? What comes to my mind is either starting a Service or saving the information to a file (or shared preferences).
2) What happens if you have two events that must start an Activity? (E.g. "something started" and "something finished".) You must resolve this, either showing both events or just the latest one.
Note that the user can turn the screen on and off without unlocking the screen (Intent.ACTION_USER_PRESENT), and that if the phone is configured not to lock the screen, Intent.ACTION_USER_PRESENT does not happen.

Android - other app stealing my intent receiver?

I have an app which uses the ACTION_MEDIA_BUTTON intent with a BroadcastReceiver to control a music player. The user pushes a button on external hardware and it controls the in-app music player. The user can also HOLD DOWN the button and change the volume.
I recently downloaded another app which uses the headset button, and it takes over the media button intent from my app! So when this other app is open and I press the button, the other app will start running, but my app will think that the button is still pressed down so it will cycle the volume.
To summarize,
my app is open, supposed to be sole listener of media button intents
other app gets opened, it also wants to be sole listener of media button intents
button gets pressed with both apps open, control goes to other app
my app thinks the button is being held down, as it lost control as the button was pressed in down mode (I think). It then launches functions I don't want launched because it thinks the user has held down the button.
Is there any way I could make sure that while my app is open it's the sole receiver of this media button intent? Could I at least check to see if another app has taken over, so I can prevent unexpected behaviour?
Thank you for any help, I've never had apps not play nicely before!
You can alter your BroadcastReceiver's priority (make it something large, like 10000): it should then get the Intent first, and then you can pass it on to the other app.
I have a similiar issue. I believe, outside of the 'arms race' over the priorites mentioned, the only real solution is to close the other application. If you are releasing this application to other users, you could possibly give them a message telling them to close other media player apps and services.
In your manifest you can set the intent priority to the max value of an integer which is: 2147483647.
You should not however set your IntentFilter priority over 1000 as it tells you in the API docs. You can set the IntentFilter priority like so:
myIntentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
I assume you should subtract one from the SYSTEM_HIGH_PRIORITY constant as the docs say the value must be less than SYSTEM_HIGH_PRIORITY.
Quote from docs about IntentFilter.setPriority(int):
Applications must use a value that is larger than SYSTEM_LOW_PRIORITY and smaller than SYSTEM_HIGH_PRIORITY.

Categories