Different keys for Debug and Release Build

In lots of projects i had the problem, that i need different key for a live environment and the environment during the development. for example currently i use parse.com for my cloud backend. there is a live instance (with application_id and client_id) and a development instance. until now all the time i had to switch the instances by copy the right key in the string.xml file. in this post u can see my mechanism for that by using gradle.

the following code is for initialize the parse framework in my android project

Parse.initialize(this, getString(R.string.parse_application_id), getString(R.string.parse_client_key));

the keys for the application_id and the client_key are in the string.xml file. at the beginning they are empty. looks strange but later this will make sense ;)

<?xml version="1.0" encoding="utf-8"?>
<resources>

 <string name="parse_application_id"></string>
 <string name="parse_client_key"></string>

</resources>

the following code is my gradle.build file for my android application

apply plugin: 'android'

android {
 ...
 defaultConfig {
 ...
 }
 signingConfigs {
 ...
 }
 buildTypes {
 release {
 ...

 }
 debug {
 ...
 }
 }
}
dependencies {
 ...
}

android.applicationVariants.all { variant ->
   variant.mergeResources.dependsOn {
      overrideParseKey(variant)
   }
}

def overrideParseKey(def buildVariant) {
 def xmlStringsFileAsNode = new XmlParser().parse("app/src/main/res/values/strings.xml")

 xmlStringsFileAsNode.each {

    // debug
    if (buildVariant.name.equals("debug")) {
       if (it.attribute("name").equals("parse_application_id")) {
          it.setValue("DEBUG_PARSE_APPLICATION_ID")
       }
       if (it.attribute("name").equals("parse_client_key")) {
          it.setValue("DEBUG_PARSE_CLIENT_ID")
       }
    }

    // release
    if (buildVariant.name.equals("release")) {
       if (it.attribute("name").equals("parse_application_id")) {
          it.setValue("RELEASE_PARSE_APPLICATION_ID")
       }
       if (it.attribute("name").equals("parse_client_key")) {
          it.setValue("RELEASE_PARSE_CLIENT_ID")
       }
    }

    def fileWriter = new FileWriter("app/src/main/res/values/strings.xml")
    def printWriter = new PrintWriter(fileWriter)
    printWriter.print("""<?xml version="1.0" encoding="utf-8"?>\n""")
    def xmlPrinter = new XmlNodePrinter(printWriter)
    xmlPrinter.setPreserveWhitespace(true)
    xmlPrinter.print(xmlStringsFileAsNode)
 }
 createOverrideDirIfNecesarry()
}

def createOverrideDirIfNecesarry() {
   def file = new File("app/src/main/res/values/")
   if (!file.exists()) {
      file.mkdirs()
   }
}

so what happen in this gradle script? at first u can see 2 build types (release and debug). i build the release apk by using gradle assembleRelease with the signingConfigs. the debug type is used by me with gradle assembleDebug and the debug type is also used by the android studio by default!

if u rebuild your project (android studio will do this also automatically) –> build –> rebuild project, the gradle script will be executed. the script will replace the empty entries in the string.xml file withe the debug keys!!! is that cool? yes it is. and if you build the application with gradle assembleRelease the script will replace the entries with the release keys!

create android dependency with gradle and upload artifact to maven repository

some weeks ago i would like to share a set of util classes from my android project with a colleague. and whats better than create a jar and upload it into a maven repository? the following code show how to create a jar file and upload it to a maven repository by using gradle

apply plugin: 'android'
apply plugin: 'maven'

def computeVersionName() {
     return "0.1.0-SNAPSHOT"
}

android {
     // defaultConfig, buildTypes and stuff

     task AnimationUtilsLibJar(type: Jar) {
          archiveName = "animation-" + computeVersionName()
          from fileTree(dir: 'build/classes/debug')
     }
     artifacts {
          archives AnimationUtilsLibJar
     }
uploadArchives {
     repositories {
          mavenDeployer {
               pom.groupId = 'de.buildpath.utils.android'
               pom.artifactId = 'animation'
               pom.version = computeVersionName()

               Console console = System.console()
               def username = null;
               def password = null;

               if (console != null) {
                    username = new String(console.readLine("\nUsername: "))
                    password = new String(console.readPassword("Password: "))

                    if (computeVersionName().endsWith("-SNAPSHOT")) {
                         snapshotRepository(url: "SNAPSHOT_REPO_URL"){
                            authentication(userName: username, password: password)
                         }
                    } else {
                         repository(url: "RELEASE_REPO_URL") {
                              authentication(userName: username, password: password)
                         }
                    }

                }
            }
        }
    }
}

to upload the artifact you have to open a terminal, change to the root directory of your project and execute the following command

gradle uploadArchives

now you can integrate the dependency in your android project

dependencies {
    compile 'de.buildpath.utils.android:animation:0.1.0-SNAPSHOT'
}

 

Persist data with greenDAO

In my last project i used the framework greenDao (http://greendao-orm.com/) for persisting data. this post will show you how to use it.

1. At first you have to create a simple java project to define and generating the entities

2. include DaoGenerator.jar to your buildpath

3. create a starter class like this

public class Start {
	private static final int SCHEMA_VERSION = 1;

        public static void main(final String[] args) throws Exception {

                final Schema schema = new Schema(SCHEMA_VERSION, "<MODEL_NAMESPACE>");

		new DaoGenerator().generateAll(schema, "<OUTPUT_PATH>");
        }
}

4. now you can define your entity

final Entity entityArea = schema.addEntity("Area");
entityArea.addStringProperty("areaId").primaryKey();
entityArea.addStringProperty("country").notNull();
entityArea.addDateProperty("lastSync").notNull();
entityArea.addStringProperty("name").notNull();
entityArea.addStringProperty("subscribed").notNull();

5. after executing the main method the result looks like this

public class Area {

    private String areaId;
    private String country;
    private java.util.Date lastSync;
    private String name;
    private String subscribed;

    private transient DaoSession daoSession;
    private transient AreaDao myDao;

    // KEEP FIELDS - put your custom fields here
    // KEEP FIELDS END

    public Area() {
    }

    public Area(String areaId) {
        this.areaId = areaId;
    }

    public Area(String areaId, String country, java.util.Date lastSync, String name, String subscribed) {
        this.areaId = areaId;
        this.country = country;
        this.lastSync = lastSync;
        this.name = name;
        this.subscribed = subscribed;
    }

// some getter, setter and some other stuff

}

6. but thats not all! look at the AreaDao class. inside of this class is all the sql stuff i dont want to write by my own. and the class extends from AbstractDao. so you have all the CRUD operations for free! awesome :-)

7. now you can use this classes in your android-project and you have do add the greendao.jar to your android project

8. in the next snipped i show you how easy it is to save an entity in your android project

public class DataProvider {
      private static final String DB_NAME = "my-db";
      private final SQLiteDatabase db;
      private AreaDao areaDao;

      public DataProvider(final Context context) {
            SQLiteDatabase.CursorFactory cursorFactory = null;
             final DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, DB_NAME, cursorFactory);

            db = helper.getWritableDatabase();
            DaoMaster daoMaster = new DaoMaster(db);
            daoSession = daoMaster.newSession();

            areaDao = daoSession.getAreaDao();
      }

      public void createArea(final Area area) {
            areaDao.insert(area);
      }
}

the setup looks a little bit like overhead. but remember – you get CRUD for free!

9. the last think i want to show you is the query api. here is a short example how you can use ist

areaDao.queryBuilder().where(AreaDao.Properties.Country.like("%island%")).list();
// that means give me all areas from countries that contains "island"

the query api has also methods like equals, greater than, between and all the other stuff we know from sql like ordering…

in addition it is possible to create relations between entities. for more infomation click here