Release WAKELOCK when screen is off - android

I'm making an Android TV and Amazon Fire TV app that uses WAKELOCK to prevent the TV device from going to sleep. What I need to do though is release the WAKELOCK when the screen gets turned off, e.g. when someone presses the power button on the TV, as in this case the Amazon Fire TV Stick etc stay active although the TV is powered off.
I then need to re-add the WAKELOCK when the TV is powered on. What is the accepted best practice for handling this?

EDIT: as per comment I'm updating this response with the most effective method.
In a nutshell you can achieve this in two ways:
Check if the HDMI gets disconnected (mainly works on phones, keep reading for TV)
Check if the audio channel becomes noisy. As per Android documentation (https://developer.android.com/guide/topics/media/mediaplayer.html#noisyintent) you can do something like the following (change with ):
"You can ensure your app stops playing music in these situations by handling the ACTION_AUDIO_BECOMING_NOISY intent, for which you can register a receiver by adding the following to your manifest:
<receiver android:name=".MusicIntentReceiver">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
This registers the MusicIntentReceiver class as a broadcast receiver for that intent. You should then implement this class:
public class MusicIntentReceiver extends android.content.BroadcastReceiver {
#Override
public void onReceive(Context ctx, Intent intent) {
if (intent.getAction().equals(
android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
// signal your service to stop playback
// (via an Intent, for instance)
}
}
}

Related

Send Extra data on Audio Manager object to ensure android.media.RINGER_MODE_CHANGED Action Receiver receives this information

I have a Broadcast Receiver that listens to Ringer mode change action as follows:
public class RingerModeStateChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("RECEIVER", "Ringer Change detected.");
}
}
The manifest declaration is as follows:
<receiver android:name=".receivers.RingerModeStateChangeReceiver" >
<intent-filter>
<action android:name="android.media.RINGER_MODE_CHANGED" />
</intent-filter>
</receiver>
My app changes the Ringer mode by making use of Audio Manager as shown below:
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if(someCondition) {
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
} else {
audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
}
Is there a way to detect the ringer change to be coming from Audio Manager(may be by adding some extra content to the audio manager object) in my broadcast receiver?
UPDATE:
I have solved this problem by making use of 2 boolean variables, one representing the updates made to RINGER by some external force and the other representing the updates made by my code. The former is true by default and the later false. The later becomes true only when the update to Ringer is about to be made by my code.
This allows the broadcast receiver to differentiate between external and internal changes made to the RINGER.
Although, this still is a workaround and I am still nowhere close to finding a solution internal to the android system (if at all one does exist).

Intent filter when Android Auto started

Does there exist an intent filter which indicates when Android Auto starts? am building an app that start background thread, and I want connect to a device using Bluetooth to get remote control of head unit from custom hardware.
You can use ACTION_ENTER_CAR_MODE in a broadcast receiver to listen for when Android Auto starts and connects. Just keep in mind that ACTION_ENTER_CAR_MODE is not exclusive to Android Auto, it just means the OS is in car mode, which may or may not involve Android Auto.
Also, to satisfy the Android O requirements, you’ll need to make an explicit registration of the receiver by registering it in the activity. As a result of registering it in the activity it will not receive the broadcast on the very first connection to Auto, but only after the activity has been created and then on each connection afterwards.
<receiver
android:name=".CarModeReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.app.action.ENTER_CAR_MODE"/>
<action android:name="android.app.action.EXIT_CAR_MODE"/>
</intent-filter>
</receiver>
Then in the implementation of the receiver...
public class CarModeReceiver extends BroadcastReceiver {
#Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(action)) {
Log.d("CarModeReceiver", "Entered Car Mode");
} else if (UiModeManager.ACTION_EXIT_CAR_MODE.equals(action)) {
Log.d("CarModeReceiver", "Exited Car Mode");
}
}
}
It's also worth noting that from the documentation linked above...
In addition, the user may manually switch the system to car mode without physically being in a dock. While in car mode -- whether by manual action from the user or being physically placed in a dock -- a notification is displayed allowing the user to exit dock mode. Thus the dock mode represented here may be different than the current state of the underlying dock event broadcast.

ACTION_SCREEN_OFF background service trigger

I have a notification being fired through AlarmManager and the notification also
plays a sound.
Obviously, it may happen that the alarm is fired when the app is in the background, and I would like to let the user cancel the sound when pressing the lock button - i.e. listening for ACTION_SCREEN_OFF.
Therefore I wonder if it's possible to start a service and listen for ACTION_SCREEN_OFF?
I have seen Listening for ACTION_SCREEN_OFF but that solution of having a BroadCastReceiver only seems to work when the app is in the foreground. Right?
For instance if you are trying to do ACTION_SCREEN_OFF then you would define your broadcast receiver in your Activity that started the alarm for instance.
public class SomeListener extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//Turn off sounds
}
}
Then in the manifest provide something of the sort like this within the activity that uses the listener.
<intent-filter>
<action android:name="android.hardware.usb.action.ACTION_SCREEN_OFF" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.ACTION_SCREEN_OFF"
android:resource="#xml/my_filter" />
Where the extra my_filter class could provide additional meta-data. In this case it was a check against a Serial or UUID of the device so not to launch on all USB connects. But you should be able to do something similar.
When the action occurs, this should fire the listener within your application, as I understand it anyways. This feature works for launch of application on USB connect for me in the past. Even without having had the application open in the first place.

Detect Camera button in sleep mode

Is there anyway to detect hthe camera button in Sleep mode? I tried the examples explained in this forum, but nothing works in Sleep mode.. I am llooking for this for a long time, but no proper answers..
How I can receive hardware key events in sleep mode?
Please help me...
public class YourBoardcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_CAMERA_BUTTON.equals(intent.getAction())) {
Intent main = new Intent();//
}
}
}
And in your Manifest :
<receiver android:name="YourBoardcastReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
</intent-filter>
</receiver>
This is not possible. When the device is put in sleep mode, almost all apps are paused or stopped. Only enough of the processor is kept on to be able to receive calls and SMS texts, and manage alarms and notifications. Apart from that, pretty much everything is discontinued.
If you want to keep detecting it when the screen is off, you will need to acquire a wakelock to prevent the device from going into sleep. However, if you do this all the time it will have an impact on the users' battery life.

App not receiving broadcast when originated in Launcher but receiving when originated from other App

I Have an app that is showing a toast when receiving broadcast and action equals BluetoothAdapter.ACTION_STATE_CHANGED, everything is working OK, but the problem here is that I want to do something when bluetooth is turning on but when bluetooth is activated from a button of the launcher it seems like the broadcast is arriving late or my app is receiving late or something like that, because when I started Bluetooth from other app, the receiver works great and on time.
Any suggestion in what is the problem? I have the receiver registered in manifest.
and it seems that sometimes loops infinitely because I have two toast to show when bluetoothAdapter.ACTION_STATE_CHANGED and it shows infinitely
Any idea of why is happening this and previous things?
Receiver:
public class Receivers extends BroadcastReceiver {
protected static AlertObject BTTurningOn = new AlertObject();
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
final String action = intent.getAction();
this.context=context;
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
if(state == BluetoothAdapter.STATE_TURNING_ON && BTTurningOn.Activated == true)
{
Alert(BTTurningOn);
}
}
}
BTTurningOn is just an object with some boolean variables to know whether to attend the broadcast message or not
Here is the important part of manifest:
<receiver android:name=".Receivers">
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
</intent-filter>
</receiver>
When I start the bluetooth from my other app or from Adjusts/ wireless connections it works great, but its not working when I start it from an icon of the launcher or the upper bar where notifications appear, Im using GO Launcher EX Version 2.76
My other app get the broadcast and works great from the site that this app is not getting, but the difference is only where I register the receiver, this app is in MAnifest and other app is on one Activity
The answer is: I did not have the bluetooth permission in manifest, but it's kinda strange because it did not receive broadcast messages when originated from Launcher but actually the app received them when originated from my other app

Categories

Resources