I am trying to make a program that shows all the active applications.
I searched everywhere but could only find code that shows the package name only.
It would be of great help if you masters can tell me how to display all the active application name
Did you try using ActivityManager.getRunningAppProcesses()?
Here is the sample code for retrieving names:ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
List l = am.getRunningAppProcesses();
Iterator i = l.iterator();
PackageManager pm = this.getPackageManager();
while(i.hasNext()) {
ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next());
try {
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
Log.w("LABEL", c.toString());
}catch(Exception e) {
//Name Not FOund Exception
}
}
If you are getting the package name, you should be able to get additional information about the application using the PackageManager:
http://developer.android.com/reference/android/content/pm/PackageManager.html
There are direct methods for getting the application icon, ApplicationInfo and ActivityInfo objects. Off the top of my head I don't know which one would direct you to the readable name, but if its not directly accessible through one of the methods here, it should be accessible from the application resources (also accessible from this class).
If you are writing a service and want to update the current "foreground app" at regular intervals like I did, DO NOT be tempted to get the ActivityManager instance in the onCreate() of your service and re-use it when updating the current app name:
public class MyService extends Service implements {
ActivityManager mActivityManager;
#Override public void onCreate() {
mActivityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE ); }
String getForegroundAppName() {
String appname;
List <RunningAppProcessInfo> l;
l = mActivityManager.getRunningAppProcesses();
while( i.hasNext() ) {
if ( info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && !isRunningService(info.processName) {
currentApp = info;
break;
}
}
if ( currentApp != null ) {
try {
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(currentApp.processName, PackageManager.GET_META_DATA ));
appname = c.toString();
}
return appname;
}
}
Don't do this. It causes a memory leak resulting in numerous GC_CONCURRENT errors every time it's called. I don't know the real reason behind this but it's much cleaner to get the ApplicationManager instance each time you use it like this:
public class MyService extends Service implements {
#Override public void onCreate() {... }
String getForegroundAppName() {
ActivityManager mActivityManager;
String appname;
mActivityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE );
List <RunningAppProcessInfo> l;
l = mActivityManager.getRunningAppProcesses();
while( i.hasNext() ) {
if ( info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && !isRunningService(info.processName) {
currentApp = info;
break;
}
}
if ( currentApp != null ) {
try {
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(currentApp.processName, PackageManager.GET_META_DATA ));
appname = c.toString();
}
return appname;
}
}
Related
In my app I need to monitorize recently added or updated packages, but since Oreo this is a hard task.
To do it I have a service that runs every X time to detect the new installed/updated apps.
The main core of this service is to call the getChangedPackages function from the PackageManager, but this function always returns null, even if I install or update any app from or not from the Play Store in the interval between two consequtive calls to getChangedPackages.
https://developer.android.com/reference/android/content/pm/PackageManager.html#getChangedPackages(int)
I need to request any permission to call this function? Is the getChangedPackages buggy?
private void _doProcess()
{
try
{
PackageManager package_manager = getPackageManager();
int sequence_number = ApplicationPreferences.getInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, 0);
ChangedPackages changed_packages = package_manager.getChangedPackages(sequence_number);
LogUtilities.show(this, String.format("Retrieve recently apps installs/updates using sequence number %d returns %s", sequence_number, changed_packages == null ? "null" : "a not null object"));
if (changed_packages == null) changed_packages = package_manager.getChangedPackages(0);
LogUtilities.show(this, String.format("Retrieve recently apps installs/updates using sequence number %d returns %s", sequence_number, changed_packages == null ? "null" : "a not null object"));
if (changed_packages != null)
{
List<String> packages_names = changed_packages.getPackageNames();
LogUtilities.show(this, String.format("%d recently installed/updated apps", packages_names == null ? 0 : packages_names.size()));
if (packages_names != null) for (String package_name : packages_names) PackagesUpdatedReceiver.doProcessPackageUpdate(this, new Intent(isNewInstall(package_manager, package_name) ? Intent.ACTION_PACKAGE_ADDED : Intent.ACTION_PACKAGE_REPLACED).setData(Uri.parse(String.format("package:%s", package_name))));
LogUtilities.show(this, String.format("Storing %s is the sequence number for next iteration", changed_packages.getSequenceNumber()));
ApplicationPreferences.putInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, changed_packages.getSequenceNumber());
}
else
{
LogUtilities.show(this, String.format("Storing %s is the sequence number for next iteration", sequence_number + 1));
ApplicationPreferences.putInteger(this, GET_CHANGED_PACKAGES_SEQUENCE_NUMBER_KEY, sequence_number + 1);
}
}
catch (Exception e)
{
LogUtilities.show(this, e);
}
}
My experimental results so far have shown that this PackageManager API method getChangedPackages() is not reliable: quite often the returned ChangedPackages value contains many unchanged packages. So I’ve decided to implement a similar feature in a class called PackageUtils, as shown below. The idea is to poll for all the installed packages, as shown in method getInstalledPackageNames() below, and compare the string list with a previously saved one. This comparison boils down to comparing 2 string lists, as shown in method operate2StringLists() below. To get a set of removed packages, use GET_1_MINUS_2_OR_REMOVED as operation. To get a set of added packages, use GET_2_MINUS_1_OR_ADDED as operation.
public class PackageUtils {
public static final int GET_1_MINUS_2_OR_REMOVED = 0;
public static final int GET_2_MINUS_1_OR_ADDED = 1;
// Get all the installed package names
public static List<String> getInstalledPackageNames(Context context) {
List<String> installedPackageNames = new ArrayList<>();
try {
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> appInfoList = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo appInfo : appInfoList) {
installedPackageNames.add(appInfo.packageName);
}
} catch (Exception e) {
e.printStackTrace();
}
return installedPackageNames;
}
// Compare 2 string lists and return differences.
public static Set<String> operate2StringLists(List<String> pkgList1, List<String> pkgList2, int operation) {
Set<String> result = null;
Set<String> pkgSet1 = new HashSet<String>(pkgList1);
Set<String> pkgSet2 = new HashSet<String>(pkgList2);
switch (operation) {
case GET_1_MINUS_2_OR_REMOVED:
pkgSet1.removeAll(pkgSet2);
result = pkgSet1;
break;
case GET_2_MINUS_1_OR_ADDED:
pkgSet2.removeAll(pkgSet1);
result = pkgSet2;
break;
default:
break;
}
return result;
}
}
The code has been tested on an Android Oreo device. It can reliably detect all added and removed packages between 2 time instances. However, it can’t detect updated packages in-between.
Finally got it. You have to create a variable called sequenceNumber, and update it every time you query changed packages.
private static int sequenceNumber = 0;
...
PackageManager pm = getContext().getPackageManager();
ChangedPackages changedPackages = pm.getChangedPackages(sequenceNumber);
if(changedPackages != null)
sequenceNumber = changedPackages.getSequenceNumber();
I am trying to find out the data usage on Android on a per-application basis. Something like Android Data Usage Apps and Quota / Cap Monitor Widgets: never get charged extra for data or get capped again!.
I looked at Stack Overflow question How to go about detecting data usage in the Android environment.
But it's not been of much help.
ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo mInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo( mInfo );
List<RunningAppProcessInfo> listOfRunningProcess = activityManager.getRunningAppProcesses();
Log.d(TAG, "XXSize: " + listOfRunningProcess.size());
for (RunningAppProcessInfo runningAppProcessInfo : listOfRunningProcess) {
if (runningAppProcessInfo.uid > 1026)
{
Log.d(TAG, "ANS " + runningAppProcessInfo.processName +
" Id :" + runningAppProcessInfo.pid +
" UID: " + runningAppProcessInfo.uid);
}
}
I tried the above code as suggested by Akos Cz. However all the UIDs are numbers, unlike app_79 as you have mentioned above. Is this all right?
The following links should help you figure out how to programmatically determine the data usage per application.
Create a network monitor using Android's TrafficStats class
Android Traffic Statistics Inside
You will need to implement your code to use the TraficStats API and track the number of bytes sent/received per UID (application).
Use this method after create a new class PackageInformationTotal.
public void getPakagesInfoUsingHashMap() {
final PackageManager pm = getPackageManager();
// get a list of installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(0);
// loop through the list of installed packages and see if the selected
// app is in the list
for (ApplicationInfo packageInfo : packages) {
// get the UID for the selected app
UID = packageInfo.uid;
String package_name = packageInfo.packageName;
ApplicationInfo app = null;
try {
app = pm.getApplicationInfo(package_name, 0);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String name = (String) pm.getApplicationLabel(app);
Drawable icon = pm.getApplicationIcon(app);
// internet usage for particular app(sent and received)
double received = (double) TrafficStats.getUidRxBytes(UID)
/ (1024 * 1024);
double send = (double) TrafficStats.getUidTxBytes(UID)
/ (1024 * 1024);
double total = received + send;
if(total>0)
{
PackageInformationTotal pi=new PackageInformationTotal();
pi.name=name;
pi.packageName=package_name;
pi.icon=icon;
pi.totalMB=String.format( "%.2f", total )+" MB";
pi.individual_mb=String.format( "%.2f", total );
totalData+=Double.parseDouble(String.format( "%.2f", total ));
dataHash.add(pi);
Log.e(name,String.format( "%.2f", total )+" MB");
}
}
Editor edit=shared.edit();
edit.putString("Total",String.format( "%.2f", totalData));
edit.commit();
}
After that you can track all process usages in MB.
Prorammatically:
You can declare the intent filter for the ACTION_MANAGE_NETWORK_USAGE action (introduced in Android 4.0) to indicate that your application defines an activity that offers options to control data usage. ACTION_MANAGE_NETWORK_USAGE shows settings for managing the network data usage of a specific application. When your app has a settings activity that allows users to control network usage, you should declare this intent filter for that activity.
Check this out for more information about managing data usage manage usage per application.
The proper definition of ACTION_MANAGE_NETWORK_USAGE is you can see here.
public class Main extends Activity {
private Handler mHandler = new Handler();
private long mStartRX = 0;
private long mStartTX = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mStartRX = TrafficStats.getTotalRxBytes();
mStartTX = TrafficStats.getTotalTxBytes();
if (mStartRX == TrafficStats.UNSUPPORTED || mStartTX == TrafficStats.UNSUPPORTED) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Uh Oh!");
alert.setMessage("Your device does not support traffic stat monitoring.");
alert.show();
} else {
mHandler.postDelayed(mRunnable, 1000);
}
}
private final Runnable mRunnable = new Runnable() {
public void run() {
TextView RX = (TextView)findViewById(R.id.RX);
TextView TX = (TextView)findViewById(R.id.TX);
long rxBytes = TrafficStats.getTotalRxBytes()- mStartRX;
RX.setText(Long.toString(rxBytes));
long txBytes = TrafficStats.getTotalTxBytes()- mStartTX;
TX.setText(Long.toString(txBytes));
mHandler.postDelayed(mRunnable, 1000);
}
};
}
You can also checkout https://github.com/commonsguy/cw-andtuning/tree/master/TrafficMonitor
This snippet also works for those actually running apps in your device
final PackageManager pm = getPackageManager();
ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
//final List<ActivityManager.RunningTaskInfo> recentTasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (int i = 0; i < appProcesses.size(); i++) {
Log.d("Executed app", "Application executed : " + appProcesses.get(i).processName + "\t\t ID: " + appProcesses.get(i).pid + "");
// String packageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
//String packageName = appProcesses.get(i)..getPackageName();
ApplicationInfo app = null;
try {
app = pm.getApplicationInfo(appProcesses.get(i).processName, 0);
if ((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1) {
//it's a system app, not interested
} else if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
//Discard this one
//in this case, it should be a user-installed app
} else {
// tx = TrafficStats.getUidTxBytes(app.uid);
//rx = TrafficStats.getUidRxBytes(app.uid);
long delta_rx = TrafficStats.getUidRxBytes(app.uid) - rx;
long delta_tx = TrafficStats.getUidTxBytes(app.uid) - tx;
}
}
To access an individual app stats you will need the uid of that app, which is an int value assigned by the system to each app at install time.
PackageManager packageManager = context.getPackageManager();
ApplicationInfo info = packageManager.getApplicationInfo("com.example.app", 0);
int packageUid = info.uid;
To get all Rx and Tx bytes of Mobile for package :
NetworkStats.Bucket bucket = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis(),packageUid);
long rxBytes = 0L;
long txBytes = 0L;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
while (networkStats.hasNextBucket()) {
networkStats.getNextBucket(bucket);
rxBytes += bucket.getRxBytes();
txBytes += bucket.getTxBytes();
}
networkStats.close();
For more clarification about this, check:
How do I programmatically show data usage of all applications?
After a long struggle,I am able to find the Solution for getting data over any interface for each installed Application in android
device.
As Android provides TrafficStats Apis but these APIs are providing comple Data stastics for each app uid since device boot and Even
APIs are not supporting to get the data over any interface for a particular application.
Even if we rely over TraffiucStates APIS ,we get a new data statstics for each Application.
So I thought to use the hidden APIs to USe this..
Here I am mentioning the Steps to get the data statstics for each application over any Interface in Android...
Estabalish a "INetworkStatsSession" session
#import android.net.INetworkStatsSession;
INetworkStatsSession mStatsSession = mStatsService.openSession();
Create a Network Templeate according to interafce which you want to measure..
#import static android.net.NetworkTemplate.buildTemplateEthernet;
#import static android.net.NetworkTemplate.buildTemplateMobile3gLower;
#import static android.net.NetworkTemplate.buildTemplateMobile4g;
#import static android.net.NetworkTemplate.buildTemplateMobileAll;
#import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
#import android.net.NetworkTemplate;
private NetworkTemplate mTemplate;
mTemplate = buildTemplateMobileAll(getActiveSubscriberId(this
.getApplicationContext()));
GetActive SubcriberID:
private static String getActiveSubscriberId(Context context) {
final TelephonyManager tele = TelephonyManager.from(context);
final String actualSubscriberId = tele.getSubscriberId();
return SystemProperties.get(TEST_SUBSCRIBER_PROP, actualSubscriberId);
}
Collect the network HIStory of respective application byt passing application UIDs...
private NetworkStatsHistory collectHistoryForUid(NetworkTemplate template,
int uid, int set) throws RemoteException {
final NetworkStatsHistory history = mStatsSession.getHistoryForUid(
template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
return history;
}
Get the total Consumption data:
public void showConsuption(int UID){
NetworkStatsHistory history = collectHistoryForUid(mTemplate, UID,
SET_DEFAULT);
Log.i(DEBUG_TAG, "load:::::SET_DEFAULT:.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
history = collectHistoryForUid(mTemplate, 10093,
SET_FOREGROUND);
Log.i(DEBUG_TAG, "load::::SET_FOREGROUND::.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
history = collectHistoryForUid(mTemplate, 10093,
SET_ALL);
Log.i(DEBUG_TAG, "load::::SET_ALL::.getTotalBytes:"+ Formatter.formatFileSize(context, history.getTotalBytes()));
}
I am using following line of code to get the package name of top running application in Android
ActivityManager am = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();
What I want is the label name of top running activity in the stack, like if facebook is running on the top , I should get "facebook" as label name of the application
public String getTopActivityStackName()
{
ActivityManager mActivityManager = (ActivityManager)
getSystemService(Activity.ACTIVITY_SERVICE);
PackageManager mPackageManager = getPackageManager();
String packageName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
ApplicationInfo mApplicationInfo;
try
{
mApplicationInfo = mPackageManager.getApplicationInfo( packageName, 0);
} catch (NameNotFoundException e) {
mApplicationInfo = null;
}
String appName = (String) (mApplicationInfo != null ?
mPackageManager.getApplicationLabel(mApplicationInfo) : "(unknown)");
return appName;
}
try this i dont know whether it help you or not ,
PackageManager pm = context.getPackageManager();
RunningAppProcessInfo info = am.getRunningAppProcesses().get(0);
try {
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA)); System.out.println("the label of the app is " + c); Log.w("LABEL", c.toString());
}
catch(Exception e) { //Name Not FOund Exception
}
In my manifest I have:
<application
android:name=".MyApp"
android:icon="#drawable/ic_launcher_icon"
android:label="#string/app_name"
android:debuggable="true">
How do I get the label element?
Note: My code is running inside of someone else's, so I don't have access to #string/app_name
There's an easier way than the other answers that doesn't require you to name the resource explicitly or worry about exceptions with package names. It also works if you have used a string directly instead of a resource.
Just do:
public static String getApplicationName(Context context) {
ApplicationInfo applicationInfo = context.getApplicationInfo();
int stringId = applicationInfo.labelRes;
return stringId == 0 ? applicationInfo.nonLocalizedLabel.toString() : context.getString(stringId);
}
Edit
In light of the comment from Snicolas, I've modified the above so that it doesn't try to resolve the id if it is 0. Instead it uses, nonLocalizedLabel as a backoff. No need for wrapping in try/catch.
If not mentioned in the strings.xml/hardcoded in AndroidManifest.xml for whatever reason like android:label="MyApp"
Java
public String getAppLable(Context context) {
ApplicationInfo applicationInfo = null;
try {
applicationInfo = context.packageManager.getApplicationInfo(context.getPackageManager().getApplicationInfo().packageName, 0);
} catch (final NameNotFoundException e) {
Log.d("TAG", "The package with the given name cannot be found on the system.");
}
return (applicationInfo != null ? packageManager.getApplicationLabel(applicationInfo) : "Unknown");
}
Or if you know the String resource ID then you can directly get it via
getString(R.string.appNameID);
UPDATE
Kotlin
fun getAppLable(context: Context): String? {
var applicationInfo: ApplicationInfo? = null
try {
applicationInfo = context.packageManager.getApplicationInfo(context.applicationInfo.packageName, 0)
} catch (e: NameNotFoundException) {
Log.d("TAG", "The package with the given name cannot be found on the system.")
}
return (if (applicationInfo != null) packageManager.getApplicationLabel(applicationInfo) else "Unknown")
}
Java
public static String getApplicationName(Context context) {
return context.getApplicationInfo().loadLabel(context.getPackageManager()).toString();
}
Kotlin (as extension)
fun Context.getAppName(): String = applicationInfo.loadLabel(packageManager).toString()
From any Context use:
getApplicationInfo().loadLabel(getPackageManager()).toString();
In Kotlin its simple:
val appLabel = context.applicationInfo.nonLocalizedLabel.toString()
In Kotlin, use the following codes to get Application Name:
// Get App Name
var appName: String = ""
val applicationInfo = this.getApplicationInfo()
val stringId = applicationInfo.labelRes
if (stringId == 0) {
appName = applicationInfo.nonLocalizedLabel.toString()
}
else {
appName = this.getString(stringId)
}
If you need only the application name, not the package name, then just write this code.
String app_name = packageInfo.applicationInfo.loadLabel(getPackageManager()).toString();
You can use this
JAVA
ApplicationInfo appInfo = getApplicationContext().getApplicationInfo();
String applicationLabel = getApplicationContext().getPackageManager().getApplicationLabel(appInfo).toString();
Get Appliction Name Using RunningAppProcessInfo as:
ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
List l = am.getRunningAppProcesses();
Iterator i = l.iterator();
PackageManager pm = this.getPackageManager();
while(i.hasNext()) {
ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next());
try {
CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
Log.w("LABEL", c.toString());
}catch(Exception e) {
//Name Not FOund Exception
}
}
By default you have a string resource called "app_name" generated by AndroidStudio. Why not simply use that? Or any other string resource created for this purpose. Much easier than calling several internal methods to come up with a value you have to set yourself in the first place.
Okay guys another sleek option is
Application.Context.ApplicationInfo.NonLocalizedLabel
verified for hard coded android label on application element.
<application android:label="Big App"></application>
Reference:
http://developer.android.com/reference/android/content/pm/PackageItemInfo.html#nonLocalizedLabel
The source comment added to NonLocalizedLabel directs us now to:
return context.getPackageManager().getApplicationLabelFormatted(context.getApplicationInfo());
Kotlin
A simple function to get the name of the application in kotlin
fun getApplicationName() : String{
var applicationName = ""
try {
val applicationInfo = application.applicationInfo
val stringId = applicationInfo.labelRes
if (stringId == 0) {
applicationName = applicationInfo.nonLocalizedLabel.toString()
}
else {
applicationName = application.getString(stringId)
}
} catch (e: Exception) {
e.printStackTrace()
}
return applicationName
}
Have you tried using the PackageManager#getActivityInfo() method? There will be a field that should contain the name of the application.
See the answer to a very similar question here.
If "don't have access" means you don't get the expected value... Try This:
String appName = getString(R.string.app_name);
I'm new here and I've searched for questions to help me but I have no clear answers.
I need to make an application to block other applications on the phone.
I've seen several on the market but I want to make one.
is there any way of knowing when a user tries to open an application and bring forward an activity? (to put the password).
I tried with FileObserver, but only works with files and directories (obviously).
Could I make a listener that captures the Intent of the other applications before starting?
I apologize for my english and I appreciate your help!
No you cannot know when another application is launched without some kind of hack.
This is because application launches are not broadcasted.
What you can do is creating a service running on fixed intervals , say 1000 milliseconds, that checks what non system application is on front. Kill that app and from the service pop a password input box. If that password is correct relaunch that application
Here is some code sample
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
List<RunningAppProcessInfo> appProcesses= activityManager.getRunningAppProcesses();
for (RunningAppProcessInfo appProcess : appProcesses) {
try {
if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (!lastFrontAppPkg.equals((String) appProcess.pkgList[0])) {
apkInfo = ApkInfo.getInfoFromPackageName(appProcess.pkgList[0], mContext);
if (apkInfo == null || (apkInfo.getP().applicationInfo.flags && ApplicationInfo.FLAG_SYSTEM) == 1) {
// System app continue;
} else if (((apkInfo.getP().versionName == null)) || (apkInfo.getP().requestedPermissions == null)) {
//Application that comes preloaded with the device
continue;
} else {
lastFrontAppPkg = (String) appProcess.pkgList[0];
}
//kill the app
//Here do the pupop with password to launch the lastFrontAppPkg if the pass is correct
}
}
}
} catch (Exception e) {
//e.printStackTrace();
}
}
}
}, 0, 1000);
And here is the ApkInfo.getInfoFromPackageName()
/**
* Get the ApkInfo class of the packageName requested
*
* #param pkgName
* packageName
* #return ApkInfo class of the apk requested or null if package name
* doesn't exist
* #see ApkInfo
*/
public static ApkInfo getInfoFromPackageName(String pkgName,
Context mContext) {
ApkInfo newInfo = new ApkInfo();
try {
PackageInfo p = mContext.getPackageManager().getPackageInfo(
pkgName, PackageManager.GET_PERMISSIONS);
newInfo.appname = p.applicationInfo.loadLabel(
mContext.getPackageManager()).toString();
newInfo.pname = p.packageName;
newInfo.versionName = p.versionName;
newInfo.versionCode = p.versionCode;
newInfo.icon = p.applicationInfo.loadIcon(mContext
.getPackageManager());
newInfo.setP(p);
} catch (NameNotFoundException e) {
e.printStackTrace();
return null;
}
return newInfo;
}
there is a way to do so . you can know when a application is launched.
you can use packagemanager class to get all the information about any installed and inbuld application . and use the below code to know whwn that application is launched
#Override
public void run() { Log.i("test","detector run");
try {
Process process;
process = Runtime.getRuntime().exec(ClearLogCatCommand);
process = Runtime.getRuntime().exec(LogCatCommand);
br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
// Check if it matches the pattern
while(((line=br.readLine()) != null) && !this.isInterrupted()){
Log.d("Detector", "RUN"+line);
// Ignore launchers
if (line.contains("cat=[" + Intent.CATEGORY_HOME + "]")) continue;
Matcher m = ActivityNamePattern.matcher(line);
if (!m.find()) continue;
if (m.groupCount()<2){
// Log.d("Detector", "Unknown problem while matching logcat output. Might be SDK version?");
continue;
}
if (mListener!=null) mListener.onActivityStarting(m.group(1), m.group(2));
Log.i("Detector", "Found activity launching: " + m.group(1) + " / " + m.group(2));
}
} catch (IOException e) {
e.printStackTrace();
}
}
You can now use an AccessibilityService that allows you to find out which Activity is at the top.
In the AccessibilityService class:
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
ComponentName componentName = new ComponentName(
event.getPackageName().toString(),
event.getClassName().toString()
);
ActivityInfo activityInfo = tryGetActivity(componentName);
boolean isActivity = activityInfo != null;
if (isActivity) {
Log.i("CurrentActivity", componentName.flattenToShortString());
}
}
}
You will have to turn the Accessibility on in your phone's settings, which can be done by going to Settings > Accessibility > Services > Your App. There are also a couple of permissions you'll have to add in your Manifest. A lot of the information can be found in the Android Developers site: http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html
Hope this helps!