Archive

Archive for the ‘Tricks & Tips’ Category

Error creating project in ADT rev.20

July 6, 2012 2 comments

Now this is what happen after updating ADT to rev.20.

Error create project in ADT rev.20

Error create project in ADT rev.20

 

The problem is that the ADT looks for the Android Support Library in <ANDROID-SDK>\extras\android\support , but in facts, it stays in <ANDROID-SDK>\extras\android\compatibility

So the solution is to copy the folder [\compatibility] and rename it to [\support] then it will be fixed.

 

Cheers,

Pete Houston

 

Advertisements
Categories: Tricks & Tips Tags: ,

Do TaskManager apps really kill other apps immediately?


It’s the question that I was wondering for while “How to kill other running processes?”.

I’ve found some methods to proceed this action.


1. Use Process to kill : android.os.Process.killProcess()

This is what it is said in documentation:

Kill the process with the given PID. Note that, though this API allows us to request to kill any process based on its PID, the kernel will still impose standard restrictions on which PIDs you are actually able to kill. Typically this means only the process running the caller's packages/application and any additional processes created by that app; packages sharing a common UID will also be able to kill each other's processes.

So basically, it means that it cannot kill other processes unless they share the same UID.

> Epic Failed!

 

2. Use Process to send SIGNAL: android.os.Process.sendSignal()

Look at this page on signal and kill

So it means the TaskKiller-like apps should have privileges or appropriate permission on other process in order to kill, otherwise, it must depend on system to decide when to kill.

> Epic Failed!

3. Use ActivityManger to kill: android.app.killBackgroundProcesses()

Have the system immediately kill all background processes associated with the given package. This is the same as the kernel killing those processes to reclaim memory; the system will take care of restarting these processes in the future as needed.

Above is what the docs say about it.

However, does it really kill the give package immediately? I’ve tried but fail. It really depends on system to kill.

> Epic Failed! Or Not?

 

4. Use ActivityManager to kill: android.app.ActivityManager.restartPackage()

– It’s deprecated now, nevermind about this!

 

So if TaskKiller-like apps cannot kill other running processes immediately, then what does it do because users might feel like it really works right away?

– One thing might be that the TaskKiller-like apps send the signal or whatever killing like above, then displaying on screen list of running process not in SUSPENDED state, just hide from users. It could be an answer, there might be others as well but I cannot think of.

There are some references on StackOverflow talking about this matter:

How do Task Manager’s kill apps?

How to kill currently running task in android?

Android: kill processes and close applications

Android process killer

Feel free to share if you got any idea.

 

Cheers,

Pete Houston

 

Categories: Tricks & Tips Tags: , , ,

Get Default Launcher on Device


A simple snippet to get default launcher on device, which is checked “Use by default for this action” on Launcher selection dialog.

	public static ApplicationInfo getDefaultLauncher(Context context) {
		// first query all installed launcher
		ArrayList<ApplicationInfo> listAppInfo = getAllLaunchers(context);

		// the default launcher queried being stored here
		ArrayList<ComponentName> listDefault = new ArrayList<ComponentName>();
		// create list IntentFilter for Launcher apps
		final IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
		filter.addCategory(Intent.CATEGORY_HOME);
		filter.addCategory(Intent.CATEGORY_DEFAULT);
		ArrayList<IntentFilter> listFilters = new ArrayList<IntentFilter>();
		listFilters.add(filter);
		// query default launcher
		context.getPackageManager().getPreferredActivities(listFilters, listDefault, null);

		// check if default launcher
		if(listDefault.size() > 0) {
			for(ComponentName name: listDefault) {
				for(ApplicationInfo info: listAppInfo) {
					if(name.getPackageName().equals(info.packageName)) {
						// found yeah!
						return info;
					}
				}
			}
		}

		// not found any, no launcher set Default
		return null;
	}

Refer to my previous post to get all install Launchers on device.

 

Cheers,

Pete Houston

Categories: Tricks & Tips Tags: ,

The Magic behind App Protector Application

July 4, 2012 1 comment

As you see on Google Play Store, there’re various app protector applications like:

+ Perfect App Protector

+ Smart App Protector

+ App Lock

+ Smart AppLock

+ App Defender

+ Secret App Lock Pro

+ ZDBox

… and many more.

But how do they work actually?

After two days of investigation through these apps on Play Store, I’ve found the machenism.

Basically, the App Protector (so called AP) need to create a Service that runs in background to detect whether a locked application is launched or not.

Also, there are two ways I found to detect when an application is launched.

1) Using the Top Task:

– First refer to this documentation on Google Android Developers about ActivityManager.RunningTaskInfo

– In description, all running tasks on Android phone are put in a stack, so the launching application should be somehow on the top, which displays on mobile screen currently. By this way, you can detect the launching application.

RunningTaskInfo topTask = actMgr.getRunningTasks(1).get(0);

– I have tried many times and not sure when it can fail, so I assume it works as my expectation.

2) Monitor the Logcat:

– If you read Logcat, when an application is launched there should be some lines like this:

I/ActivityManager( 1269): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.andrew.apollo/.activities.MusicLibrary bnds=[240,557][360,707]} from pid 18431

– This is the clue, so the Service needs to monitor the Logcat continuously for this. Of course, parsing the Logcat for the time being.

– Here the Logcat command to filter the above line:

$ logcat ActivityManager:I *:S
$ logcat -c

– Remember to clear after each parsing.

– I guess you can write your own piece of code to parse.

 

(*) Note: if you want to try it, then you will see the difficult problems when to lock, when to unlock, when to detect app state…so please don’t ask me about this, because it’s your own math logic. But it’s fun to test IQ though.

Anyway, make your own App Protector and share your concepts and techniques!

Cheers,

Pete Houston

 

 

Query all installed Launcher Applications

July 3, 2012 1 comment

The tip for making this happen is that all launchers register these two categories in Manifest

+ CATEGORY_HOME

+ CATEGORY_DEFAULT

and this is my snippet to query ’em all.

	public static ArrayList<ApplicationInfo> getAllLaunchers(Context context) {
		// create new intent
		final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
		// all launchers register these two categories
		mainIntent.addCategory(Intent.CATEGORY_HOME);
		mainIntent.addCategory(Intent.CATEGORY_DEFAULT);

		// query normally
		final ArrayList<ResolveInfo> pkgAppsList = (ArrayList<ResolveInfo>)
				context.getPackageManager().queryIntentActivities( mainIntent, 0);

		// you can return 'pkgAppsList'
		// anyway, I need the following information,
		// so I just query what I need
		ArrayList<ApplicationInfo> listAppInfo = new ArrayList<ApplicationInfo>();
		for(ResolveInfo info: pkgAppsList) {
			listAppInfo.add(info.activityInfo.applicationInfo);
		}

		// return
		return listAppInfo;
	}

There you go, gotta do something with it.
Enjoy and have fun!

Cheers,
Pete Houston

Categories: Tricks & Tips Tags: , , , ,

Common array clone mistake in Java

May 29, 2012 1 comment

While working on my application, I’ve found one bug whereas the cause is very common in practice.

Assuming, you have an two dimensional array storing data, and you want to copy or clone it to another storage variable, this is what somebody often does:

boolean data[][] = ... // original data

// common use of clone()
boolean copied[][] = data.clone();

The problem is that, it’s not gonna working as a new fresh copy data but a reference to the original data.
The fix for this is pretty much straight forward.

public static boolean[][] cloneData(boolean[][] from) {
	boolean[][] to = new boolean[from.length][];
	for (int i = 0; i < from.length; i++) {
		to[i] = from[i].clone();
	}
	return to;
}

Cheers,
Pete Houston

Categories: Tricks & Tips Tags: ,

Improve finger/multi-touch on ViewGroup


I’ve been working on an application that users can take many touch operations on screen (ViewGroup) like: Click, LongClick, Swipe-Up, Swipe-Down, Fling-Left, Fling-Right, Pinch-In, Pinch-Out, DoubleTap…

However, my application has a problem, that is, the Pinch-In and Fling-Left/-Right process at the same time.

The process is like:

onInterceptTouchEvent()

-> (1) GestureListener : TRUE -> fire onFling() , FALSE -> go to (2)

-> (2) ACTION_POINTER_UP (DOWN) -> TRUE/FALSE: return super.onInterceptTouchEvent()

This process somehow makes difficult to Pinch-In. Trouble for 2 days, found a way to improve this:

protected boolean onInterceptTouchEvent(MotionEvent me) {
    // whatever check before...

    // if one finger only
    if(me.getPointerCount() == 1) {
        return super.onInterceptTouchEvent(me);
    } else {
        // do something else
        return false;
    }
}

This really does the trick.

Cheers,
Pete Houston