Tutorial Android
In this tutorial we will build an Android app with the ability to receive push notifications. This includes creating a new Android app, enabling the Google Cloud Messenger, preparing ApiOmat as well as setting up a basic layout and some code.
Creating a new Android App
Open your IDE. We recommend using Android Studio, as that is what we will be using for this tutorial.
Select Start A new Android Studio Project or if you want to enhance an existing project, choose Open an existing Android Studio Project, as shown in the figure below.
If you've decided to create a new project, you will have to setup a few basics, which we will cover in the next 4 screens. If you are using an existing one you can skip these instructions continuing with Enable GCM for your app. First you will enter your app's name and a company domain. You will need these information later.
Next, you'll have to pick the android devices and minimum API levels you are targeting with your app. Please note, that you'll need to choose at least API level 9 to be able to use Google's GCM.
After that, you will have to decide which kind of activity your app initially should contain. For this tutorial, select the Blank Activity.
Next, set your activity's name, and respectively your activity's title and the layout's name. The name won't effect this tutorial, so we will just leave it as the default and As it plays a subordinate role for our use case, just keep the defaults and finish setting up our project by clicking the finish button.
To send push messages to an Android device, we have to use the Google Cloud Messaging Service and to do so we have to get a server API key. The next part of the tutorial will walk you through signing up for GCM.
Enable GCM for your app
Please note that a Google account is required in order to enable the GCM service.
Go to the Enable Google Services for your app section of Google's developer site.
As shown in Figure 01: Create or choose an app you will have to enter your app's name and the corresponding package name. Please make sure that these values are matching those of your app's manifest.
Now you can choose and configure your app's services by clicking the button at the bottom.
You can activate other services in addition to cloud messaging, but we won't need any others for this tutorial.
Figure 02: Choose and configure services.
Click on the button ENABLE GOOGLE CLOUD MESSAGING, to see your Server API key.
Instead of copying and pasting, you can use the generated config file. Simply click the button at the bottom one more time.
Click on Download google-services.json the .json file includes all the generated values and can be added to your project's app-folder.
Setting up the Backend
2. If you haven‘t created an app yet, you will be asked to give your first app a name and to describe it shortly. In our example the app is called “Facebook”. For your app, though, you should use a unique name.
3.Now you see the Apiomat Dashbaord. You start on the Module Market with all the available modules you can add to your app. Scroll down and select the Push Module and click "+" to add the module.
4. A pop-up will appear where we can configure the Push module. Insert your GCM API project key and confirm with “OK”.
5. Now we have to deploy our backend, to do this, we click on the slider next to "INACTIVE".
6. Click on the SDK tab on the menu at the top of the screen. This will take you to an overview of the ApiOmat SDKs, which you can download by clicking "DOWNLOAD SDK".
7. For this tutorial we will need the SDK for Android. To download, simply click on the button “Download SDK”. This downloaded .ZIP file contains all classes and resources you'll need. Unpack the .ZIP file, saving it somewhere on your hard disk.
9. Open the folder containing the unpacked .ZIP file.
10. Copy both of the folders into the “src” folder (source) of your app. Now we can get started on the frontend!
Configure your App
Now we need the configuration file we downloaded while Enabling GCM for our app. Simply copy the file into the app-Folder of your app-project. As this file is intended to be parsed by the Google Services plugin for Gradle, we have to install this plugin first. This is done by adding a dependency into your gradle files.
-
insert the following line into the build.gradle file in the root folder of your project.
classpath 'com.google.gms:google-services:2.0.0-alpha6'
2. add the plugin into the build.gradle file in the app folder of your project
apply plugin: 'com.google.gms.google-services'
Next we have to install the Google Play services SDK. Go to the SDK manager in Android studio, select the SDK Tools tab and install the latest version of the Google Play Services. After the installation is finished, add the following dependency to your app's build.gradle located in your app folder.
dependencies {
compile "com.google.android.gms:play-services-gcm:8.3.0"
}
Creating the Layout
To be able to trigger the GCM registration and display push messages, we'll put together a simple layout in this tutorial. You'll find the XML code below, where the two most important elements are a TextView with the id txt_push and a Button with the id btn_push. We will use those ids later.
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
xmlns:app
=
"http://schemas.android.com/apk/res-auto"
xmlns:tools
=
"http://schemas.android.com/tools"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:fitsSystemWindows
=
"true"
android:orientation
=
"vertical"
tools:context
=
"com.apiomat.push.MainActivity"
>
<
android
.support.design.widget.AppBarLayout
android:layout_width
=
"match_parent"
android:layout_height
=
"wrap_content"
android:theme
=
"@style/AppTheme.AppBarOverlay"
>
<
android
.support.v7.widget.Toolbar
android:id
=
"@+id/toolbar"
android:layout_width
=
"match_parent"
android:layout_height
=
"?attr/actionBarSize"
android:background
=
"?attr/colorPrimary"
app:popupTheme
=
"@style/AppTheme.PopupOverlay"
/>
</
android
.support.design.widget.AppBarLayout>
<
TextView
android:id
=
"@+id/txt_push"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:paddingTop
=
"50dp"
android:layout_gravity
=
"center"
android:text
=
"No message recevied yet."
/>
<
Button
android:id
=
"@+id/btn_push"
android:layout_marginTop
=
"20dp"
android:text
=
"prepare"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center"
/>
</
LinearLayout
>
Writing Code
First we need to handle the GCM registration. We'll instantiate the service if no registration token was found. Within the method onHandleIntent, we save the registration token to shared preferences and create a new ApiOmat user with this token. Finally we save this user.
public
class
RegistrationIntentService
extends
IntentService
{
private
static
final
String TAG =
"RegIntentService"
;
public
static
final
String APIOMAT_PREFERENCES =
"APIOMAT_PREFERENCES"
;
public
static
final
String APIOMAT_PREFERENCES_GCM_TOKEN =
"GCM_TOKEN"
;
public
RegistrationIntentService()
{
super
(TAG);
}
@Override
public
void
onHandleIntent(Intent intent)
{
try
{
final
InstanceID instanceID = InstanceID.getInstance(
this
);
final
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE,
null
);
final
SharedPreferences prefs =
this
.getSharedPreferences(APIOMAT_PREFERENCES,
this
.MODE_PRIVATE);
final
SharedPreferences.Editor editor = prefs.edit();
editor.putString(APIOMAT_PREFERENCES_GCM_TOKEN, token);
editor.commit();
createUser(token,
this
);
}
catch
(Exception e)
{
Log.e(TAG, e.getMessage());
}
}
public
static
void
createUser(String token,
final
Context ctx)
{
final
User user =
new
User();
user.setUserName(
"myUser"
);
user.setPassword(
"myPassword"
);
user.setRegistrationId(token);
Datastore.configureWithCredentials(user);
user.saveAsync(
new
AOMEmptyCallback()
{
@Override
public
void
isDone(ApiomatRequestException exception)
{
Toast.makeText(ctx,
"Registration sucessful"
, Toast.LENGTH_SHORT).show();
}
});
}
}
We also need a service to handle a server side token refresh. Simply create a file called InstanceIDService.java and paste the code below.
public
class
InstanceIDService
extends
InstanceIDListenerService
{
private
static
final
String TAG =
"MyInstanceIDLS"
;
@Override
public
void
onTokenRefresh()
{
final
Intent intent =
new
Intent(
this
, RegistrationIntentService.
class
);
startService(intent);
}
}
Next we will create a service that handles the reception of push messages. When a push message is recieved, we send a broadcast, that will be handled in our main activity and display it in our text view.
public
class
GCMPushReceiverService
extends
GcmListenerService
{
public
static
final
String INTENT_ID =
"GCMIntent"
;
public
static
final
String INTENT_DATA_ID =
"GCmIntentData"
;
private
static
final
String TAG = GCMPushReceiverService.
class
.getName();
@Override
public
void
onMessageReceived(String from, Bundle data) {
final
String message = data.getString(
"payload"
);
final
Intent intent =
new
Intent(INTENT_ID);
intent.putExtra(INTENT_DATA_ID, message);
getApplicationContext().sendBroadcast(intent);
}
}
Last but not least, we have to extend our main activity as shown below. If we haven't recieved a token yet, we will provide the function to request a new one by clicking the previously defined button. Otherwise we will hide the button and only show push messages in our text field.
public
class
MainActivity
extends
Activity
{
private
static
final
String REGISTRATION_SUCCESS =
"RegistrationSuccess"
;
private
static
final
String REGISTRATION_ERROR =
"RegistrationError"
;
private
BroadcastReceiver receiver;
public
TextView push_message;
private
Button push_button;
private
Context ctx;
@Override
protected
void
onCreate(Bundle savedInstanceState)
{
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
push_message = (TextView) findViewById(R.id.txt_push);
push_button = (Button) findViewById(R.id.btn_push);
ctx =
this
;
receiver =
new
BroadcastReceiver()
{
@Override
public
void
onReceive(Context context, Intent intent)
{
push_message.setText(intent.getStringExtra(GCMPushReceiverService.INTENT_DATA_ID));
}
};
final
IntentFilter filter =
new
IntentFilter();
filter.addAction(GCMPushReceiverService.INTENT_ID);
registerReceiver(receiver, filter);
final
String token =
this
.getSharedPreferences(RegistrationIntentService.APIOMAT_PREFERENCES, MODE_PRIVATE).getString(RegistrationIntentService.APIOMAT_PREFERENCES_GCM_TOKEN,
""
);
if
(token.isEmpty())
{
push_button.setOnClickListener(
new
View.OnClickListener()
{
@Override
public
void
onClick(View v)
{
final
Intent intent =
new
Intent(ctx, RegistrationIntentService.
class
);
startService(intent);
}
});
}
else
{
push_button.setVisibility(View.INVISIBLE);
}
}
@Override
protected
void
onResume()
{
super
.onResume();
}
@Override
protected
void
onPause()
{
super
.onPause();
}
}
Asking for Permission
An Android app is not allowed to do anything by default. So to access the internet, we have to ask for permission. We do this in the Android Manifest.
1. Open the AndroidManifest.xml in your app's root folder.
2. Add this line after the <manifest [...]> tag:
<!-- App receives GCM messages.-->
<uses-permission android:name=
"com.google.android.c2dm.permission.RECEIVE"
></uses-permission>
<!-- GCM connects to Google Services.-->
<uses-permission android:name=
"android.permission.INTERNET"
></uses-permission>
<!-- GCM requires a Google account.-->
<uses-permission android:name=
"android.permission.GET_ACCOUNTS"
></uses-permission>
<!-- Keeps the processor from sleeping when a message is received.-->
<uses-permission android:name=
"android.permission.WAKE_LOCK"
></uses-permission>
3.Enter the following two permissions, but replace "my_app_package” with the your app's package name:
<permission android:name=
"my_app_package.permission.C2D_MESSAGE"
android:protectionLevel=
"signature"
></permission>
<uses-permission android:name=
"my_app_package.permission.C2D_MESSAGE"
></uses-permission>
4. Assign our GCMPushReceiverService as a child node of “application”. For details on this service please see section above.
<service android:name=
".GCMPushReceiverService"
android:exported=
"false"
>
<intent-filter>
<action android:name=
"com.google.android.c2dm.intent.RECEIVE"
/>
</intent-filter>
</service>
5. In addition to the GCMPushReceiverService, we also need to add the InstanceIDService, which has to be added as a child node of "application" as well:
<
service
android:name
=
".InstanceIDService"
android:exported
=
"false"
>
<
intent
-filter>
<
action
android:name
=
"com.google.android.gms.iid.InstanceID"
/>
</
intent
-filter>
</
service
>
6. We also nee a BroadcastReceiver, which also has to be a child element of “application”:
<
service
android:name
=
".RegistrationIntentService"
android:exported
=
"false"
/>
Let’s go!
To test our app, we will send the push message from the ApiOmat dashboard.
1. Start the app on your Android device.
2. Press the button “Prepare”. A toast saying: “Registration successful” should emerge. The device is now registered at GCM.
3. Open the dashboard of ApiOmat.
4. Click the tab My Modules and then the button “Push”.
5. Click “Send”.
6. Check out your Android app. The text field should contain the push message you entered. In our case it was the message "Test!".