My Android Apps

Solbrent - UV Indeks. Sjekk yr.no sin UV prognose. Pass på deg og dine i Sola!



Badetemperaturer for Oslo. Local water temperatures for Oslo.


A New and fresh way to experience your Google Reader stream

Concerts and events from Sentrum scene, Rockefeller & John dee in Oslo

A specialist app for break baking enthusiasts. 

GPS Locate your phone from anywhere. Find your phone, by making it ring, when it is muted by sending it SMS. 

Følg meg på Twitter
My employer

Inmeta blogs
Thursday
Nov032011

A couple of IntelliJ live templates for Android developers

IntelliJ is very good at making developers type less. When developing Android however; I find myself typing a couple of lines over and over. I have created a few Live templates to save some finger work.

This Live template creates a static TAG string than can be used for logging   

private static String TAG = $className$.class.getName();

 This Live tmplate creates a Toast.

Toast.makeText(this,"$TEXT$", Toast.LENGTH_LONG).show();

 Do you have any Live templates for Android that you want to share?

 

Saturday
Sep032011

The Google Plus App for Android does not respect the background data setting

In the Account/Sync menu on Android phones there is a setting that a user can check to allow or deny data traffic from applications that are running in the background. The value of this setting is available to developers in the API through the getBackgroundDataSetting method on the ConnectivityManager.

The documentation says

“Developers should respect this setting, and check the value of this before performing any background data operations.”

The wording is “should”, and I suspect that many developers either forget, ignore or do not know this. Why should your app be polite and respect the setting, when the rest of the world does not?  Even the official Google Plus App totally ignores this and uploads your photos via the “Instant upload”, regardless of the setting. Here is how to test it:

1. Make sure WIFI is disabled, and mobile data is enbaled
2. In the Account/Sync page in your Android settings, disable the "Background data setting".
3. Make sure you have the "Instant upload" setting enabled in Google Plus. 
4. Take a photo
5. In a couple of minutes the image will be available online.

The concept of having a common setting for background data is a great idea and very user friendly. The user shouldn't have to disable background data in every single app. Some apps may even lack a setting to turn data off. 

I suspect that google is stuck between a rock and a hard place right now. If they change the Android operating system to enforce this setting, a lot of applications would be cut off from the Internet, including their own. 

Why not enforce the setting, or remove it? Right now it gives users a false
sense of 
security. It also adds confusion since a lot of apps ignore the setting. Google could also practice what they preach and respect  the setting in their own applications to set a good example.

Tuesday
Aug022011

Ny norsk Android app på market

Jeg har nå publisert Android applikasjonen "Solbrent" som viser UV data fra Yr.no. Man kan sjekke applikasjonen før man reiser på stranda, og se hvor sterk sola er den dagen.

Vær obs på at applikasjonen laster ned mye data. Det finnes ikke noe god måte å slå opp UV indeksen for en gitt lokasjon i APIet til yr. Jeg  må derfor lese igjennom hele XML dokumentet til man finner en UV måling som er i nærheten av brukerens lokasjon. 

Denne applikasjonen fikke en noe trang fødsel med en rekke problemer første uken; 

Det er flere pixler på HTC Sensation enn Samsung Galaxy 2 og en del andre "store" Android telefoner. Veldig mange av de nyere og store telefonene har en oppløsning på 480 x 800, mens min HTC Sensation har 960 x 540. Dette gjorde at noe av innholdet i appen ble skjøvet utenfor skjermen.

Lokasjon, Lokasjon, Lokasjon. Hvorfor skal dette være så vanskelig?

Jeg klønet til i konstruksjon av URLen jeg henter UV-XML data ifra. Istedet for 2007-08-01 som var riktig datoformat, laget min applikasjon URLer uten ledende null-tegn på dag; 2007-08-1 (!) Dette gjorde at applikasjonen krasjet 1. August og oppdatering var nødvendig. Unit testing ville plukket opp dette!     

Leassons learned

Enhetstesting er minst like viktig på Android som ved Enterprise

Lokasjon er vanskelig! En ganske god artikkel, som også belyser hvor vanskelig dette egentlig er; ble publisert av Reto Meier. Koden han har skrevet er langt fra perfekt, og inneholder konkrete feil. Når Google kløner det det til er det ikke enkelt!

Stream-basert parsing er nyttig når man ønsker å løpe igjennom et XML dokument helt til man finner det man er interessert i, og så avslutte. Man har to alternativer; SAX Parseren i JDKen, og XMLPullParser som er innebygget i rammeverket. 

 

Tuesday
Jul192011

Unable to add window -- token null is not for an application

I have encountered this problem twice now, So I can just as well put it up here. 
If you get this error, or something like it, you are probably working on an Android app that uses the maps library. If I add an Overlay to a map by extending the ItemizedOverlay class, I must provide a constructor that keeps a reference to the Context.
public SomeItemizedOverlay(Drawable marker, Context context) {
        super(boundCenterBottom(marker));
        this.mContext = context;
        populate();
 }
When I implement the onTap method I give the context to a AlertDialog.Builder
    @Override
    protected boolean onTap(int index) {
        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
        dialog.setTitle("Title");
        dialog.setMessage("Message");
        dialog.show();
        return true;
    } 
It is VERY importalt that the Context given to the AlertDialog.Builder is the Activity that extends MapActivity. If you do not, you end up with the exception below.
So, the code 
SomeItemizedOverlay overlay =
             new SomeItemizedOverlay (marker, getApplicationContext());
Does not work, but the following does 
SomeItemizedOverlay overlay =
                new SomeItemizedOverlay (marker, this);

ERROR/AndroidRuntime(29246): FATAL EXCEPTION: main
        android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
        at android.view.ViewRoot.setView(ViewRoot.java:562)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
        at android.app.Dialog.show(Dialog.java:265)
        at android.app.AlertDialog$Builder.show(AlertDialog.java:802)
        at com.norsktrafikkinfo.activities.RoadMessagesItemizedOverlay.onTap(RoadMessagesItemizedOverlay.java:46)
        at com.google.android.maps.ItemizedOverlay.onTap(ItemizedOverlay.java:453)
        at com.google.android.maps.OverlayBundle.onTap(OverlayBundle.java:83)
        at com.google.android.maps.MapView$1.onSingleTapUp(MapView.java:356)
        at com.google.android.maps.GestureDetector.onTouchEvent(GestureDetector.java:533)
        at com.google.android.maps.MapView.onTouchEvent(MapView.java:683)
        at android.view.View.dispatchTouchEvent(View.java:3932)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:955)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1784)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1157)
        at android.app.Activity.dispatchTouchEvent(Activity.java:2228)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1759)
        at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2340)
        at android.view.ViewRoot.handleMessage(ViewRoot.java:1980)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:143)
        at android.app.ActivityThread.main(ActivityThread.java:4293)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:507)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
        at dalvik.system.NativeStart.main(Native Method)

RROR/AndroidRuntime(29246): FATAL EXCEPTION: main        android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application        at android.view.ViewRoot.setView(ViewRoot.java:562)        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)        at android.app.Dialog.show(Dialog.java:265)        at android.app.AlertDialog$Builder.show(AlertDialog.java:802)        at com.norsktrafikkinfo.activities.RoadMessagesItemizedOverlay.onTap(RoadMessagesItemizedOverlay.java:46)        at com.google.android.maps.ItemizedOverlay.onTap(ItemizedOverlay.java:453)        at com.google.android.maps.OverlayBundle.onTap(OverlayBundle.java:83)        at com.google.android.maps.MapView$1.onSingleTapUp(MapView.java:356)        at com.google.android.maps.GestureDetector.onTouchEvent(GestureDetector.java:533)        at com.google.android.maps.MapView.onTouchEvent(MapView.java:683)        at android.view.View.dispatchTouchEvent(View.java:3932)        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:955)        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1784)        at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1157)        at android.app.Activity.dispatchTouchEvent(Activity.java:2228)        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1759)        at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2340)        at android.view.ViewRoot.handleMessage(ViewRoot.java:1980)        at android.os.Handler.dispatchMessage(Handler.java:99)        at android.os.Looper.loop(Looper.java:143)        at android.app.ActivityThread.main(ActivityThread.java:4293)        at java.lang.reflect.Method.invokeNative(Native Method)        at java.lang.reflect.Method.invoke(Method.java:507)        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)        at dalvik.system.NativeStart.main(Native Method)

Sunday
Jul102011

First encounter with the Amazon App store

I am working on an application called HOGER. (Hands off google reader). It’s a niche app I admint, for Google reader users, like myself,  that want to quickly browse through headlines while doing something else; like exercising, eating or working.  

To increase the reach of my app, I have submitted it to Handster and the Amazon App Store in addition to the Android Market.  The big difference between Amazon and Google is that they follow in apple’s footsteps and review all applications before they are accepted into the store.
 
First rejection

The first time I submitted my app, I checked back every hour to see if it was published. The review process can take days, sometimes weeks I learned. After four days Amazon reported back that there was a slight problem with my submission. A small Icon was visually inconsistent with a larger icon I submitted. 

They obviously care about the look of their storefront. Excellent! I have seen a couple of bad looking icons or two in the Android Market. I think this Quality assurance process benefits both store and seller. It was also the fault of my own not to read the guidelines https://developer.amazon.com/help/faq.html#Program Overview properly before submitting.

Second Rejection

This morning I have had my app rejected again. It seems that it crash with an “out of memory” error on devices with hardware keyboards, but only if the user changes orientation from portrait to landscape, during the loading of Google news items.

The feedback I got shows very clearly that a real person- or team has installed my app and are testing it, including corner cases. It also seem that they test on different devices.

I test my applications of three devices; A galaxy Tab 10.1, HTC Sensation and a lower end device with a slow CPU and small screen; Huawei IDEOS. This takes out a lot of bugs, but with 400+ Android devices available, test help is greatly welcome!

Hoger. My "Hands off Google Reader Reader"


Developer complaints

The Amazon App store is young, and some developers complain. The Swedish team, bithack, behind the popular game “Apparatus” decided to pull their game from the web store earlier this month 

To Amazon’s defence, the most significant problem they point out is also present in the Android market. Getting in touch with complaining customers is very difficult.

All in all I look forward to working with Amazon. I find it assuring that they actually invest time and money on all submitted applications. Quality problems, malware and to some degrees Spam is starting to become an issue in the Android Market. It will be interesting to see how they will succeed with a more “appelish” approach to their market.