Is there any way to create a service that runs forever on a background for Android user to check whether their screen on or off, etc?
I'm about to create an analytics, so I need to know when the user turn on or turn off their screen.
Thanks, I will appreciate all the input
You may use Android broadcast receiver to detect screen on and off.
Here is a good example of it
https://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
you may also follow this thread
https://stackoverflow.com/a/9478013/2784838
You need to create broadcast receiver and manage screen on or off status.
Declare receiver in manifest:
<receiver android:name=".DeviceWakeUpReceiver" />
public class DeviceWakeUpReceiver extends BroadcastReceiver {
private static final String TAG = "DeviceWakeUpService";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive() called");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//End service when user phone screen off
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//Start service when user phone screen on
}
}
}
You cannot use a BroadcastReceiver for receiving screen off/on events.
Write a intent service which is started via boot complete listener and register for Intent.ACTION_SCREEN_OFF and Intent.ACTION_SCREEN_ON.
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(new ScreenOffOnReceiver(), filter);
class ScreenOffOnReiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// Screen OFF
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// Screen ON
}
}
}
Related
Im developping app for tablets, its a car navigation.
What I need to do is - if the driver turns on car the tablet turns on screen, if the car is shut down display is off.
My first thought is to keep tablet plugged to the car charger and if the charging is detected turn on display. If the charging is not detected turn off display.
App would run in KIOSK mode. What would be the best approach to detect charging status while screen is off ?
It's pretty simple.
First you need to listen for charging state changes. It can be done by:
//Create receiver
BroadcastReceiver powerChangeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_POWER_CONNECTED.equals(action)){
turnScreenOn();
} else if(Intent.ACTION_POWER_DISCONNECTED.equals(action)){
turnScreenOff();
}
}
};
//Register receiver
IntentFilter i = new IntentFilter();
i.addAction(Intent.ACTION_POWER_CONNECTED);
i.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(powerChangeReceiver, i);
and now all you need to do is to implement turnScreenOn() and turnScreenOff() methods:
public void turnScreenOn(){
runOnUiThread(() -> {
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(POWER_SERVICE);
#SuppressWarnings("deprecation")
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP, "example:tag");
wl.acquire();
});
}
public void turnScreenOff(){
if(policyManager.isDeviceOwnerApp(getPackageName())) {
runOnUiThread(() -> {
policyManager.lockNow();
});
}
}
and don't forget to add WAKE_LOCK permission to your Manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Hope it helps!
I created a floating widget that works even when the app closed. In addition I have a class that is responsible for detecting incoming and outgoing calls on the device And send a suitable toast. it also works when the app is closed.
Now I want the floating widget to appear on the screen when a call on the device ends.
I tried to do this but the widget does not appear. Both work separately, but not together.
There are two classs:
-Creates the widget : FloatingViewService extends Service.
-Call Recognition: CallReceiver extends BroadcastReceiver.
CallReceiver class
public class CallReceiver extends BroadcastReceiver {
// ^ detecting incoming and outgoing calls ^
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
showToast(context,"Call started...");
}
else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE)){
showToast(context,"Call ended...");
//*****Activate the floating widget after the call ends.
startWidget( context );
}
else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)){
showToast(context,"Incoming call...");
}
}
//*****Activate widget
void startWidget(Context cotx) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //Permission checks
if (Settings.canDrawOverlays(cotx)) {
// Start widget service
startService( new Intent( cotx, FloatingViewService.class));
}
}
}
//*****Action: Start a particular service
public ComponentName startService(Intent service) {
throw new RuntimeException("Stub!");
}
//Another action unrelated to my question
}
I believe the problem is related to the "startService" operation.
I was able to solve the problem for myself in a relatively simple way.
All I had to do was delete "startService" and update "startWidget" as follows:
void startWidget(Context cotx) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //Permission checks
if (Settings.canDrawOverlays(cotx)) {
Intent intent = new Intent(cotx,FloatingViewService.class);
cotx.startService(intent);
Log.i("Autostart", "started");
}
}
}
I'm developing lock screen app. Here Lock screen is displayed on the top of the screen using this command "WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;"
But my problem is I can't See the Incoming call Window when the custom lock screen is displayed. Incoming call window is not overrided over my custom lock screen.
1) Is there any permission required for displaying the incoming call window.?
2) We have to add any other codes for answering the incoming class
This is my Lockscreen receiver class
public class LockScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(Intent.ACTION_SCREEN_OFF) || action.equals(Intent.ACTION_BOOT_COMPLETED))
{
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
In the normal lock screen apps -> They can attend the incoming calls and after attending that call, lock screen is displayed. How ????
Please help me. Thanks in advance
Add receiver in the manifest and ask for permission
<receiver android:name=".IncomingCall">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
Create class IncomingCall
public class IncomingCall extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
try {
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
MyPhoneStateListener PhoneListener = new MyPhoneStateListener();
// Register listener for LISTEN_CALL_STATE
telephonyManager.listen(PhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
} catch (Exception e) {
e.printStackTrace();
}
Implement PhoneStateListener in LockScreen and call onCallStateChanged
private class LockScreen extends AppCompatActivity implements PhoneStateListener{
public void onCallStateChanged(int state, String incomingNumber) {
//Disable lockscreen when calls come
}
I am newbie in android programming; sorry if my question is easy :)
I'm trying to write code that monitors the battery level on the phone and if it is, lower some level for example (%15), create a message that asks user to plug the charger. I know that I need to use BroadcastReceiverclass and I want to use it in my MainActivity class. Here is the code I have:
public class MainActivity extends Activity{
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
String intentAction = intent.getAction();
Log.d("receiver", intentAction);
int level = intent.getIntExtra("level", 0);
if (level < 15){
Log.d("receiver", "battery level low");
}
if (Intent.ACTION_BATTERY_OKAY.equalsIgnoreCase(intentAction)) {
Log.d("receiver", "battery level okay");
}
}
};
......
but it seems that the onReceivemethod is never called since I never see the Log.d("receiver", intentAction) message on Android Studio debug window.
I also have registered br in onResume and unregistered it in onPause:
public void onResume() {
super.onResume();
filter.addAction("receiver");
registerReceiver(br, filter);
}
public void onPause() {
super.onPause();
unregisterReceiver(br);
}
But still I am not getting any message.
Can anybody please help me? Should I also add something to AndroidManifest.xml?
If you dont want to use BroadcastReceiver simply dont use it. Battery intent is sticky intent so you can check it without need of BroadcastReceiver and i also dont think its good idea to put receiver in activity. You can check battery stuff in your activity like this and you dont need to edit your manifest
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, filter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level / (float)scale;
if(batteryPct < 15){
//do your stuff
}
Your code in onResume() is wrong. You will have to update it as follows.
filter.addAction(Intent.ACTION_BATTERY_LOW);
filter.addAction(Intent.ACTION_BATTERY_OKAY);
registerReceiver(br, filter);
to include the ACTION_BATTERY_LOW and ACTION_BATTERY_OKAY filters as mentioned in the docs.
I want to listen the power key event in the service.
How can in do that ?
Currently I am working with an app, where I need to listen the power button for some events, from a service which is running in a background, even when the app is killed or stopped.
Somehow I can manage to get it.
But when I kill/stop the app, the service is getting stopped.
How can i overcome this ?
Currently the code i am using this :
Service Class:
public class SampleService extends Service
{
SettingContentObserver mSettingsContentObserver;
AudioManager mAudioManager;
private ComponentName mRemoteControlResponder;
private Intent intent;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("StartServiceAtBoot", "StartAtBootService -- onStartCommand()");
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Toast.makeText(getApplicationContext(), "On", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Off", Toast.LENGTH_SHORT).show();
}
}
public void onCreate()
{
mSettingsContentObserver = new SettingContentObserver(this,new Handler());
getApplicationContext().getContentResolver().registerContentObserver
(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver );
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mRemoteControlResponder = new ComponentName(getPackageName(),
StartAtBootServiceReceiver.class.getName());
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new StartAtBootServiceReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onDestroy()
{
getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);
}
}
BroadcastReceiver Class:
public class StartAtBootServiceReceiver extends BroadcastReceiver
{
static boolean wasScreenOn;
private boolean screenOff;
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
wasScreenOn = false;
Toast.makeText(context, "Power Off", Toast.LENGTH_SHORT).show();
}
else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
wasScreenOn = true;
}
Intent i = new Intent(context, SampleService.class);
i.putExtra("screen_state", screenOff);
i.setAction("com.example.antitheft.SampleService");
context.startService(i);
//
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i1 = new Intent();
i1.setAction("com.example.sampleonkeylistener.MainActivity");
context.startService(i1);
}
}
}
given above is the sample code and i have created AndroidManifest.xml files also with user's permission but i cannot get the app continue service if it is killed or stopped.
Thanks in Advance.
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, SampleService.class));
}
This is one way to ensure that service will never stop even user want to destroy it.
This is one Just ONE of ways to achieve what you are trying to achieve.
Secondly, you can try and run service in "foreground" by using startForeground().
Also, make sure that in you return "START_STICKY" (which you are doing in the sample code that you shared and I trust that you are also doing in App's code too :) ) in Services's onStartCommand().
This will ensure that If this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service.
And you may find some additional pointers/hints to make sure your service is not stopped at below link.
How can we prevent a Service from being killed by OS?
Just pick and choose the approach that best suits YOUR Need/implementation.