engage and retain users in the android world - droidcon italy 2016
TRANSCRIPT
Who I am?
+Matteo Bonifazi
Android Google Developer Expert
Member of GDG Rome
@mbonifazi
matteobonifazi[at]gmail[dot]com
Do you need any Android book?
Sviluppare applicazioni per Android in sette giorni
AndroidProgrammazione Avanzata
Goat Checker storyWhat is the best scored Android question?
http://developer.android.com/reference/android/os/UserManager.html
User acquisition
How people become aware about an app?
32% family, friends and collegues
13% TV
17% search engines 14% company website
24% app store
stats from https://think.storage.googleapis.com/docs/mobile-app-marketing-insights.pdf
App Invites
App Invites from Google
● App content sharing
● Personalized onboarding flows
● Compatible for both Android & iOS
● Sharing & installation stats are fully
integrated with Google Analytics
App Invites
classpath 'com.google.gms:google-services:2.0.0-alpha5'
apply plugin: 'com.google.gms.google-services
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
AndroidManifest.xml
build.gradle
compile 'com.google.android.gms:play-services-appinvite:8.4.0'
project configuration
https://developers.google.com/mobile/add?platform=android&cntapi=appinvite
google-services.json
App Invites
public void sendInvite() {
Intent intent = new AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title)
.setMessage(getString(R.string.invitation_message)) .setDeepLink(Uri.parse(getString(R.string.invitation_deep_link))) .setCustomImage(Uri.parse(getString(R.string.invitation_custom_image)))
.setCallToActionText(getString(R.string.invitation_cta)).build();
startActivityForResult(intent, REQUEST_INVITE);
}
mClient = new GoogleApiClient.Builder(this).addApi(AppInvite.API).build();
100 max message length
App Invites
public void sendInvite() {
Intent intent = new AppInviteInvitation.IntentBuilder("Send Invitation")
.setEmailHtmlContent("<html><body>"
+ "<a href=\"%%APPINVITE_LINK_PLACEHOLDER%%\">GOAT Checker Invitation</a> </body></html>")
.setEmailSubject("XYZ Offer").build();
startActivityForResult(intent, REQUEST_INVITE);
}
mClient = new GoogleApiClient.Builder(this).addApi(AppInvite.API).build();
50 KB max HTML CONTENT
App Invites
Intent intent = new AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
...
.setOtherPlatformsTargetApplication(
AppInviteInvitation.IntentBuilder.PlatformMode.PROJECT_PLATFORM_IOS,
getString(R.string.ios_app_client_id))
...
.build();
No Windows Phone, sorry :)
App Invites
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_INVITE && resultCode == RESULT_OK ) {
String[] ids = AppInviteInvitation.getInvitationIds(resultCode,data);
Log.d(TAG, getString(R.string.sent_invitations_fmt, ids.length));
}
}
App Invites
boolean autoLaunchDeepLink = true;
AppInvite.AppInviteApi.getInvitation(mGoogleApiClient, this, autoLaunchDeepLink)
.setResultCallback(new ResultCallback<AppInviteInvitationResult>(){
@Override
public void onResult(AppInviteInvitationResult result) {
Log.d(TAG, "getInvitation:onResult:+result.getStatus());
}});
App usage
26% of installed smartphone apps are
used daily
1 in 4 apps are never used
Most installed apps are not often used
App usage
38% of app users are likely to download an app when it’s required to complete a
purchase, half of which would uninstall it after purchase is complete.
Consumers often abandon apps immediately after a download.
App Indexing
<activity
android:name=".GoatActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="goatchecker.webs.com/"
android:scheme="http" />
</intent-filter>
</activity>
App Indexing
protected void onNewIntent(Intent intent) {
String action = intent.getAction();
String data = intent.getDataString();
if (Intent.ACTION_VIEW.equals(action) && data != null) {
String productId = data.substring(data.lastIndexOf("/") + 1);
Uri contentUri = GoatChecker.CONTENT_URI.buildUpon()
.appendPath(productId).build();
//Handle content
}
}
App Indexing
android-app://dekra.goatchecker/http/goatchecker.webs.com
Protocol Package ID PathScheme
App Indexing Markup
● http● custom
App Indexing
<link rel=“alternate”
href=“android-app://dekra.goatchecker/http/goatchecker.webs.com” />
Approve request on Webmaster Tools - https://www.google.com/webmasters/tools
<html><head> ... <link rel="alternate" href="android-app://dekra.goatchecker/http/goatchecker.webs.com" /> ...</head><body> … </body>
In the web page
App Indexing
compile 'com.google.android.gms:play-services-appindexing:8.4.0'
build.gradle
Uri APP_URI = Uri.parse("android-app://dekra.goatchecker/http/goatchecker.webs.com");
Uri WEB_URL = Uri.parse("http://goatchecker.webs.com/");
URI definition
mClient = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
Google Client
App Indexing
mUrl = "http://goatchecker.webs.com/";
mTitle = "Are you a goat?";
public Action getAction() {
Thing object = new Thing.Builder()
.setName(mTitle).setUrl(mUrl).build();
return new Action.Builder(Action.TYPE_VIEW).setObject(object)
.setActionStatus(Action.STATUS_TYPE_COMPLETED).build();
}
App Indexing
@Override
public void onStart() {
super.onStart();
mClient.connect();
AppIndex.AppIndexApi.start(mClient, getAction());
}
@Override
public void onStop() {
AppIndex.AppIndexApi.end(mClient, getAction());
mClient.disconnect();
super.onStop();
}
App Indexing
App Indexing example https://developers.google.com/app-indexing/partners/case-studies
Thank you for your attention
TURIN 07-08 MARCH 2016
+Matteo Bonifazi - @mbonifazi
matteobonifazi[at]gmail[dot]com
http://androidinsettegiorni.wordpress.comAll pictures belong to their respective authors
Discover today if you are a goat