I am having an activity and on Launching the activity through Intent from one of my service, onCreate(), onPause() and onResume() is called.
I am not very sure where i am doing wrong, i have removed all the code, just the basic function codes are available, and also i have removed all the codes which were opening that particular activity, still the behaviour is same.
I am including the simplest code i am using
ActivityClass.java
public class ActivityClass extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
System.out.println("TEST : onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lockscreen);
ButterKnife.bind(this);
}
#Override
protected void onPause() {
System.out.println("TEST : onPause");
super.onPause();
}
#Override
protected void onDestroy() {
System.out.println("TEST : onDestroy");
super.onDestroy();
}
}
Service class
public class OverlayService extends Service {
Context context;
public static final String TAG = OverlayService.class.getSimpleName();
public OverlayService(Context applicationContext) {
super();
context = applicationContext;
}
public OverlayService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "[onCreateService]");
super.onStartCommand(intent, flags, startId);
KeyguardManager myKM = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
if(myKM.inKeyguardRestrictedInputMode()) {
//it is locked
showOverlayActivity();
} else {
//it is not locked
}
registerOverlayReceiver();
context = this;
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterOverlayReceiver();
Log.i("EXIT", "ondestroy!");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Intent broadcastIntent = new Intent("ac.in.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void unregisterOverlayReceiver() {
if (overlayReceiver != null) {
unregisterReceiver(overlayReceiver);
}
}
private static final String ACTION_DEBUG = "kunal.lockoverlay.action.DEBUG";
private void registerOverlayReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(ACTION_DEBUG);
registerReceiver(overlayReceiver, filter);
}
private BroadcastReceiver overlayReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "[onReceive]" + action);
if (action.equals(Intent.ACTION_SCREEN_ON)) {
// ACTON_SCREEN_ON
showOverlayActivity();
} else if (action.equals(ACTION_DEBUG)) {
showOverlayActivity();
}
}
};
private void showOverlayActivity() {
Intent intent = new Intent();
intent.setClass(this, ActivityClass.class);
intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
Can someone point some of the possible reasons for this behaviour or could identify where i am doing wrong?
Well everything will be called regardless, you have defined it in your ClassName.java file.
You override the method and define it in your class to perform certain action/function when that is called.
For eg.,
You could use onResume to clear an arraylist and add updated elements to arraylist (OR) dismiss all notifications from your app on moving to that activity, say
#Override
public void onResume() {
super.onResume();
calendarList.clear();
//dismiss all notifications here
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager!=null)
notificationManager.cancelAll();
}
OR eg., onDestroy to destroy the bluetooth service,
#Override
public void onDestroy() {
super.onDestroy();
if (mBluetoothService != null) {
mBluetoothService.stop();
}
}
Hope that clarifies. Happy coding!
About service class, you should call registerReceiver() or initialize variables in onCreate instead of onStartCommand because onCreate is only called once at the first time of starting service and onStartCommand will be called every time you want to trigger an action to the service by calling startService(Intent).
Related
I am using a Service for performing some task, which should run only if the app is in background, moreover the service runs for sometime and after sometime, it gets destroyed. Earlier this was working completely fine, but don't know where i am doing wrong.
Here is the code of my Service:
public class MyService extends Service {
Context context;
public static final String TAG = MyService.class.getSimpleName();
public MyService(Context applicationContext) {
super();
context = applicationContext;
Log.i("myservice", "here service created!");
}
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "[onCreateService]");
super.onStartCommand(intent, flags, startId);
// Code
registerOverlayReceiver();
context = this;
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterOverlayReceiver();
Log.i("EXIT", "ondestroy!");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void unregisterOverlayReceiver() {
if (myReceiver != null) {
unregisterReceiver(myReceiver);
}
}
private static final String ACTION_DEBUG = "abc.action.DEBUG";
private void registerOverlayReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(ACTION_DEBUG);
registerReceiver(myReceiver, filter);
}
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "[onReceive]" + action);
if (action.equals(Intent.ACTION_SCREEN_ON)) {
showMyActivity();
} else if (action.equals(ACTION_DEBUG)) {
showMyActivity();
}
}
};
private void showMyActivity() {
Intent intent = new Intent();
intent.setClass(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
I have debugged but couldn't find out the problem for the same.
Anybody who came across anything like this can help me out.
I use activity recognition api and activity transitions. When I first run the app, the first transition is always the. In this app it's WALKING-ENTER. When I tried with only IN_VEHICLE-ENTER and IN_VEHICLE-EXIT in transitions, it was IN_VEHICLE-ENTER. I thought about ignoring the first transition but a device I've tested on didn't have such a problem. The devices that had these problem were Android 8.1, and the device didn't have the problem was 6.0.
MainActivity extends AppCompatActivity
private static Intent serviceIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
if(!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
Button button = findViewById(R.id.button);
button.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
serviceIntent = new Intent(MainActivity.this, ServiceS.class);
MainActivity.this.startService(serviceIntent);
}
});
}
public static boolean hasPermissions(Context context, String... permissions) {
if (permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
ServiceS extends Service
public ServiceS() {
super();
}
public static void locationArrived(Context context, Location location) {
Log.d("hmm: ", location.toString());
}
#SuppressLint("MissingPermission")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCreate() {
initActivityTransition();
super.onCreate();
}
#Override
public void onDestroy() {
Log.d("hmm: ", "Updates stopped!");
Task task = ActivityRecognition.getClient(this)
.removeActivityTransitionUpdates(activityPendingIntent);
super.onDestroy();
}
// ACTIVITY TRANSITION BLOCK START
private static List<ActivityTransition> transitions = new ArrayList<>();
private static PendingIntent activityPendingIntent;
private static ActivityTransitionRequest transitionRequest;
void initActivityTransition(){
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.IN_VEHICLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.IN_VEHICLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
transitions.add(
new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
Intent activityIntentService = new Intent(this, TransitionReceiver.class);
activityPendingIntent = PendingIntent.getBroadcast(this, 1, activityIntentService, PendingIntent.FLAG_UPDATE_CURRENT);
Log.d("hmm: ","DriveBuddyService - initActivityTransition");
}
static void transitionArrived(final ActivityTransitionEvent event, final Context context){
Log.d("hmm: ", event.toString());
Toast.makeText(context, event.getActivityType() + "-" + event.getTransitionType(), Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
if(transitionRequest==null) {
transitionRequest = new ActivityTransitionRequest(transitions);
}
Task task = ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(transitionRequest, activityPendingIntent);
super.onStart(intent, startId);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
TransitionReceiver extends BroadcastReceiver.
public void onReceive(final Context context, Intent intent) {
Log.d("hmm: ","DriveBuddyTransitionReceiver - Enter");
if (ActivityTransitionResult.hasResult(intent)) {
ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
for (ActivityTransitionEvent event : result.getTransitionEvents()) {
ServiceS.transitionArrived(event, context);
}
}
}
I observed the same thing too. It seems that the last activity is kept in cache or something like that. I saw this happening on Android 7.1 and Android 8.1.
To counter this I check the elapsed time of when the transition happened. I ignore the callback if the transition happened over 30 seconds ago.
This is what my code looks like:
#Override
public void onReceive(Context context, Intent i) {
if (ActivityTransitionResult.hasResult(i)) {
ActivityTransitionResult result = ActivityTransitionResult.extractResult(i);
for (ActivityTransitionEvent event : result.getTransitionEvents()) {
//continue only if the activity happened in the last 30 seconds
//for some reason callbacks are received for old activities when the receiver is registered
if(((SystemClock.elapsedRealtime()-(event.getElapsedRealTimeNanos()/1000000))/1000) <= 30) {
//activity transition is legit. Do stuff here..
}
}
}
}
I've typically seen callbacks arrive 0-10 seconds of them occurring.
I am trying to run intent service in background even if the app is closed and have written this code. But the service doesn't runs in the background.Here is my code.
MainActivity.java
package com.example.h.intentservice;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startService(View view){
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);
}
public void stopService(View view){
Intent intent=new Intent(this,MyIntentService.class);
stopService(intent);
}
}
MyIntentService.java
public class MyIntentService extends IntentService {
public MyIntentService() {
super("My_Worker_Thread");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"Service started",Toast.LENGTH_LONG).show();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"Stopped",Toast.LENGTH_LONG).show();
}
#Override
protected void onHandleIntent(Intent intent) {
synchronized (this){
int count=0;
while(count<=10)
{
try{
wait(1500);
count++;
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
First of all an intent service cannot run in the background after closing the application. An intentService is run only once and it automatically closes the thread once the task assigned to it is done. You will have to use a service for background requests.
Secondly you have not called the startService() method from the onCreate and therefore the serviceIntent has not been initiated.
In both the startService() method and the stopService() method you are passing a view which i can see is unused inside the method body. So therefore i can advice you to adjust your code this way
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService();
//here you have started the service intent
//if you want to stop the same just call stopService()
}
public void startService(){
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);
}
public void stopService(){
Intent intent=new Intent(this,MyIntentService.class);
stopService(intent);
}
Am also posting sample code for a service that can run in the background.
Below is sample code for a service
public class UploadService extends Service {
public int counter = 0;
public UploadService(Context applicationContext) {
super();
Log.i("SERVICE", "hService started");
}
public UploadService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
//instantiate your variables here
//i call my startUpload method here to doing the task assigned to it
startUpload();
return START_STICKY;
}
public void startUpload() {
//call the method with your logic here
//mine is a sample to print a log after every x seconds
initializeTimerTask();
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
// timerTask = new TimerTask() {
//we can print it on the logs as below
Log.i("in timer", "in timer ++++ " + (counter++));
//or use the print statement as below
System.out.println("Timer print " + counter++);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
stopSelf();
}
}
I'm trying to implement service in android to make an app locker.
I'm trying to check the which activity is running on the foreground and if it's locked, forwarding it to my Locker activity.
I've added the service in manifest too, but it isn't working at all.
Here's the code `
private static Timer timer = new Timer();
public Boolean userAuth = false;
private Context mContext;
public String pActivity = "";
public IBinder onBind(Intent arg0) {
return null;
}
public void onCreate() {
super.onCreate();
mContext = this;
startService();
}
private void startService() {
timer.scheduleAtFixedRate(new mainTask(), 0, 500);
}
private class mainTask extends TimerTask {
public void run() {
toastHandler.sendEmptyMessage(0);
}
}
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Stopped ...", Toast.LENGTH_SHORT).show();
}
private final Handler toastHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String activityOnTop;
ActivityManager manager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
//Getting the foreground activity name
activityOnTop=tasks.get(0).processName;
//Checking it against the app I need to lock
if (activityOnTop.equalsIgnoreCase("com.droiddigger.techmanik")) {
Intent lockIntent = new Intent(mContext, Lockscreen.class);
lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(lockIntent);
} else if(activityOnTop.equalsIgnoreCase("com.droiddigger.applocker")){
}else{
}
}
};
You must start that service. It can be done in an Activity or a BroadcastReceiver.
startService(new Intent(this, UpdaterServiceManager.class));
For example:
public class MyActivity extends Activity {
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, YourService.class));
finish();
}
}
EDIT:
You are always retrieving the item 0 of the list called tasks. Looking at the SDK documentation, it is said that list order is not especified: https://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()
Returns a list of RunningAppProcessInfo records, or null if there are
no running processes (it will not return an empty list). This list
ordering is not specified.
You must get the current visible activity other way. I suggest an AccessibilityService
I am using a Service to play background Music. The problem is that the music continues playing when i have finished the activity.
Here is code From Main Activity which starts the service
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
startService(svc);
BackgroundSoundService.java
public class BackgroundSoundService extends Service {
private static final String TAG = null;
public static MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("atMedia", "Backround Music playing");
player = MediaPlayer.create(this, R.raw.background);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
Try to stop service from your MainActivity:
Intent svc=new Intent(HomeActivity.this, BackgroundSoundService.class);
stopService(svc);
You have to call selfStop() method inside your service.
or use stopService() API