Amazon Gift Cards

Saturday, July 17, 2010

Paid Apps vs Apps with ads in Android

With Korea adding to the list of Android market having Paid apps, the question is, is it good to have your app as a paid app or have ads on it.

There are the markets where paid apps are available
Australia - (English)
Austria - (German)
Canada - (English)
France - (French)
Germany - (German)
Italy - (Italian)
Japan - (Japanese)
Netherlands - (Dutch)
New Zealand - (English)
Spain - (Spanish)
Switzerland - (French,German,Italian, Romansh)
United Kingdom - (English)
United States - (English)
Korea - (Korean)

If you look closely, just 14 out of 46 countries have paid apps, in these countires only 5 countries having English as their primary language, and all the other countries are of different languages. This language barrier is a big factor in selling your apps, especially if your app has a global target.

Why do you have to care about other languages?
As i stated before mobile is not the web. On the web, forums and blogs would copy your content and translate it to their native language or they could use tools like Google Translate or Yahoo BabelFish, mobile apps on the other hand could not be copied and recompiled to other languages and redistributed, thats why it is important that you cater atleast the biggest langauges like English, Chinese, French, Spanish, German, Arabic, Italian, etc.

What does the language have to do with your apps being paid or with ads?
If your app would be in English and you dont have plans to support other language, its pretty bad idea to make it as a paid app (users can forgive you for the ads if its not on their native language). And there are a lot of apps that are paid who are doing this and if your app is just the english language, kindly uncheck the non english speaking countries on the market (Some countries have a huge numbers of non-english speaking/reading so be kind to their paying users)

Conclusion
If English would be the only language in your app then dont go with paid apps.
If you do a paid app 32 other counties would not see your app, which some of them huge market like India (English as big second language) and China.

Android: resolution independence and high performance graphics

New Video added on http://sites.google.com/site/tutorialsformobileprogramming/android-videos titled "Android: resolution independence and high performance graphics "

Monday, July 12, 2010

App Inventor

Incase you didn't read the news today, App Inventor is announce, its a way to develop Android App without programming. And what do I have to say about it?

1. Kindly fix the GUI tool in eclipse before releasing some GUI tools for noobs when the SDK for developers cant work properly...

2. It would generate a lot of stupid application, since the market is already in a mess, it would be a lot more messier (yes its redundant) when this comes out. Yes there would be 1 or 2 that would be good that would came out from this but how many nonsense apps would be out there. Is the number of apps really that important to battle yourself with iOS when more than 50% of the apps are nonsense and copy cat apps.

3. I know the palm guy is now in Android but do you have to copy Project Ares (btw their interface is way better then App Inventor)

As you can see, i hate it, giving power to create applications is not the same with the power normal people gets in creating websites, in the web you dont have to download and install something (unless android would have this feature) and thus mobile users are committed into what they had downloaded, but on the web, users usually pass by a page then forget about it like nothing happens and on the web you can just bounce into a single page in the middle of the sitemap and you dont have to download/visit the whole site.

For example, your friend, far from you, found a cute page on the web, most of the time they would give you a link and you'll click on it and you'll view it (its done), in a mobile application when your found a cute activity on the app, they would give the market link/apk/QRCode to their friend, friend would download, wait, install, wait, open app, other friend would tell them where to see the activity. These process is disappointing when the other friend, who's interest so happen to be slightly different, found out that app she/he got from the other friend is not worth her time. While this still happens in the web but usually the user would just close the site within few seconds and they dont have to uninstall it.

Unless Android or other mobile OS dont behave like the web, too many apps in any market that have more useless apps then useful apps are not a good indicator. And kindly fix the GUI on Eclipse or create a new IDE for Android for developers/designers if Eclipse is not enough for the GUI stuff.

Sunday, July 11, 2010

Debugging locally with App Engine and Android

Senario
AppEngine is free, Android is free thus you think that developing for both of them is cheap and thus you start working on your backend and found out that you have to connect the AppEngine to Android, how could you enable this?

Introduction
If you're in mac, there is the AppEngine software but what it does is bind your AppEngine application to localhost thus you cant access localhost in Android coz Android has its own localhost, and if you access via your ip and port on Android it might not work.

What Do I Need
Terminal
Mac or Linux (If you guys can port this in Windows or it works in Windows, kindly drop a comment below)

On App Engine
On your terminal, get your IP
ifconfig | grep 192
If you're under the 192.168 IP then you can see your IP, copy this. In mac its the first 192.168.x.x. For our example we would use 192.168.1.101 and bind it to 8082
cd <your AppEngine Folder
dev_appserver.py -a 192.168.1.101 -p 8082 .


On Android
In you App you can now access 192.168.1.101:8082 and it shall return it from values from your AppEngine. This method works as long as your in the same network thus if there are more than one programmer both could access it.

You could use Open URL Tutorial to try it out :)

Tuesday, July 6, 2010

Access Internal classes in Android

So long before, i was blogging too much, then i stopped and told you guys i'll be doing more Android and Frontend, then i quit OpenRice and now back to doing Android as hobby.

Senario
Say you want to access some internal class in Android which are not public and you really want to use that feature, what do you do?

Notes
* This is on how to access non public classes thus are restricted classes which are not recommended, use this knowledge at your own risk and i'm NOT to be held responsible to any harm it might cause.
* This is quite advance and i hope to explain it as much as possible while keeping it simple.
* The following codes might not work as you/I expected it to work thus this is for reference only

Introduction
As i was trying to update my tutorial on Localization i was looking at how the locale setting was done and i found it at the LocalePicker.java under the onListItemClick function, if you try this code in your app you would realized that ActivityManagerNative and IActivityManager are internal classes. So how to use this piece of code?
IActivityManager am = ActivityManagerNative.getDefault();
Configuration config = am.getConfiguration();
Loc loc = mLocales[position];
config.locale = loc.locale;
final String language = loc.locale.getLanguage();
final String region = loc.locale.getCountry();
am.updateConfiguration(config);



What Do I Need
In Manafiest.xml
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />

Codes
DexFile  df = new DexFile(new File("/system/app/Settings.apk"));
String name = "com.android.settings.LocalePicker"; 
ClassLoader cl = getClassLoader();     
Class LocalePicker = df.loadClass(name, cl);
Class ActivityManagerNative = Class.forName("android.app.ActivityManagerNative");
Class IActivityManager = Class.forName("android.app.IActivityManager");

Method getDefault =  ActivityManagerNative.getMethod("getDefault", null);
Object am = IActivityManager.cast(getDefault.invoke(ActivityManagerNative, null));

Method getConfiguration =  am.getClass().getMethod("getConfiguration", null);

Configuration config = (Configuration) getConfiguration.invoke(am, null);
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
config.locale = locale;

Class[] args = new Class[1];
args[0] = Configuration.class;
Method updateConfiguration =  am.getClass().getMethod("updateConfiguration", args);
updateConfiguration.invoke(am, config);


Explanation
DexFile df = new DexFile(new File("/system/app/Settings.apk"));
You need to load the package from where the class is from
NOTE: The dex don't directly open or readed in this line but they're memory-mapped read-only by the VM.

String name = "com.android.settings.LocalePicker";
ClassLoader cl = getClassLoader();
Class LocalePicker = df.loadClass(name, cl);

Load the class where your target classes were imported.

Class ActivityManagerNative = Class.forName("android.app.ActivityManagerNative");
Class IActivityManager = Class.forName("android.app.IActivityManager");

Load the classes you want to use

Method getDefault = ActivityManagerNative.getMethod("getDefault", null);
To use a method you have to get the method first. http://developer.android.com/reference/java/lang/reflect/Method.html

Object am = IActivityManager.cast(getDefault.invoke(ActivityManagerNative, null));
Execute the getDefault method using the invoke class, and since it has a return of IActivityManager, cast the returned object.

Method getConfiguration = am.getClass().getMethod("getConfiguration", null);
Since am is an instance of IActivityManager we could use getClass() to reflect on its method.

Configuration config = (Configuration) getConfiguration.invoke(am, null);
Execute the getConfiguration method, you can see here we use the regular casting (Configuration), you could also use Configuration.Class.cast

ocale locale = new Locale(languageString);
Locale.setDefault(locale);
config.locale = locale;

Just set a new Locale configuration

Class[] args = new Class[1];
args[0] = Configuration.class;
Method updateConfiguration = am.getClass().getMethod("updateConfiguration", args);
updateConfiguration.invoke(am, config);

To reflect on a method with arguements you have to do it this way, the second argument is a list of Class type of the required arguments. Optionally you could refer to another approach found in Calling private methods in Android

Conclusion
Reflecting a class could be lead to unknown results, like this class would set System Wide language change and not application wise and thus executing would lead to your whole system being reconfigured on the language (your home screen would HANG after you change and click Home), this is a powerful tool thus "We great knowledge comes great responsibility" :)

References
Google Groups
ClassTest
LocalePicker.java
Calling private methods in Android
http://developer.android.com/reference/java/lang/reflect/Method.html

Sunday, July 4, 2010

Adobe Air Download for Android

Over at Droid-life an early version of Adobe Air was leaked, and the download links are there, the problem is that megaupload is blocked in some places on the globe including Hong Kong thus for our friends in Hong Kong, here are the links for Adobe Air in Rapidshare.com

http://rapidshare.com/files/404834594/AIR.apk.html
http://rapidshare.com/files/404838291/air_apps.zip.html

Friday, July 2, 2010

Birthday Gift to me by Google

Could be coincidence but I got an Official Android Froyo Update on my birthday. Thank you Google