Archiv für den Monat: Juli 2010

Android-Appz.de berichtet über Memory

Hey,
Android-Appz.de hat ein nettes Review über Memory veröffentlicht! 8.5 von 10 Punkten, Genial! Vielen vielen Dank dafür @Tim 😀

Gr33tz Goddchen

Flurry Analytics House Ads – Market Links not working on Milestone

Hey everybody,

i was experiencing a problem on my Milestone (Android 2.1). When i clicked on any Flurry Ad that led to a market://… link nothing happened. Instead there was an error in my Logcat saying „could not find a resolving intent on ad click“. On my friend’s Milestone it didn’t work either.

So i made a workaround: I hosted a PHP file on my webserver which just redirects to the market link. Because clicking ads that lead to webpages work perfectly fine…

So i created the following file called market_redirect.php on my webserver:


        $pname = $_GET['pname'];
        header('Location: market://search?q=pname:'.$pname);

Now everything works fine when users click on my house ads 🙂 Now i set my destination url to http:///market_redirect.php?pname=.

Gr33tz Goddchen

Android OnSharedPreferenceChangeListener not called

Hey everyone,

i now had a problem with an OnSharedPreferenceChangeListener multiple times. The problem was: it just never got called. I had a PreferenceActivity to manage the settings and i wanted to get notified in my main Activity when something changed. But my listener never was called.

Recently i found the answer to that problem on StackOverflow. The thing is that the SharedPreference keeps its listeners in a WeakHashMap. Which leads to the inability to use a nested inner class a the listener since it will be garbage collected.

So the solution to that problem is just storing the listener in a private variable like this:

private OnSharedPreferenceChangeListener prefListener;

And everything will work just fine 🙂

Gr33tz Goddchen

TableLayout with borders / margins

Hey everybody,

in my latest Android game i had the problem that i had a TableLayout with 4×4 icons (cards) in it. There should be a border between them. But neither setting „android:layout_margin“ or anything else i tried did work 🙁 So i had the idea of surrounding each of my table cells content (the icon) with a LinearLayout that only containt the content (the icon) and set a padding (left, right, top, bottom, 2px) on that LinearLayout. And: it works perfectly 😀 Hope that helps many developers that also have problems with TableLayout and borders / margins.

See the app screenshot for a view of what i wanted to do:

Gr33tz Goddchen

„Android Bash“ hits 1000 downloads

Hey everybody,
i’m proud to announce that „Android Bash“ now has more then 1000 downloads in the Android Market 🙂
It let’s you view quotes from various bash sources like iBash.de, German-Bash.de or Bash.org in the categories latest, best and random.

Gr33tz Goddchen

ListView Divider Settings Order

Hey everybody,

today i experienced a little „problem“ with a ListView that i want to share with you.

I had a ListView defined in an XML layout file:


<ListView android:id="@+id/ListView" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:dividerHeight="5px"
		android:divider="#000000" android:scrollbars="none" />

For some reason i now needed to create it programmatically. So i did the following to create an equivalent ListView:


			ListView listView = new ListView(context);
			listView.setDivider(new ColorDrawable(0));
			listView.setDividerHeight(5);
			listView.setVerticalScrollBarEnabled(false);

But somehow the divider didn’t show up anymore. So what was the reason for that? It was just the order! Somehow setting the divider color after setting it’s height doesn’t work and the height is reset to 0. So changing the order to first setting the color and then setting the height fixed the problem!

Gr33tz Goddchen

„App Update Notifier“ hits 1000 downloads in Android Market

YEAY,
my first Android app hits 1000 downloads in the Android Market. „App Update Notifier“ has won the race for this milestone.

Followed by „Android Bash“ with ~900 downloads…

Thanks for using my apps! 😀

Gr33tz Goddchen

Backward Compatible Android Programming

Hey everybody,

i just wanted to share my way of making Android apps backwards compatible with older Android versions.

In my case i have the „App Update Notifier“ app. Basically it checks your installed apps for available updates. Therefore it queries the Android Market (via Android Market API). To be able to do this one has to provide a valid google account login. On Android 2.x devices there is the AccountManager class that you can query for the phone’s account information and use this information. This way the user doesn’t have to provide his login details again for your app. He just needs to accept once that your app might use his login details. But this feature is not available on Android 1.x. So the user has to provide valid google login details in the settings of my app. Because of that there were two versions of „App Update Notifier“ in the Android Market at the beginning. „App Update Notifier (for 1.x)“ and „App Update Notifier (for 2.x)“.

But then i thought of a way to make both functionalities available in one app. So i had to think of a way to check whether AccountManager is available on the current device or not. So i came up with using Java Reflection. I wrote this simple function:


public static boolean classAvailable(String name) {
     try {
          Class.forName(name);
          return true;
     } catch (ClassNotFoundException e) {
          return false;
     }
}

It just tries to get the Class information for the given class and returns true if it exists and false if it’s not present in the current Android version.
This way it is easy to destinguish between the two versions. For example in my settings activity i have two possible layouts – the one where the user needs to enter his login details and the one where he doesn’t because they are provided through the AccountManager.

if (classAvailable("android.accounts.AccountManager")) {
     addPreferencesFromResource(R.xml.settingsscreen_2x);
} else {
     addPreferencesFromResource(R.xml.settingsscreen_1x);
}

This way you can check if a class you want to use is available on the device. But now you have a problem. The compiled DEX file contains stuff that might not exist on the current device. Android will then throw a VerifyException when it’s loading the DEX file. Now you have two options: use Reflection only to call your stuff (which is ok when only have to call a single method or so) or you need to seperate the code for different Android versions. So you only have supported references in you invoked dex file. For example i have a class with the AccountManager implementation called Helper2x and a class with the old way called Helper1x. This way on an Android 1.x device, the Helper2x DEX file will never be loaded and therefore will not throw an exception.

Hope that helps many of you to make their app better backwards compatible.
Gr33tz Goddchen