i want to receive a broad cast when the screen is turned off in android. I have written the following code. This is the Receiver's code.
#Override
public void onReceive(Context context, Intent intent) {
helper = new FeedReaderDBHelper(context);
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
System.out.println("Screen Off Receiver just received something");
if(helper.getValue(FeedReaderContract.FeedEntry.onlock).equals("YES"))
{
helper.lockAll();
wasScreenOn = false;
}
else if(helper.getValue(FeedReaderContract.FeedEntry.onLock3).equals("YES"))
{
System.out.println("Running 3 minutes thread");
Runner runner = new Runner(context);
Thread t = new Thread(runner);
t.setName("LockThreeThread");
t.start();
}
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// and do whatever you need to do here
wasScreenOn = true;
}
}
I am registering and unregistering the Receiver in a Service. The code is as follows.
Registring Receiver in onStartCommand method
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
isScreenOn = pm.isScreenOn();
RegisterReceiver();
//Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_SHORT).show();
//System.out.println("StartRemove");
helper = new FeedReaderDBHelper(this);
names = helper.getNames();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
startChecker();
}
});
t.start();
return START_STICKY;
}
And this is how i unregister in onDestroy of the Service method.
private void RegisterReceiver()
{
receiver = Factory.getScreeReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(receiver, filter);
}
Please let me know what could be the problem. I have been digging into it for long time. Last two days were wasted on this. Nothing seems to work.
I think you're overly complicating this.
This is the activity you would need
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent startServiceIntent = new Intent(this, MyService.class);
startService(startServiceIntent);
}
This is the service
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("APP", "Service started");
ScreenOffReceiver receiver = new ScreenOffReceiver();
registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
return START_STICKY;
}
}
And this is the Broadcast Receiver
public class ScreenOffReceiver extends BroadcastReceiver {
public ScreenOffReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Log.i("APP", "EVENT occured");
}
}
I just tried out this code and the logging worked fine.
When you start this via a service, and start a new thread to do the job in the onStartCommand() method, be noted that the thread will start every time you invoke the onCreate() of the activity.
Hope this helps
Related
so i am trying to create a battery statistics android app but neither i'm able to receive broadcast using broadcastmanager cos its not available for android oreo and nor my service is running on background for more than a few minutes.
my question is how do i receive battery broadcasts like plug,unplug,level..... in background on android oreo api 26+
i run the service from the activity on destroy
/////my service code/////
public class bservice extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter ifl = new IntentFilter();
registerReceiver(bcr,new IntentFilter(Intent.ACTION_POWER_DISCONNECTED));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_POWER_CONNECTED));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_SCREEN_OFF));
registerReceiver(bcr,new IntentFilter(Intent.ACTION_SCREEN_ON));
registerReceiver(bcr,ifl);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10000);
update();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Log.d("msg","running in background 1");
return Service.START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private final BroadcastReceiver bcr = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
update();
Log.d("msg","running in background 2");
}
};
#Override
public void onDestroy() {
super.onDestroy();
//unregisterReceiver(bcr);
Log.d("msg","service destroyed");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(new Intent(this,bservice.class));
Log.d("msg","serv restarted");
}
}
void update()
{.......... my updating code
updaten(pct,cc,isCharging,isCharging);
}
Notification notification;
NotificationManager notificationManager;
void updaten(float pct,float cc,boolean a,boolean ot)
{.........my notification update code
notificationManager.notify(id, notification);
}
}
}
Use JobIntentService instead of Service and then register broadcast receiver dynamically from service.
https://developer.android.com/reference/android/support/v4/app/JobIntentService.html
What are the best practices for running worker threads in the background that periodically update UI elements in an activity. The goal here is to avoid any screen freezing on any kind of updates and if there are any specific guidelines/standards that should be followed.
Try Service for Background Work.
I have made an example for you.
Try this.
TestActivity.java
public class TestActivity extends AppCompatActivity {
private final String TAG = "TestActivity";
public final static String RECEIVER_ACTION = "com.action.MyReceiverAction";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_work);
registerMyReceiver();
startService(new Intent(this, BackgroundService.class));
}
MyReceiver myReceiver = new MyReceiver();
private void registerMyReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RECEIVER_ACTION);
registerReceiver(myReceiver, intentFilter);
}
class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive() called");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
}
BackgroundService.java
public class BackgroundService extends Service {
private String TAG = "BackgroundService";
#Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate() called");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind() called");
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand() called");
notifyToUI();
return super.onStartCommand(intent, flags, startId);
}
/**
* This Methd will notify your Activity
*/
private void notifyToUI()
{
Intent myIntent = new Intent();
myIntent.setAction(TestActivity.RECEIVER_ACTION);
sendBroadcast(myIntent);
}
}
Now at the end register BackgroundService in AndroidManifest.xml file
<service android:name=".BackgroundService"/>
Use AlarmManager (or some other timer) to periodically start a service. That service then updates the model, and notifies UI thread with for example LocalBroadcastManager. UI thread can then use BroadcastReceiver to catch the Intent and update itself.
I'm trying to catch when my device screen is turned off or on. I looked at this answer here. However I haven't quite figured it out. When I test it, I get a warning saying that the service wasn't able to be created: Unable to start service Intent... not found. I'm new to services so I was hoping someone could look over the code and see what I'm doing wrong. Here is my Receiver and Service:
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;
Home.locked = true;
Log.i("screenstate", "off");
} else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.i("screenstate", "on");
}else if(intent.getAction().equals(Intent.ACTION_ANSWER)) {
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}}
Service:
public class UpdateService extends Service {
BroadcastReceiver mReceiver;
Boolean isRunning;
Context context;
Thread backgroundThread;
#Override
public void onCreate() {
super.onCreate();
context = this;
isRunning = false;
// register receiver that handles screen on and screen off logic
Log.i("UpdateService", "Started");
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_ANSWER);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
isRunning = false;
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, 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");
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}}
Here is my main activity:
public class Home extends Activity {
static boolean locked = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(Home.this, UpdateService.class));
if(locked)
setContentView(R.layout.activity_home2);
else
showApps(null);
}
public void showApps(View v){
locked = false;
Intent i = new Intent(this, AppsList.class);
startActivity(i);
}}
Thanks in advance.
It looks like the service hasn't been declared in the manifest file. Add its declaration within the <application> tag:
<service android:name=".UpdateService"/>
I want to create an app that will know when user is using the phone(start the screen and close the screen). After a period of time I need to call doSomething() method.
Question:
1.How can I know when user start using the phone and when he close the screen?
2.Should I use Service or IntentService? Which is better in my case?
You can try something like this using a BroadcastReceiver and a Service:
Your class using The BroadcastReceiver:
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
And the service:
public static class ScreenService extends Service {
#Override
public void onCreate() {
super.onCreate();
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) {
//Implement here your code
} else {
//Implement here your code
}
}
}
I have broadcast receiver that activates on phone boot
public class autostart extends BroadcastReceiver {
public void onReceive(Context arg0, Intent arg1) {
Intent intent = new Intent(arg0, MyService.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
}
The service is very simple it just keeps registered an broadcast receiver that can be only registered by code and not from manifest
public class MyService extends Service
{
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
ScreenOffReceiver actionScreenOffReceiver;
#Override
public void onStart(Intent intent, int startid)
{
try {
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(Intent.MY_ACTION);
registerReceiver(actionScreenOffReceiver = new ScreenOffReceiver(),
intentfilter);
} catch (Exception e) {
}
}
}
The problem is that if the app get closed, for example with call of finish() on some activity, then the service just dies.
How can I keep the service running till the phone is turned on
what is the right way to do this ?
You don't need an BroadcastReceiver just add this code in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Source: Service | Android Developers