Background info: I'm trying to create a service. I create it in my main activity. I know the service is running because the notification is showing. So the service doesn't stop at any point.
What i want to happen: when the screen is locked/turned off i want a certain activity to be displayed for when the screen is turned back on.
What is happening: first, When the screen is turned back on the main activity shows and then the activity i want shows over that. I dont want the main activity to show at all when the screen is turned on .
Then i changed a few things: and now the desired activity flickers on the main screen and then vanishes. It seems very unreliable and only comes a few times.
That should be enough info, here is the code so far (specifically onReceive())
public class OverlayService extends Service{
//IN THIS CLASS CHECK WHETHER LOCK BUTTON WAS PRESSED OR IF PHONE WHEN TO SLEEP.. UPON AWAKENING START THE OVERLAY ACTIVITY...
private BroadcastReceiver mReceiver;
private boolean isShowing = false;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private WindowManager windowManager;
WindowManager.LayoutParams params;
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//Register receiver for determining screen off and if user is present
mReceiver = new OverlayStateReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(mReceiver, filter);
makeNotification();
}
void makeNotification() {
Notification notification = new NotificationCompat.Builder(this)
//TODO change icon
.setSmallIcon(R.drawable.test)
.setContentTitle("App")
.setContentText("service is running...")
.setPriority(Notification.PRIORITY_LOW)
.build();
startForeground(1, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public class OverlayStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("app", "load view");
showOverlayActivity(context);
}
}
}
private void showOverlayActivity(Context context) {
Intent intent = new Intent(context, OverlayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
#Override
public void onDestroy() {
//unregister receiver when the service is destroy
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
//TODO remove view if it is showing and the service is destroy
super.onDestroy();
}
}
Related
I have my application running a service for shake detect, however in my MainActivity, I have button for log out user, in which I must log out and terminate the service that detects the shake event.
my method for log out in my MainActivity is:
public void signOutAndFinish(){
//Stop Shakeservice
Intent intent = new Intent(this, ShakeService.class);
stopService(intent);
//Go to login activity
Intent iLoginView = new Intent(this, LoginActivity.class);
startActivity(iLoginView);
}
however if I shake my device after logging out, the service recognizes the shake, it is as if it will not kill it immediately:
Intent intent = new Intent(this, ShakeService.class);
stopService(intent);
The code in the method onDestroy is:
#Override
public void onDestroy() {
super.onDestroy();
}
How can I terminate the service so that when I log out the service dies?
Thanks for your help!
You can send a broadcast back your activity in the onDestroy() method of your service and then do the logout.
Here is some sample code of the above idea:
This for your service:
#Override
public void onDestroy() {
super.onDestroy();
Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data","Notice for logout!");
sendBroadcast(intent);
}
And this is for your activity:
private BroadcastReceiver br = new MyBroadcastReceiver();
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter("com.example.broadcast.MY_NOTIFICATION");
registerReceiver(br, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(br);
}
// An inner class at your activity
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
YourActivity.this.finish();
// or do anything you require to finish the logout...
}
}
however if I shake my device after logging out, the service recognizes the shake
Then presumably you did not clean up your Sensor stuff in the service's onDestroy() method.
How can I terminate the service so that when I log out the service dies?
You are doing that now. However, if you set up something in the service, such as listening to events from SensorManager, you need to clean that up, typically in onDestroy() of the service.
I have an app that plays video on ACTION_SCREEN_ON. However, I do not want to play the video if the reason of screen on is an incoming call. I tried to detect incoming phones with TelephonyManager.ACTION_PHONE_STATE_CHANGED but I could not. How can manage to do this? You can find my code below.
Services.java
public class Services extends Service {
private BroadcastReceiver sReceiver;
public IBinder onBind(Intent arg){
return null;
}
public int onStartCommand(Intent intent,int flag, int startIs) {
IntentFilter filter=new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
//TelephonyManager.ACTION_PHONE_STATE_CHANGED ????
sReceiver=new Receivers();
registerReceiver(sReceiver,filter);
return START_STICKY;
}
}
Receivers.java
public class Receivers extends BroadcastReceiver {
public void onReceive(Context context, Intent intent){
if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
Log.e("Log", "The screen is on.");
Intent i = new Intent(context.getApplicationContext(), CommercialVideo.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
else{
Log.e("Log", "The screen is off.");
}
}
}
The service works normally when is started from the MainActivity however when the application is removed from the recent apps or when activity is closed, the service is restarted instead of continuing from where it left off.
public class ServiceExample extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO: Implement this method
return null;
}
#Override
public void onCreate() {
// TODO: Implement this method
super.onCreate();
//Do Something
}
I need to perform an action in the background but it can not be stopped or restarted when the activity ends. The Service Statement is the best to Use?
Try putting this inside your service class.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Add below code to service and override onStartCommand and return START_STICKY
#Override
public void onTaskRemoved(Intent rootIntent){
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent = PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartPendingIntent
);
super.onTaskRemoved(rootIntent);
}
I start a service from activity button click that fire a service class and start Broadcastreceiver and it's run in background but I want to unregisterReceiver with a button click from same activity class.it seem not working.I added receiver class to menifest.
Here is my code.
Activity button click for registerreceiver
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent svc = new Intent(this, DemoService.class);
startService(svc);
});
DemoService.class
public class DemoService extends Service {
static final String LOGGING_TAG = "MyDemo";
private static Alarm1 tickReceiver =new Alarm1();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onStart(Intent intent, int startId){
super.onStart(intent, startId);
Log.v(LOGGING_TAG, "DemoService.onStart()");
}
#Override
public void onCreate(){
super.onCreate();
Log.d(LOGGING_TAG, "DemoService.onCreate()");
registerReceiver(
new Alarm1(),
new IntentFilter(Intent.ACTION_TIME_TICK));
}
}
Activity button click for unregisterReceiver
unreg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DemoService demo=new DemoService();
demo.unreg();
});
And receiver class
public class Alarm1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("tag","working");
}
How can I unregisterReceiver from unreg button click.
If I click in unreg button it show me error java.lang.IllegalArgumentException: Receiver not registered:
create a method for unregistering Receiver in Service class. And call the service with action like.
Intent svc = new Intent(this, DemoService.class);
svc.setAction("com.package.UN_REGISTER");
startService(svc);
and in Service class handle them in onStartCommand ()
like
if(intent.getAction().equals("com.package.UN_REGISTER")
//call your unregister method
Add action in Manifest in your service Tag
<IntentFilter>
<action name = "com.package.UN_REGISTER">
</IntentFilter>
You should use Bound Services for this. Check link for implementation and usage
If you want to correctly register and unregister a BroadcastReceiver. The BroadcastReceiver passed in registerReceiver() and unregisterReceiver() must be the same instance, so is the Context instance be invoked. Because the implement uses Context and BroadcastReceiver instances to uniquely map to a "Register operation".
I'm creating a custom launcher that is used like a kiosk mode for the phone. This means most things are hidden away but allows the user to access some apps. I've noticed that when I launch apps from the Recent Apps list, when I press the back button, the stock launcher comes up instead of my custom launcher. I made sure my custom launcher is the default launcher since that's the launcher that comes up when I press the home button. Has anyone run into this issue? How do I solve it?
In my attempt to make a Custom Launcher myself, to make that result you needed to disable the default launcher, that i was able to do using KeyguardManager.
package com.themejunky.locker.services;
public class KeyguardService extends Service {
BroadcastReceiver mReceiver, mBatteryReceiver;
// Intent myIntent;
public class LocalBinder extends Binder {
public KeyguardService getService() {
return KeyguardService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
#Override
public void onCreate() {
KeyguardManager.KeyguardLock k1;
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
k1 = km.newKeyguardLock("IN");
k1.disableKeyguard();
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.setPriority(999);
mReceiver = new LockScreenReceiver();
registerReceiver(mReceiver, filter);
mBatteryReceiver = new BatteryReceiver();
IntentFilter filter2 = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
filter2.addAction(Intent.ACTION_BATTERY_OKAY);
filter2.addAction(Intent.ACTION_BATTERY_LOW);
registerReceiver(mBatteryReceiver, filter2);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
unregisterReceiver(mBatteryReceiver);
super.onDestroy();
}
}
The only solution i found when i had this same problem was restarting the device. When you launch apps from the recent apps after that and press the back button you will see the correct home screen.