I want to run a method when android phones screen lock appear.
I tested ACTION_SCREEN_ON as a broadcast, but it only works when the activity is live.
I also tested ACTION_USER_PRESENT and it works when the phone is unlocked, but I want to run the method before unlocking (just when the screen lock appears).
I also tested AlarmManager by repeating alarm every 1 minute, but this solution has two defects:
Battery soon gets empty.
It's a deprecated way, and I don't need to do method every 1 minute.
What should I do?
You can create a service that listen to ACTION_SCREEN_ON broadcast.
Below are the example code for your reference:
public class LockScreenService extends Service {
private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case Intent.ACTION_SCREEN_ON:
// do your stuff
break;
}
}
};
public LockScreenService () {}
#Override
public void onCreate() {
super.onCreate();
// register ACTION_SCREEN_ON receiver
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
registerReceiver(mScreenStateReceiver, filter);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// do some extra things
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// do not bind service to activity because service will end if activity is destroyed
return null;
}
#Override
public void onDestroy() {
// release receiver
unregisterReceiver(mScreenStateReceiver);
}
}
Full Answer :
use service and set it START_STICKY.
It Causes after killing service the service will restart again.
it is my code :
android manifest :
<application
....
<service android:name=".UpdateService" />
</application>
service class :
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class UpdateService extends Service {
BroadcastReceiver mReceiver;
#Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
Log.i("onDestroy Reciever", "Called");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if ( !screenOn) {
Log.i("screenON", "Called");
Toast.makeText(getApplicationContext(), "Awake", Toast.LENGTH_LONG)
.show();
} else {
Log.i("screenOFF", "Called");
Toast.makeText(getApplicationContext(), "Sleep",
Toast.LENGTH_LONG)
.show();
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
}
receiver class :
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
Log.i("screenLog", "screen off");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
Log.i("screenLog", "screen on");
}
}
}
in StartupActivity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context context = getApplicationContext();
Intent service = new Intent(context, UpdateService.class);
context.startService(service);
}
Related
package com.vkstechnologies.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.widget.Toast;
/**
* Created by Vipul-Laptop on 03-01-2018.
*/
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(!hasFocus) {
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
}
I want to make an application that runs in background and detects whenever a power key is pressed to shut down the phone and it just dismisses the "power off" window.
If I run this method in MainActivity, then it runs smoothly, but not in service.
The Error says : cannot resolve method onWindowFocusChanged
I want to do a method when lock screen displayed (not when unlocked or screen on, just when lock screen displayed).
i try with broadcast and services but they don't work after killing app.
Also In eclips LogCat i see a log like /WindowManager(473): Lock screen displayed! that genymotion produce .
maybe can be done with windowmanager..
Try something like the following:
KeyguardManager myKM = (KeyguardManager)
context.getSystemService(Context.KEYGUARD_SERVICE);
if( myKM.inKeyguardRestrictedInputMode()) {
// it is locked
}
else {
// it is not locked
}
This should allow you to determine the locked status of the device.
I found it.
using service and set it START_STICKY.
after killing service the service restart again.
it is my code :
android manifest :
<application
....
<service android:name=".UpdateService" />
</application>
service class :
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class UpdateService extends Service {
BroadcastReceiver mReceiver;
#Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
Log.i("onDestroy Reciever", "Called");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if ( !screenOn) {
Log.i("screenON", "Called");
Toast.makeText(getApplicationContext(), "Awake", Toast.LENGTH_LONG)
.show();
} else {
Log.i("screenOFF", "Called");
Toast.makeText(getApplicationContext(), "Sleep",
Toast.LENGTH_LONG)
.show();
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
}
receiver class :
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
Log.i("screenLog", "screen off");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
Log.i("screenLog", "screen on");
}
}
}
in StartupActivity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context context = getApplicationContext();
Intent service = new Intent(context, UpdateService.class);
context.startService(service);
}
I have a BroadcastReceiver class in my Activity. I want to start a Fragment from the receiver class. Can i call that from the same Activity where the receiver is written?
Try something like this... And if your using your custom Broadcast Receiver then replace BroadcastReceiver this class with your receiver's class.
public class Demo extends AppCompatActivity {
private final IntentFilter filter = new IntentFilter();
private BroadcastReceiver networkStateReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onResume() {
super.onResume();
// Defining broadcast receiver in onResume()
networkStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Do what you want
}
};
// Registering receiver with intent filter, here intent filter can be changed
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(networkStateReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
// Unregister receiver in onStop to avoid any runtime exception
unregisterReceiver(networkStateReceiver);
}
}
Yes you can do it using LocalBroadCastManger
import android.app.Activity;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class LocalBroadcastExampleActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.log_list);
Button buttonStartService = (Button)findViewById(R.id.button_ok);
buttonStartService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Register MessageService in Manifest to work
startService(new Intent(LocalBroadcastExampleActivity.this, MessageService.class));
}
});
}
#Override
protected void onPause() {
// Unregister since the activity is paused.
LocalBroadcastManager.getInstance(this).unregisterReceiver(
mMessageReceiver);
super.onPause();
}
#Override
protected void onResume() {
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-event-name".
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter("custom-event-name"));
super.onResume();
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Get extra data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
public class MessageService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
sendMessage();
return super.onStartCommand(intent, flags, startId);
}
// Send an Intent with an action named "custom-event-name". The Intent
// sent should
// be received by the ReceiverActivity.
private void sendMessage() {
Log.d("sender", "Broadcasting message");
Intent intent = new Intent("custom-event-name");
// You can also include some extra data.
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
}
In my android application, I am registering multiple broadcast receiver that includes: WiFi, Screen and Activity. The app is running smoothly on Moto g and Samsung G3 but its stopped sensing Screen on/off, Wifi connect/disconnect and Activity events on another phone after three days of smooth execution. Since app is on user phone, i dont know the model/make. Other than event sensing, the usual location sensing is working fine (which is scheduled after every 10 mins). Any ideas what could be wrong? Otherwise, on my test devices it still runs fine (testing for more then 2 weeks). For reference, below is the code for screen sensor only. Also, I tried to register receiver in onstartcommand, but it didn't work on my test devices (See the commented part in screenService)
MainActivity:
Intent intentscreen = new Intent(getApplicationContext(), ScreenService.class);
startService(intentscreen);
ScreenService:
private final BroadcastReceiver mybroadcast = new ScreenReceiver();
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
/* if (intent!=null)
{
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mybroadcast, screenStateFilter);
}*/
return START_STICKY;
}
#Override
public void onCreate (){
super.onCreate();
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mybroadcast, screenStateFilter);
}
#Override
public void onDestroy()
{
super.onDestroy();
unregisterReceiver(mybroadcast);
}
}
ScreenReceiver:
public class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("Check","Screen went OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.i("Check","Screen went ON");
}
}
These BroadcastReceivers have to be registered dynamically
android.intent.action.SCREEN_ON
android.intent.action.SCREEN_OFF
android.intent.action.BATTERY_CHANGED
android.intent.action.CONFIGURATION_CHANGED
android.intent.action.TIME_TICK
EDIT:
MainActivity.java
package com.kishore_kumar.stackoverflow;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
BroadcastReceiver mybroadcast;
IntentFilter screenStateFilter;
static boolean alreadyListening = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mybroadcast = new ScreenBroadcastReceiver();
screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
If (!alreadyListening)
{
registerReceiver(mybroadcast, screenStateFilter);
alreadyListening = true;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
ScreenBroadcastReceiver.java
package com.kishore_kumar.stackoverflow;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ScreenBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.e("Check", "Screen went OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.e("Check","Screen went ON");
}
}
}
You can do this way:
Define Receiver in manifest file:
<receiver android:name=".ScreenOnOffListener" >
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.SCREEN_ON" />
</intent-filter>
</receiver>
Now add class which extends BroadcastReceiver:
public class ScreenOnOffListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("Check","Screen OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.i("Check","Screen ON");
}
}
Hope this will help you.
How can I know when an Android phone is going to sleep? I tried with the sample code but nothing is happening.
Here is what I have so far:
ScreenON_OFF_ACTIVITY.java:
package com.pack;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class ScreenON_OFF_ACTIVITY extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onCreate();
}
public void onCreate() {
// initialize receiver
System.out.println("onCreate1 ");
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
System.out.println("onCreate ");
}
#Override
protected void onPause() {
// when the screen is about to turn off
if (ScreenReceiver.screenOff) {
// this is the case when onPause() is called by the system due to a screen state change
System.out.println("SCREEN TURNED OFF");
} else {
// this is when onPause() is called when the screen state has not changed
System.out.println("this is when onPause() is called when the screen state has not changed ");
}
super.onPause();
}
#Override
protected void onResume() {
// only when screen turns on
if (!ScreenReceiver.screenOff) {
// this is when onResume() is called due to a screen state change
System.out.println("SCREEN TURNED ON");
} else {
// this is when onResume() is called when the screen state has not changed
System.out.println(" this is when onResume() is called when the screen state has not changed ");
}
super.onResume();
}
}
ScreenReceiver.java:
package com.pack;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ScreenReceiver extends BroadcastReceiver {
public static boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("onReceive ");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
System.out.println("SCREEN TURNED OFF on BroadcastReceiver");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
System.out.println("SCREEN TURNED ON on BroadcastReceiver");
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
UpdateService.java:
package com.pack;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
public class UpdateService extends Service {
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
System.out.println("Screen is off");
} else {
System.out.println("Screen is on");
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
According to my knowledge you can not know Android Phone is going to sleep or not.only one thing you can guarantee after relase wakelock android phone can be going sleep any time.
It can happen after screen off (screen black).