Broadcast Receiver to detect application start - android

I want to capture the time whenever a user starts any application using my broadcast receiver.
is it possible that a broadcast receiver can catch such an event??
if yes , is there any permision which can do that?

The best you can do is create a STICKY Service that tracks all of the running application.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run()
{
final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
final List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (int i = 0; i < services.size(); i++) {
if(!stalkList.contains(services.get(i).baseActivity.getPackageName()))
{
// you may broad cast a new application launch here.
stalkList.add(services.get(i).baseActivity.getPackageName());
}
}
List<RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
for(int i = 0; i < procInfos.size(); i++) {
ArrayList<String> runningPkgs = new ArrayList<String>(Arrays.asList(procInfos.get(i).pkgList));
Collection diff = subtractSets(runningPkgs, stalkList);
if(diff != null)
{
stalkList.removeAll(diff);
}
}
}
}, 20000, 6000); // every 6 seconds
return START_STICKY;
}
private RunningAppProcessInfo getForegroundApp() {
RunningAppProcessInfo result = null, info = null;
final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List <RunningAppProcessInfo> l = activityManager.getRunningAppProcesses();
Iterator <RunningAppProcessInfo> i = l.iterator();
while(i.hasNext()) {
info = i.next();
if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& !isRunningService(info.processName)) {
result = info;
break;
}
}
return result;
}
private boolean isRunningService(String processName) {
if(processName == null)
return false;
RunningServiceInfo service;
final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List <RunningServiceInfo> l = activityManager.getRunningServices(9999);
Iterator <RunningServiceInfo> i = l.iterator();
while(i.hasNext()){
service = i.next();
if(service.process.equals(processName))
return true;
}
return false;
}
private boolean isRunningApp(String processName) {
if(processName == null)
return false;
RunningAppProcessInfo app;
final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List <RunningAppProcessInfo> l = activityManager.getRunningAppProcesses();
Iterator <RunningAppProcessInfo> i = l.iterator();
while(i.hasNext()){
app = i.next();
if(app.processName.equals(processName) && app.importance != RunningAppProcessInfo.IMPORTANCE_SERVICE)
return true;
}
return false;
}
private boolean checkifThisIsActive(RunningAppProcessInfo target){
boolean result = false;
ActivityManager.RunningTaskInfo info;
if(target == null)
return false;
final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List <ActivityManager.RunningTaskInfo> l = activityManager.getRunningTasks(9999);
Iterator <ActivityManager.RunningTaskInfo> i = l.iterator();
while(i.hasNext()){
info=i.next();
if(info.baseActivity.getPackageName().equals(target.processName)) {
result = true;
break;
}
}
return result;
}
// what is in b that is not in a ?
public static Collection subtractSets(Collection a, Collection b)
{
Collection result = new ArrayList(b);
result.removeAll(a);
return result;
}

You can't get a broadcast when someone starts any other app. The only thing you can do is start a service that polls and periodically checks if new apps have been started (using Reno's code above for example).
Also if you start this service when the phone starts you have a reasonably good solution.

Related

How to get package name after lollipop version in android

I have tried this below code for getting forground application package name but it is getting my own app application package name only. other application packagte name will be null.it means it is returning null ...how can i get package name.. is there any other way. I know getrunningappprocess is blocked by google.
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
String mpackageName = tasks.get(0).processName;
UsageStatsManager usage = (UsageStatsManager) this.getSystemService(this.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usage.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> runningTask = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
runningTask.put(usageStats.getLastTimeUsed(), usageStats);
}
if (!runningTask.isEmpty() && runningTask != null) {
mpackageName = runningTask.get(runningTask.lastKey()).getPackageName();
}
}
for (int i = 0; pakageName != null && i < pakageName.size(); i++) {
Log.e("AppCheck", "comfor2 : " + mpackageName + " pak2 : " + pakageName.get(i));
if (mpackageName.equals(pakageName.get(i))) {
currentApp = pakageName.get(i);
return true;
}
}
}
Get class name from below method...
public static void classNameRunning(Context context) {
boolean isInBackground = true;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
for (String activeProcess : processInfo.pkgList) {
if (activeProcess.equals(context.getPackageName())) {
// print log for class name
}
}
}
}
} else {
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (componentInfo.getPackageName().equals(context.getPackageName())) {
Log.w("Package name ==> ",componentInfo.getPackageName());
}
}
}
public static HashSet<String> getRunningApps(Context context) {
final HashSet<String> hashSet = new HashSet<String>();
final ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
final PackageManager packageManager = context.getPackageManager();
List<RunningTaskInfo> runningTasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (RunningTaskInfo runningTaskInfo : runningTasks) {
String packageName = runningTaskInfo.baseActivity.getPackageName();
try {
String appName = packageManager.getApplicationInfo(packageName, 0).loadLabel(packageManager).toString();
hashSet.add(appName);
} catch (NameNotFoundException exception) {
// handle Exception
}
}
return hashSet;
}

How to `getTopActivity` name or get currently running application package name in lollipop?

I am creating a app lock application. How to get current running task in lollipop? getRunningTaskinfo method is deprecated in lollipop API, then how to overcome this problem?
try this:
ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT > 20){
String mPackageName = mActivityManager.getRunningAppProcesses().get(0).processName;
}
else{
String mpackageName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
we can get using UsageStats:
public static String getTopAppName(Context context) {
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
String strName = "";
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
strName = getLollipopFGAppPackageName(context);
} else {
strName = mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName();
}
} catch (Exception e) {
e.printStackTrace();
}
return strName;
}
private static String getLollipopFGAppPackageName(Context ctx) {
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("LPU", "queryUsageStats size: " + queryUsageStats.size());
}
long recentTime = 0;
String recentPkg = "";
for (int i = 0; i < queryUsageStats.size(); i++) {
UsageStats stats = queryUsageStats.get(i);
if (i == 0 && !"org.pervacio.pvadiag".equals(stats.getPackageName())) {
Log.i("LPU", "PackageName: " + stats.getPackageName() + " " + stats.getLastTimeStamp());
}
if (stats.getLastTimeStamp() > recentTime) {
recentTime = stats.getLastTimeStamp();
recentPkg = stats.getPackageName();
}
}
return recentPkg;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
// TO ENABLE USAGE_STATS
// Declare USAGE_STATS permisssion in manifest
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
Best solution of get Running app in API 21 or up is below try it.
this work for me
private String retriveNewApp() {
if (VERSION.SDK_INT >= 21) {
String currentApp = null;
UsageStatsManager usm = (UsageStatsManager) this.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<>();
for (UsageStats usageStats : applist) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
Log.e(TAG, "Current App in foreground is: " + currentApp);
return currentApp;
}
else {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
String mm=(manager.getRunningTasks(1).get(0)).topActivity.getPackageName();
Log.e(TAG, "Current App in foreground is: " + mm);
return mm;
}
}
You can use the AccessibilityService to get current Running app.
Accessibility Service provides the onAccessibilityEvent event.
Following is some sample code.
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (event.getPackageName() != null && event.getClassName() != null) {
Log.d("Foreground App", event.getPackageName().toString());
}
}
}
You can find more info about Accessibility Service here
Are you sure? As I can see according to the latest Android docs, LOLLIPOP update doesnt allow you to know any info about other apps than your own!?
http://developer.android.com/reference/android/app/ActivityManager.html
You can see that all those methods are deprecated!
according to this ; the following code worked perfectly for me :
MOVE_TO_FOREGROUND and MOVE_TO_BACKGROUND added in sdk 21 and deprecated in sdk 29
ACTIVITY_RESUMED and ACTIVITY_PAUSED added in sdk 29
public static String getTopPkgName(Context context) {
String pkgName = null;
UsageStatsManager usageStatsManager = (UsageStatsManager) context
.getSystemService(Context.USAGE_STATS_SERVICE);
final long timeTnterval= 1000 * 600;
final long endTime = System.currentTimeMillis();
final long beginTime = endTime - timeTnterval;
final UsageEvents myUsageEvents = usageStatsManager .queryEvents(beginTime , endTime );
while (myUsageEvents .hasNextEvent()) {
UsageEvents.Event myEvent = new UsageEvents.Event();
myUsageEvents .getNextEvent(myEvent );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
switch (myEvent .getEventType()) {
case UsageEvents.Event.ACTIVITY_RESUMED:
pkgName = myEvent .getPackageName();
break;
case UsageEvents.Event.ACTIVITY_PAUSED:
if (myEvent .getPackageName().equals(pkgName )) {
pkgName = null;
}
}
}else {
switch (event.getEventType()) {
case UsageEvents.Event.MOVE_TO_FOREGROUND:
pkgName = myEvent .getPackageName();
break;
case UsageEvents.Event.MOVE_TO_BACKGROUND:
if (myEvent .getPackageName().equals(pkgName )) {
pkgName = null;
}
}
}
}
return pkgName ;
}
Try this.. This worked for me.
ActivityManager activityManager = (ActivityManager) getSystemService (Context.ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP)
{
String packageName = activityManager.getRunningAppProcesses().get(0).processName;
}
else if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
{
String packageName = ProcessManager.getRunningForegroundApps(getApplicationContext()).get(0).getPackageName();
}
else
{
String packageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
#Manish Godhani's answer (https://stackoverflow.com/a/38829083/8179249) works very well, but you have to give the right permissions for this !
See the two first points of that answer : https://stackoverflow.com/a/42560422/8179249
It works for me (before adding permissions I was getting 'null' too), as shown below :
Can be achieved like this.....
ActivityManager am =(ActivityManager)context.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
ActivityManager.RunningTaskInfo task = tasks.get(0); // current task
ComponentName rootActivity = task.baseActivity;
rootActivity.getPackageName();//*currently active applications package name*
For lollipop:
ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT > 20){
String activityName =mActivityManager.getRunningAppProcesses().get(0).processName;
}
else{
String activityName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
}
for complete example check this out...

how to force stop all checked application from list view in android programmatically

In below given code I want to kill (forcestop) all the checked applications but after restarting my application it's showing the name of these killed applications again.
I really don't know if they're really killed or not. Why this is so?
kill.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
//Killing selected Apps
String savedapp;
int code = 0;
int count = lv.getAdapter().getCount();
for (int j = 0; j < count; j++)
{
if (lv.isItemChecked(j))
{
Intent ints = new Intent(Intent.ACTION_MAIN, null);
ints.addCategory(Intent.CATEGORY_LAUNCHER);
savedapp = lv.getItemAtPosition(j).toString();
nm.removeAll(nm);
// this.l = getListView();
// l.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
PackageManager pm = getApplicationContext().getPackageManager();
List<ResolveInfo> intentlist = pm.queryIntentActivities(ints, PackageManager.PERMISSION_GRANTED);
ActivityManager am1 = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> processes = am1.getRunningTasks(Integer.MAX_VALUE);
if (processes != null)
{
for (int i = 0; i < processes.size(); i++) {
String packageName = processes.get(i).topActivity
.getPackageName();
RunningTaskInfo temp = processes.get(i);
try
{
pName = (String) pm.getApplicationLabel(pm
.getApplicationInfo(packageName,
PackageManager.GET_META_DATA));
}
catch (NameNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// int f = 0;
if (savedapp.equals(pName)) {
// finish(pm.);
code = intentlist.get(i).activityInfo
.hashCode();
finishActivity(code);
am1.killBackgroundProcesses(packageName);
am1.restartPackage(packageName);
android.os.Process.killProcess(temp.id);
finishActivity(temp.id);
// Toast.makeText(this, packageName,
// Toast.LENGTH_SHORT).show();
//f = 1;
}
else
{
nm.add(pName.trim());
}
}
}
}
}
}
};//kill button close

how can i get the package name of 2nd top activity which is in other package?

here in my case, a app invokes a service and the service will inturn starts an activity. My problem here is to get the app package which invokes that service.
Can anybody help me to solve this ?
I found this directly from android source and it works fine :)
final ActivityManager am = (ActivityManager)
getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RecentTaskInfo> recentTasks =
am.getRecentTasks(3, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
for (int i = 0, index = 0; i < 3 && (index < 3); ++i) {
final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
Intent intent = new Intent( recentInfo.baseIntent);
if ( recentInfo.origActivity != null) {
intent.setComponent( recentInfo.origActivity);
}
final PackageManager pm = getPackageManager();
final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
final ActivityInfo info = resolveInfo.activityInfo;
final String title = info.loadLabel(pm).toString();
Log.d("hello"," "+title+" "+info.packageName);
final ImageView iv = (ImageView)findViewById(R.id.imageView1);
iv.setImageDrawable(info.loadIcon(pm));
++index;
}
Try this
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(1).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
}
It may useful to you to get second top activity.

check if there are 2 instances running

I am trying to check if my app is running already if the user is trying to enter it again.
it is possible if one app Launched anther one and the user entering with a mobile to the second one, and will be 2 instance.
my launcher app that starts the original one looks like that :
Intent i = new Intent(Intent.ACTION_MAIN);
PackageManager manager = getPackageManager();
i = manager.getLaunchIntentForPackage("com.test.vayo");
i.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i);
On my original code I am trying to check if there is 2 instance but always get true on this code
if (processName == null) {
return false;
}
ActivityManager manager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> processes = manager.getRunningAppProcesses();
for (RunningAppProcessInfo process : processes) {
if (processName.equals(process.processName)) {
return true;
}
}
return false;
the proccessName taken from this code, the pid is from android.os.Process.myPid():
private String getAppName(int pID)
{
String processName = "";
ActivityManager am = (ActivityManager)context.getSystemService(context.ACTIVITY_SERVICE);
List l = am.getRunningAppProcesses();
Iterator i = l.iterator();
PackageManager pm = context.getPackageManager();
while(i.hasNext())
{
ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next());
try
{
if(info.pid == pID)
{
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
//Log.d("Process", "Id: "+ info.pid +" ProcessName: "+ info.processName +" Label: "+c.toString());
//processName = c.toString();
processName = info.processName;
}
}
catch(Exception e)
{
//Log.d("Process", "Error>> :"+ e.toString());
}
}
return processName;
}
hope you can tell whats wrong why I am getting always true on my first block of code.
thanks a lot!!

Categories

Resources