2012-09-29

Gratis- och betalapp med samma kodbas

Jag har efter lanseringen av MantisDroid insett att jag även behöver publicera en gratisversion, så att man kan ladda hem appen och se om den är något att ha innan man betalar för fullversionen. Visst, man har 15 minuter på sig att testa en betalapp, men det är inte många som gör det eftersom 15 minuter är så väldigt kort tid.

Lösningen är alltså att skapa en gratisversion av min app med begränsad funktionalitet.

Hur gör man en gratisversion utan att duplicera all kod?

Det är faktiskt ganska enkelt. En app kan använda en annan app och referera till den som ett library (bibliotek). På så sätt kan den nya appen utnyttja allt i den andra. Dock kan inte en app som markerats som library längre vara en app som går att installera på en enhet. Därför behövs det 3 projekt: En betalapp, en gratisapp och en library-app. I mitt fall så ligger all kod i betalappen som redan är publicerad på Play Store.
  1. Skapa library-appen genom att skapa ett nytt projekt med lämpligt paketnamn, ex. se.nextsource.android.mantisdroid
    Det är samma paketnamn som i betalappen, men det gör ingenting.
  2. Öppna library-appen i Eclipse, ta fram properties för projektet, klicka på Android och markera checkboxen "Is Library".
  3. Flytta kod och resurser som ska vara gemensamma från betalappen till library-appen.
  4. Öppna properties för betalappen, klicka på Android och lägg till library-appen som ett Library.
  5. Skapa gratisappen som ett nytt projekt med nytt paketnamn, ex. se.nextsource.android.mantisdroidfree 
  6. Öppna properties för gratisappen, klicka på Android och lägg till library-appen som ett Library.
  7. Deklarera de komponententer (activity, service, receiver, provider etc. och även permissions, uses-library etc.) som gratis- och betalappen använder från library-appen.
  8. Nu har du 2 appar med exakt samma kodbas men med olika paketnamn.
  9. För att särskilja versionerna mellan varandra så jag lagt till en ny Application-klass i gratis- och betalapp-projekten som ärver från en Application-klassen som ligger i library-appen. Vid onCreate så sätts vilken version som körs i superklassen och sedan anropas super.onCreate(). I superklassens onCreate så slår jag av och på olika funktioner som ska skilja applikationerna åt.
Ref: http://developer.android.com/tools/projects/projects-eclipse.html

Problem jag stötte på
-Se till att ingen duplicering av kod eller res-filer finns för då bygger det inte!
-Från SDK 14 så går det inte att använda resId i switch-case i ett library eftersom de inte längre är final så ändra det med refactor-funktionen i Eclipse till if-else. Irriterande, men det finns en bra förklaring:
http://android-developers.blogspot.se/2011/10/changes-to-library-projects-in-android.html
-Proguard fick svårt att obfuskera koden i biblioteket så jag var tvungen att lägga till följande i proguard.cfg:
-keep public class com.google.android.vending.licensing.ILicensingService
-dontwarn org.xmlpull.v1.**
-dontwarn android.support.**
Obs! Tänk på att lägga till det i alla 3 proguard.cfg.

Resultatet
Nu när allt är klart så behöver jag bara göra följande för att införa kodändringar, bygga och publicera mina 2 appar:
  1. Gör ändringar och fixar i library-appen.
  2. Ändra versionsnumret i apparna så att de stegas upp.
  3. Kör kommandot: ant release på båda apparna så att de bygger, obfuskeras och signeras för release.
  4. Testkör båda apparna så att de fungerar och ändringarna är testade.
  5. Lägg upp de 2 nya apk:erna på Play Store.
  6. Klart!