Mobile App Development: Tutorial How To Create Custom Android Code Templates

1 Star2 Stars3 Stars4 Stars5 Stars (10 votes, average: 5.00 out of 5)
Loading...

Introduction

This tutorial will show you how to create custom Android code templates of your own. Most Android developers would have used Android code templates at least once to start projects. But have you tried creating your own Android code templates? In this tutorial, we will show you how to create a template that can be used to generate a Android project from Android Studio IDE that contains Google Analytics configuration. (Google Analytics v4 for Android)

Tung Dao Xuan, tungdx1210@gmail.com, is the author of this article and he contributes to RobustTechHouse Blog

 

Video & Source Code

Source Code

You can download the source code at GoogleAnalyticApplication-2015-05-31.

Step by Step Video

Video Tutorial How To Create Custom Android Code Template

 

High Level View of Code Generation Process

Create custom Android code templates

If you are not familiar with the code generation process, please also check out the documentation of the full process here.

 

Steps To Create Custom Android Code Templates For Google Analytics

To build your own template, please ensure that:

  1. You understand the code generation process described above at a high level.
  2. You have some knowledge about FreeMarker
  3. You have some knowledge about Android IDE Template Format and you can see the documentation here.

 

Step 1: Create Google Analytic Application Folder

This is for the template directory you need. On Windows, place it in: path-to-your-installation-android-studio-folder\plugins\android\lib\templates\activities. Please change your path appropriately on Linux, Mac OS etc.

Then, create the root folder and other files inside your GoogleAnalyticApplication folder.

GoogleAnalytics Folder

 

Step 2: Create template.xml file

Each template directory must contain a template.xml file. This XML file contains the metadata about the template, including the name, description, category and user-visible parameters that the IDE will present as options to the user. The XML file also indicates the name of the recipe XML file which gets processed by FreeMarker, and the global variables XML file  if there are global variables besides the template parameter values that should be visible to all FreeMarker-processed files (.ftl files).

<?xml version="1.0"?>
<template
	format="3"
	revision="4"
	name="Google Analytics Application"
	minApi="7"
	minBuildApi="14"
	description="Creates a new application that has already Google Analytics configuration.">

	<category value="Activity" />
	<formfactor value="Mobile" />

	<parameter
		id="activityClass"
		name="Activity Name"
		type="string"
		constraints="class|unique|nonempty"
		suggest="${layoutToActivity(layoutName)}"
		default="MainActivity"
		help="The name of the activity class to create" />

	<parameter
		id="layoutName"
		name="Layout Name"
		type="string"
		constraints="layout|unique|nonempty"
		suggest="${activityToLayout(activityClass)}"
		default="activity_main"
		help="The name of the layout to create for the activity" />

	<parameter
		id="classApplication"
		name="Class extends Application"
		type="string"
		constraints="nonempty|class"
		help="The name of class that extends from Application" />

	<parameter
		constraints="nonempty|string"
		id="googleAnalyticID"
		name="Google Analytic ID"
		type="string"
		help="Id of Google Analytic" />

	<parameter
		id="dispatchPeriod"
		name="Dispatch Period"
		help="Frequency of automatic dispatch in seconds. Defaults to 30 minutes (1800 seconds)."
		type="string"
		default="1800"/>

	<parameter
		id="autoActivityTracking"
		name="Auto Activity Tracking"
		help="If true, views (Activities) will be tracked automatically. false by default."
		type="boolean"
		default="false"/>
		
	<!-- 128x128 thumbnails relative to template.xml -->
	<thumbs>
		<!-- default thumbnail is required -->
		<thumb>template_google_analytics.png</thumb>
	</thumbs>

	<globals file="globals.xml.ftl" />
	<execute file="recipe.xml.ftl" />

</template>

There are parameters: activityClass, layoutName, classApplication, googleAnalyticID, dispatchPeriod, autoActivityTracking which will be shown in popups when you create a project.

Create Custom Android Code Templates

 

 Step 3: Create globals.xml.ftl file

The optional globals XML file contains global variable definitions, for use in all FreeMarker processing jobs for this template.

<?xml version="1.0"?>
<globals>
    <global id="manifestOut" value="${manifestDir}" />    
    <global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
    <global id="resOut" value="${resDir}" />	    
</globals>

 

Step 4: Create folder & files inside root folder

The root folder contains template source code & template resource to generate.

Root Folder

4a. Create AndroidManifest.xml.ftl

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="${packageName}">

    <application
        android:name="${packageName}.${classApplication}"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
		
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
			
        <meta-data
            android:name="com.google.android.gms.analytics.globalConfigResource"
            android:resource="@xml/analytics_global_config" />

        <activity
            android:name=".activities.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

There are parameters: packageName & classApplication that are declared in template.xml file above.

 

4b. Create Application.java.ftl

package ${packageName};

import android.app.Application;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;

/**
 * Created by TungDX on 5/29/2015.
 */
public class ${classApplication} extends Application {
    private static GoogleAnalytics analytics;
    private static Tracker tracker;

    @Override
    public void onCreate() {
        analytics = GoogleAnalytics.getInstance(this);
        tracker = analytics.newTracker("${googleAnalyticID}");
    }

    public static GoogleAnalytics getGoogleAnalytics() {
        return analytics;
    }

    public static Tracker getTracker() {
        return tracker;
    }
}

There are parameters: packageName & googleAnalyticID which are parameters declared in template.xml file above.

 

4c. Create MainActivity.java.ftl

package ${packageName}.activities;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

import ${packageName}.${classApplication};
import ${packageName}.R;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        ${classApplication}.getGoogleAnalytics().reportActivityStart(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        ${classApplication}.getGoogleAnalytics().reportActivityStop(this);
    }
}

There are parameters: packageName & classApplication which are parameters declared in template.xml file above.

 

4d. Create activity_main.xml.ftl

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <TextView
        android:text="@string/ready"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

 

4e. Create strings.xml.ftl

<resources>
    <#if !isNewProject>
    <string name="title_${activityToLayout(activityClass)}">${escapeXmlString(activityTitle)}</string>
    </#if>
       
	<string name="ready">Google Analytic is ready!</string>
</resources>

 

4f. Create dimens.xml

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>

 

4g. Create recipe.xml.ftl file

The recipe XML file contains the individual instructions that should be executed when generating code from this template. For example, you can copy certain files or directories (the copy instruction), optionally run the source files through FreeMarker (the instantiate instruction), and ask the IDE to open a file after the code has been generated (the open instruction).

 

<?xml version="1.0"?>
<recipe>
	<dependency mavenUrl="com.android.support:support-v4:${targetApi}.+" />
	<dependency mavenUrl="com.android.support:appcompat-v7:${targetApi}.+"/>
	<dependency mavenUrl="com.google.android.gms:play-services:6+" />
	
    <instantiate from="AndroidManifest.xml.ftl"
             to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
			 
	<instantiate from="src/app_package/Application.java.ftl" to="${escapeXmlAttribute(srcOut)}/${classApplication}.java"/>
	
	<instantiate from="src/app_package/activities/MainActivity.java.ftl" to="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java"/>

	<instantiate from="res/xml/analytics_global_config.xml.ftl" to="${escapeXmlAttribute(resOut)}/xml/analytics_global_config.xml"/>
	
	<instantiate from="res/layout/activity_main.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml"/>
	
	<copy from="res/values/dimens.xml" to="${escapeXmlAttribute(resOut)}/values/dimens.xml"/>
	
    <merge from="res/values/strings.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/values/strings.xml" />   

    <open file="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java" />
    <open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
</recipe>

 

 

4h. Check Dependencies

Check Dependencies

 

 4i. Check AndroidManifest.xml.ftl

<instantiate from="AndroidManifest.xml.ftl"          to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />

Check AndroidManifest.xml.ftl

 

4j. Check Application.java.ftl

<instantiate from="src/app_package/Application.java.ftl" to="${escapeXmlAttribute(srcOut)}/${classApplication}.java"/>https://robusttechhouse.com/wp-admin/post.php?post=6937&action=edit&message=10#

 

 

Check Application.java.ftl

 

4k. Check MainActivity.java.ftl

<instantiate from="src/app_package/activities/MainActivity.java.ftl" to="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java"/>

Check MainActivity.java.ftl 1

Check MainActivity.java.ftl 2

 

4l. Check analytics_global_config.xml.ftl

<instantiate from="res/xml/analytics_global_config.xml.ftl" to="${escapeXmlAttribute(resOut)}/xml/analytics_global_config.xml"/>

Check analytics_global.config.xml.ftl

4m. Generate files: activity_main.xml, dimens.xml, strings.xml from template to project.

<instantiate from="res/layout/activity_main.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml"/>
	
<copy from="res/values/dimens.xml" to="${escapeXmlAttribute(resOut)}/values/dimens.xml"/>
	
<merge from="res/values/strings.xml.ftl" to="${escapeXmlAttribute(resOut)}/values/strings.xml" />

 

4n. Open files after the project is generated.

<open file="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java" />
<open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />

 

Try Generating A Project For Your Own Template

If your Android Studio IDE is running, please restart it to see your own template as shown in following image.

Create Custom Android Code Templates

If you encounter this error when you are generating a project from the template:

AssertionError: Wrong line separators: ‘…plication;\r\n\r\nimport…’ at offset 29:

Please check your line separators in all your files in the template. Please ensure that you use the correct line separators for your computer’s OS. Eg Window uses LF, Linux or MAC OS use CRLF.

 

Conclusion

And that’s it. It isn’t that difficult to create custom Android code templates and you will benefit from it in the long-term because you would adhere to the DRY (Don’t Repeat Yourself) principle and save yourself some time. Have fun coding!

 

RobustTechHouse is a leading tech company focusing on mobile app development, ECommerce, Mobile-Commerce and Financial Technology (FinTech) in Singapore. If you are interested to engage RobustTechHouse on your projects in Singapore, you can contact us here.

 

 

References

Video showing the steps

Source code can be downloaded at GoogleAnalyticApplication-2015-05-31

Custom Android Code Templates Slides

GoogleSource Templates

ADT Template Format Documentation by Roman Nurik

 

 

 


Also published on Medium.

Recommended Posts
  • Afsal Ovingal

    How can i create a template project with 2 or more modules together at the time of new project creation its self.

Contact Us

We look forward to your messages. Please drop us a note for any enquiries and we'll get back to you, asap.

Not readable? Change text. captcha txt
RobotGood Store