How to detect the running activity of another app in Android? - android

Is it possible to detect when another app is running in foreground?
Is it possible to detect the specific activity of the app that is currently in the foreground?
For example if I have a package id com.netflix.mediaclient I need to detect when com.netflix.mediaclient.MediaPlayer is active.

Hiii
public class DetectCalendarLaunchRunnable implements Runnable {
#Override
public void run() {
String[] activePackages;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
activePackages = getActivePackages();
} else {
activePackages = getActivePackagesCompat();
}
if (activePackages != null) {
for (String activePackage : activePackages) {
if (activePackage.equals("com.google.android.calendar")) {
//Calendar app is launched, do something
}
}
}
mHandler.postDelayed(this, 1000);
}
String[] getActivePackagesCompat() {
final List<ActivityManager.RunningTaskInfo> taskInfo = mActivityManager.getRunningTasks(1);
final ComponentName componentName = taskInfo.get(0).topActivity;
final String[] activePackages = new String[1];
activePackages[0] = componentName.getPackageName();
return activePackages;
}
String[] getActivePackages() {
final Set<String> activePackages = new HashSet<String>();
final List<ActivityManager.RunningAppProcessInfo> processInfos = mActivityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
activePackages.addAll(Arrays.asList(processInfo.pkgList));
}
}
return activePackages.toArray(new String[activePackages.size()]);
}
}
This can give you running activity name

Related

TileService not working, tile becomes unresponsive

I've made a tileService which triggers a foreground service when clicked. I have taken the battery optimisation permission from settings and set it on don't optimise. However after 3 days the tile becomes unresponsive.
public class QSIntentService
extends TileService {
String TAG = getClass().getSimpleName();
Context context;
boolean isTileActive;
#Override
public void onStartListening() {
super.onStartListening();
Log.e(TAG, "-----onStartListening Tile--");
if (isServiceRunning(getApplicationContext())) {
isTileActive = true;
updateTile();
} else {
isTileActive = false;
updateTile();
}
}
#Override
public void onClick() {
context = getApplicationContext();
Log.e(TAG, "-----onClick --- ");
Tile tile = getQsTile();
isTileActive = (tile.getState() == Tile.STATE_ACTIVE);
Intent serviceIntent = new Intent(context,
ForegroundService.class);
if (isServiceRunning(context)) {
isTileActive = false;
Utils.setBooleanFromPref(context,
context.getString(R.string.widgetStop), true);
if (ShareIBeaconInfo.INSTANCE.getForegroundService() != null) {
ForegroundService foregroundService =
ShareIBeaconInfo.INSTANCE.getForegroundService();
if (foregroundService.scanDevice != null) {
foregroundService.stopForegroundService();
}
}
context.stopService(serviceIntent);
} else {
isTileActive = true;
Utils.setBooleanFromPref(context,
context.getString(R.string.widgetStop), false);
Log.e(TAG, "service is not running");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent service = new Intent(context,
ForegroundService.class);
ContextCompat.startForegroundService(context, service);
} else {
Intent service = new Intent(context, ForegroundService.class);
context.startService(service);
}
}
updateTile();
}
private void updateTile() {
Tile tile = super.getQsTile();
int activeState = isTileActive ?
Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
tile.setState(activeState);
tile.updateTile();
}
private boolean isServiceRunning(Context context) {
try {
final ActivityManager manager;
manager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager
.getRunningServices(Integer.MAX_VALUE)) {
if ("com.foregroundscan.service.ForegroundService"
.equalsIgnoreCase(service.service.getClassName())) {
return true;
}
}
} catch (NullPointerException ex) {
} catch (Exception e) {
}
return false;
}
}
My test device is OnePlus 6T running over android 9. Also is there a way to push a dialogue if the tile is unresponsive? So that I can restart the service?
I received a log when I click on a tile when it is unresponsive
2-08 16:34:56.710 1831-2154/? E/MdmLogger: Cannot get tag from tileTag
: Tile.CustomTile

FirebaseMessagingService doesn't work correct

I have service implemented of FirebaseMessagingService. Today I noticed unusial behavior when phone blocked. I contunie to receive message and android show me via notification but code in onMessageReceived doesn't work.
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
final Context context = this;
if(remoteMessage == null){
return;
}
if(remoteMessage.getNotification() != null){
try {
final Message msg = createMessage(remoteMessage.getNotification());
Handler handler= new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
if(!isAppIsInBackgrund(context)){
Intent intent = new Intent("APP_MESSAGE_BROADCAST");
intent.putExtra("SENDER", msg.getCorrespondent().getId().toString());
intent.putExtra("MESSAGE_ID", msg.getId());
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
else {
showNotification(msg.getCorrespondent().getName(), msg.getBody());
}
}
});
} catch (Exception e) {
showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
}
}
}
// isAppIsInBackgrund - method where's i check openning app.
public boolean isAppIsInBackgrund(Context context){
boolean isInBackground = true;
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH){
List<ActivityManager.RunningAppProcessInfo> runningProcesses = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo:runningProcesses){
if(processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
for (String activeProcess:processInfo.pkgList){
if(activeProcess.equals(context.getPackageName())){
isInBackground = false;
}
}
}
}
}
else {
List<ActivityManager.RunningTaskInfo> taskInfo = activityManager.getRunningTasks(1);
ComponentName componentName = taskInfo.get(0).topActivity;
if(componentName.getPackageName().equals(context.getPackageName())){
isInBackground = false;
}
}
return isInBackground; }

how to continuously Run Service in Bankground above Lollipop?

i have created one TimerTask and one Service.i want to check continuously current foreground App Name. But When My App get closed after 1 or 2 minute service is Not Active.How can i run my Service continuously.
In emulator it's working fine but in Real Device service stop after sometime
BackgroundService.java
public class BackgroundService extends Service {
private Timer mTimer;
public BackgroundService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
private void startTimer() {
if (mTimer == null) {
mTimer = new Timer();
AppLockTimerTask lockTask = new AppLockTimerTask(this);
mTimer.schedule(lockTask, 0L, 1000L);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTimer();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
mTimer.cancel();
mTimer.purge();
mTimer = null;
super.onDestroy();
Intent bootCompleteReceiver = new Intent("com.android.background");
sendBroadcast(bootCompleteReceiver);
}
#Override
public void onTaskRemoved(Intent rootIntent) {
mTimer.cancel();
mTimer.purge();
mTimer = null;
super.onDestroy();
Intent bootCompleteReceiver = new Intent("com.android.background");
sendBroadcast(bootCompleteReceiver);
}}
AppLockTimerTask.java
public class AppLockTimerTask extends TimerTask {
private static final String TAG = "AppLockTimerTask";
private MySharedPreferences mySharedPreferences;
private DBHelper dbHelper;
private Context mContext;
public AppLockTimerTask(Context context) {
mContext = context;
dbHelper = new DBHelper(mContext);
mySharedPreferences = MySharedPreferences.getInstance(mContext);
}
#Override
public void run() {
printForegroundTask();
}
private void printForegroundTask() {
String currentApp = "NULL";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
} else {
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
Log.e(TAG, "Current App in foreground is: " + currentApp);
getNewCurrentApp(currentApp);
}
private void getNewCurrentApp(String currentApp) {
if (!currentApp.equals("com.dharmendra.applock_timerbase")) {
String previousApp = mySharedPreferences.getData(Constant.previousOpenAppName);
if (previousApp.equals("")) {
mySharedPreferences.saveData(Constant.previousOpenAppName, currentApp);
} else {
if (previousApp.equals(currentApp)) {
Log.d(TAG, "App Not Change ==>" + currentApp);
} else {
Log.d(TAG, "App Change ==>" + currentApp);
HashMap<String, String> map = dbHelper.selectFromLI(currentApp);
if (map.size() > 0) {
if (map.get("type").equals("p")) {
Intent i = new Intent();
i.setClassName("com.dharmendra.applock_timerbase", "com.dharmendra.applock_timerbase.OpenPatternLock");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("previousApp", previousApp);
i.putExtra("currentApp", currentApp);
i.putExtra("type", "p");
mContext.startActivity(i);
} else {
Log.d(TAG, "Timmer Lock");
}
} else {
mySharedPreferences.saveData(Constant.previousOpenAppName, currentApp);
}
}
}
}
}}
You can run a long background service above Android 5.0 to Android 7 by using:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
On Android 8 onwards you must use Firebse JobDispatcher, GCMNetworkmanager etc.

On Android 5.0 lollipop maybe due to depricated getRunningTask() method

Application is working with in Kitkat version. After lollipop version application is not working properly. I am thinking problem with getRunningTasks() . Could you please give me guidance ,How to overcome this problem.
public class StartupServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Log.d("Detector", "Auto Start" + AppLockerPreference.getInstance(context).isAutoStart());
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
if (AppLockerPreference.getInstance(context).isAutoStart()){
if (AppLockerPreference.getInstance(context).isServiceEnabled()){
context.startService(new Intent(context, DetectorService.class));
}else{
AppLockerPreference.getInstance(context).saveServiceEnabled(false);
}
}
return;
}else if (AppLockerPreference.getInstance(context).isServiceEnabled()){
Toast.makeText(context, "App------>6", Toast.LENGTH_SHORT).show();
context.startService(new Intent(context, DetectorService.class));
}
}
}
DetectorService
public class DetectorService extends Service {
//public static final String ACTION_DETECTOR_SERVICE = "com.gueei.detector.service";
#Override
public IBinder onBind(Intent intent) {
return null;
}
private static final Class<?>[] mStartForegroundSignature = new Class[] {
int.class, Notification.class};
private static final Class<?>[] mStopForegroundSignature = new Class[] {
boolean.class};
private NotificationManager mNM;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat(int id, Notification notification) {
// If we have the new startForeground API, then use it.
if (mStartForeground != null) {
mStartForegroundArgs[0] = Integer.valueOf(id);
mStartForegroundArgs[1] = notification;
try {
mStartForeground.invoke(this, mStartForegroundArgs);
} catch (InvocationTargetException e) {
// Should not happen.
//debug: log.w("Detector", "Unable to invoke startForeground", e);
} catch (IllegalAccessException e) {
// Should not happen.
//debug: log.w("Detector", "Unable to invoke startForeground", e);
}
return;
}
// Fall back on the old API.
stopForeground(true);
mNM.notify(id, notification);
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundCompat(int id) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
try {
mStopForeground.invoke(this, mStopForegroundArgs);
} catch (InvocationTargetException e) {
// Should not happen.
//debug: log.w("Detector", "Unable to invoke stopForeground", e);
} catch (IllegalAccessException e) {
// Should not happen.
//debug: log.w("Detector", "Unable to invoke stopForeground", e);
}
return;
}
// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
stopForeground(false);
}
#Override
public void onCreate() {
//debug: log.i("Detector","Service.Oncreate");
initConstant();
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
}
#Override
public void onDestroy() {
//debug: log.i("Detector","Service.Ondestroy");
mThread.interrupt();
// Make sure our notification is gone.
stopForegroundCompat(R.string.service_running);
}
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
#Override
public void onStart(Intent intent, int startId) {
//debug: log.i("Detector","Service.Onstart");
handleCommand(intent);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//debug: log.i("Detector","Service.OnStartCommand");
handleCommand(intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return Service.START_STICKY;
}
private void handleCommand(Intent intent){
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.service_running);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.statusbar_icon, text,
System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, AppLockerActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, text,
text, contentIntent);
startForegroundCompat(R.string.service_running, notification);
startMonitorThread((ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE));
}
private void startMonitorThread(final ActivityManager am){
if (mThread!=null)
mThread.interrupt();
mThread = new MonitorlogThread(new ActivityStartingHandler(this));
mThread.start();
}
private static Thread mThread;
private static boolean constantInited = false;
private static Pattern ActivityNamePattern;
private static String logCatCommand;
private static String ClearlogCatCommand;
private void initConstant() {
//debug: log.i("Detector","Service.OninitConstant");
if (constantInited) return;
String pattern = getResources().getString(R.string.activity_name_pattern);
//debug: log.d("Detector", "pattern: " + pattern);
ActivityNamePattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
logCatCommand = getResources().getString(R.string.logcat_command);
ClearlogCatCommand = getResources().getString(R.string.logcat_clear_command);
}
MonitorlogThread
private class MonitorlogThread extends Thread{
ActivityStartingListener mListener;
public MonitorlogThread(ActivityStartingListener listener){
//debug: log.i("Detector","Monitor//debug: logThread");
mListener = listener;
}
BufferedReader br;
private Context context;
#Override
public void run() {
//debug: log.i("Detector","RUN!");
while(!this.isInterrupted() ){
try {
Thread.sleep(100);
////debug: log.i("Detector","try!");
//This is the code I use in my service to identify the current foreground application, its really easy:
ActivityManager am = (ActivityManager) getBaseContext().getSystemService(ACTIVITY_SERVICE);
// The first in the list of RunningTasks is always the foreground task.
//Toast.makeText(context, "App------>7", Toast.LENGTH_SHORT).show();
Log.d("Android", "App------>7----"+am);
//RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
Log.d("Android", "App------>8----"+foregroundTaskInfo);
//Toast.makeText(context, "App------>7"+foregroundTaskInfo, Toast.LENGTH_SHORT).show();
//Thats it, then you can easily access details of the foreground app/activity:
String foregroundTaskPackageName = foregroundTaskInfo.topActivity.getPackageName();
PackageManager pm = getBaseContext().getPackageManager();
PackageInfo foregroundAppPackageInfo = null;
String foregroundTaskAppName = null;
String foregroundTaskActivityName = foregroundTaskInfo.topActivity.getShortClassName().toString();
try {
foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0);
foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString();
//debug: log.i("Detector",foregroundTaskAppName);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (mListener!=null){
//mListener.onActivityStarting(foregroundAppPackageInfo.packageName,foregroundTaskAppName);
mListener.onActivityStarting(foregroundAppPackageInfo.packageName,foregroundTaskActivityName);
}
} catch (InterruptedException e) {
// good practice
Thread.currentThread().interrupt();
return;
}
}
}
}
Use this code for above 5.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
UsageStatsManager usageStatsManager = (UsageStatsManager) ctx.getSystemService("usagestats");
long milliSecs = 60 * 1000;
Date date = new Date();
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, date.getTime() - milliSecs, date.getTime());
if (queryUsageStats.size() > 0) {
Log.i(TAG, "UsageStats size: " + queryUsageStats.size());
}
long recentTime = 0;
String recentPkg = "";
for (int i = 0; i < queryUsageStats.size(); i++) {
UsageStats stats = queryUsageStats.get(i);
if (i == 0 && !getPackageName().equals(stats.getPackageName())) {
Log.i(TAG, "PackageName: " + stats.getPackageName() + " " + stats.getLastTimeStamp());
}
if (stats.getLastTimeStamp() > recentTime) {
String recentTime = stats.getLastTimeStamp();
String recentPkg = stats.getPackageName();
}
};
} catch (Exception e) {
e.printStackTrace();
}
}
Can you try this.
ActivityManager am = (ActivityManager) getBaseContext().getSystemService(ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
ActivityManager.RunningAppProcessInfo runningAppProcessInfo = (ActivityManager.RunningAppProcessInfo) am.getRunningAppProcesses();
String foregroundTaskPackageName = runningAppProcessInfo.pkgList.getClass().getPackage().getName();
PackageManager pm = getBaseContext().getPackageManager();
PackageInfo foregroundAppPackageInfo = null;
String foregroundTaskAppName = null;
String foregroundTaskActivityName = runningAppProcessInfo.pkgList.getClass().getName();
try {
foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0);
foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString();
//debug: log.i("Detector",foregroundTaskAppName);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
} else {
ActivityManager.RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
String foregroundTaskPackageName = foregroundTaskInfo.topActivity.getPackageName();
PackageManager pm = getBaseContext().getPackageManager();
PackageInfo foregroundAppPackageInfo = null;
String foregroundTaskAppName = null;
String foregroundTaskActivityName = foregroundTaskInfo.topActivity.getShortClassName().toString();
try {
foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0);
foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString();
//debug: log.i("Detector",foregroundTaskAppName);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Use RunningAppProcessInfo instead of getRunningTasks for SDK versions greater than KitKat.
ActivityManager am = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
...
} else {
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
...
}

show notification from google chat activity only when activity is in background

This is a Google Chat application. When I get a message from Google Chat I want to show it in the status bar as a notification when the activity is in background.
I tried setting boolean values in the onPause() method but it did not work.
public void addMessage(String chatid, String msg) {
// I want to the execute this line only when the activity is in background
notify.getCurrentActivity(getApplicationContext(), msg, fromName, chatid);
}
public void getCurrentActivity(Context context, String msg){
showNotification(context, msg, fromName, fromChatID);
}
try to do below
try{
boolean foregroud = new ForegroundCheckTask().execute(context).get();
if(foregroud)
{
//app is foreground
}
else
{
//app is not foreground }
}catch(Exception e)
{
e.toString();
}
add below async
//Foreground check
class ForegroundCheckTask extends AsyncTask<Context, Void, Boolean> {
#Override
protected Boolean doInBackground(Context... params) {
final Context context = params[0].getApplicationContext();
return isAppOnForeground(context);
}
private boolean isAppOnForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = context.getPackageName();
for (RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
}
I find out solution myself
private int key; // Declare as global
protected void onPause
{
key=1;
super.onpause();
}
protected void onResume{
key=0;
super.onResume();
}
public void addMessage(String chatid, String msg) {
if(key==1)
{
notify.getCurrentActivity(getApplicationContext(), msg, fromName, chatid);
}
}

Categories

Resources