[Android] Membuat Push Notifications dengan Parse

result screen

*Sebelumnya mau share dikit.. jadi pas kemaren2 main ke websitenya Parse (parse.com), ternyata salah satu software engineernya tuh org indonesia. Beliau punya personal blog juga, n it’s very inspiring ūüôā thx for hallucinogen*

Clone Github disini

So, apa itu ‘push notifications’ ? push notifications adalah teknik dimana server mengirimkan pesan ke client, baik itu pesan teks maupun JSON. Dan bisa dilakukan walaupun status aplikasi client sedang tidak aktif. Syaratnya hanyalah koneksi internet. Teknik ini sangat efektif bila dibandingkan dengan teknik ‘pull’, dimana client harus melakukan request terlebih dahulu ke server. Teknik ‘push’ memerlukan device token untuk setiap device, yang digenerate saat aplikasi pertama kali diinstall. ‘Push’ pertama kali dipopulerkan oleh Apple, dan menjadi basic untuk aplikasi instant messaging modern seperti WhatsApp, BBM dll. Untuk menggunakan ‘push’, kita harus membuat server terlebih dahulu, kemudian mengintegrasikannya dengan GCM (Google Cloud Messaging). Tetapi saat ini ada framework gratis yang disediakan oleh Parse.com, sehingga kita tidak perlu membangun server terlebih dahulu. Yang perlu kita lakukan hanyalah mendaftar di Parse.com, membuat aplikasi, mengambil ‘Application ID’ dan ‘Client Key’ nya, kemudian memasangnya di aplikasi android kita. Untuk mengirim pesan ‘push’, disediakan dashboard untuk kita oleh Parse. Nah, disini kita akan mencoba membuat aplikasi sederhana untuk mencoba penggunaan ‘push’. So let’s start ūüôā

1. Daftar account dan buat aplikasi di Parse.com.
Masuk ke website Parse, kemudian daftarkan account. Ketika pertama kali mendaftar, anda akan diminta memasukkan nama aplikasi pertama. Isi nama aplikasi dengan ‘Parse Push Demo’. Setelah registrasi berhasil, pilih aplikasi yang baru anda buat (Parse Push Demo), kemudian klik ‘Settings’ -> ‘Key’. Catat key ‘Application ID’ dan ‘Client Key’. Key ini akan dipasang di aplikasi android dan akan digunakan sebagai identifier aplikasi android anda.

pilih aplikasi

pilih setting

app id dan client key

2. Download library Parse dan Bolt.
Pertama, download library parse disini. Untuk aplikasi ini digunakan library parse versi 1.10.1 dan library bolt versi 1.2.1.

3. Buat project android.
Berikutnya buat ‘New Android Application Project‘. Disini digunakan IDE Eclipse Luna. Untuk minimal SDK : API 15, target SDK : API 23, dan Build With : API 23. Nama main activity : ‘MainActivity.java‘, nama layoutnya : ‘activity_main.xml‘.

new project

4. Pasang library parse dan bolt.
Copy library parse dan library bolt ke direktori ‘libs‘ project. Setelah itu clean project.

5. Modifikasi file ‘strings.xml’.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Parse Push Demo</string>
    <string name="action_settings">Settings</string>
    <string name="notifications">Notifications</string>
</resources>

6. Buat file ‘color.xml’ di “/res/values/”.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#FF0000</color>
    <color name="colorPrimaryDark">#F52727</color> 
    <color name="textColorPrimary">#FFFFFF</color>
    <color name="windowBackground">#FFFFFF</color>
    <color name="navigationBarColor">#000000</color>
    <color name="colorAccent">#FF80AB</color>
    <color name="orange">#F52727</color>
    <color name="black">#000000</color>
    <color name="gray">#808080</color>
</resources>

7. Modifikasi file “styles.xml”.

<resources>
    <style name="MyTheme" parent="MyTheme.Base"></style>

    <style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

Jangan lupa untuk mengubah theme yang digunakan di “AndroidManifest.xml” menjadi “MyTheme“.

8. Buat file layout “toolbar.xml” di “/res/layout”.

 <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
local:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> 

9. Buat file “row_list.xml” di “/res/layout”.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp" >

<TextView
android:id="@+id/_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />

<TextView
android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:textColor="@color/gray" />

<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:textColor="@color/black" />

<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/black" />

</LinearLayout>

10. Modifikasi file “activity_main.xml” di “/res/layout”.

<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"
    tools:context="com.bonioctavianus.parsepushdemo.MainActivity" >
    
    <LinearLayout
            android:id="@+id/container_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <include
                android:id="@+id/toolbar"
                layout="@layout/toolbar" />
        </LinearLayout>
    
    <ListView
        android:id="@+id/list"
        android:layout_below="@id/container_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:smoothScrollbar="true" />

</RelativeLayout>

11. Buat package pendukung

Buat 3 package baru di bawah package utama : “config“, “database“, “helper“. Sehingga project mempunyai empat package :

  • com.bonioctavianus.parsepushdemo
  • com.bonioctavianus.parsepushdemo.config
  • com.bonioctavianus.parsepushdemo.database
  • com.bonioctavianus.parsepushdemo.helper

package

 

 

 

 

 

 

12. Buat class “PushConfig.java” di package “config”.

Class ini berisi konfigurasi untuk aplikasi Parse. Ganti Application ID dan Client Key sesuai dengan key aplikasi Parse yang telah dibuat sebelumnya.


package com.bonioctavianus.parsepushdemo.config;

public class PushConfig {

// nama channel aplikasi, tidak boleh menggunakan spasi
public static final String PARSE_CHANNEL = "ParsePushDemo";

// key application ID
public static final String PARSE_APPLICATION_ID = "Pe7Lre67wCvJTyjhTs0w41mPD9l3DolppTuPc8um";

// key client
public static final String PARSE_CLIENT_KEY = "A2ZkPQiLAqTSX5DfMDJDGm4hQHOpkwL5Ov8LiZI7";

// id notifikasi
public static final int NOTIFICATION_ID = 100;
}

13. Buat class “DBAdapter.java” di package “database”.

Class ini berfungsi sebegai database SQLite untuk menyimpan setiap notifikasi yang diterima.

package com.bonioctavianus.parsepushdemo.database;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

// Statement untuk membuat class DBAdapter.
public class DBAdapter {

    // Membuat kolom tabel. Untuk kolom pertama selalu
    // direkomendasikan menggunakan nama "_id".
    public static final String KEY_ROWID = "_id";
    public static final String KEY_DATE = "date";
    public static final String KEY_TITLE = "title";
    public static final String KEY_MESSAGE = "message";

    // Membuat array String yg berisi semua KEY
    public static final String[] ALL_KEYS = new String[] { KEY_ROWID,
            KEY_DATE, KEY_TITLE, KEY_MESSAGE };

    // Membuat informasi database seperti nama database, nama tabel dan versi
    // database.
    public static final String DATABASE_NAME = "dbNotif";
    public static final String TABLE_NAME = "notif";
    public static final int DATABASE_VERSION = 1; // nomor versi harus lebih
                                                    // besar untuk setiap
                                                    // perubahan pada database

    // perintah SQL untuk membuat database
    private static final String DATABASE_CREATE_SQL = "CREATE TABLE "
            + TABLE_NAME + " (" + KEY_ROWID
            + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_DATE
            + " TEXT NOT NULL, " + KEY_TITLE + " TEXT NOT NULL, " + KEY_MESSAGE
            + " TEXT NOT NULL" + ");";

    // Membuat context.
    private final Context context;

    // Membuat objek myDBHelper dari class DatabaseHelper yg meng'extends class
    // SQLiteOpenHelper
    private DatabaseHelper myDBHelper;

    // Membuat objek db dari class SQLiteDatabase
    private SQLiteDatabase db;

    // Mengatur context DatabaseHelper.
    public DBAdapter(Context ctx) {
        this.context = ctx;
        myDBHelper = new DatabaseHelper(context);
    }

    // membuka database
    public DBAdapter open() {
        db = myDBHelper.getWritableDatabase();
        return this;
    }

    // menutup database
    public void close() {
        myDBHelper.close();
    }

    // insert data ke dalam tabel
    public long insertNotif(String date, String title, String message) {
        long result = 0;
        
        open();
        ContentValues cv = new ContentValues();
        cv.put(KEY_DATE, date);
        cv.put(KEY_TITLE, title);
        cv.put(KEY_MESSAGE, message);

        result = db.insert(TABLE_NAME, null, cv);
        close();
        
        return result;
    }

    // mengambil semua data pada tabel
    public Cursor getAllNotif() {
        open();
        Cursor c = db.query(true, TABLE_NAME, ALL_KEYS, null, null, null,
                null, KEY_DATE + " DESC", null, null);
        if (c != null) {
            c.moveToFirst();
        }
        close();
        
        return c;
    }

    // membuat class DatabaseHelper yg meng'extends class SQLiteOpenHelper
    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        // method onCreate() untuk membuat database dengan parameter String
        // "DATABASE_CREATE_SQL"
        // yang telah didefinisikan sebelumnya
        @Override
        public void onCreate(SQLiteDatabase _db) {
            _db.execSQL(DATABASE_CREATE_SQL);
        }

        // method onUpgrade() untuk meng'update perubahan pada database
        // pertama menghapus database lama, kemudian membuat database baru
        // dengan
        // parameter oldVersion dan newVersion
        @Override
        public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {

            // menghapus database lama
            _db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);

            // membuat database baru
            onCreate(_db);
        }
    }
}

14. Buat class “AppController.java” di package “helper”.

Class ini meng’extends “Application“, dan akan segera run ketika aplikasi dibuka, kemudian melakukan registrasi device ke Parse.com

package com.bonioctavianus.parsepushdemo.helper;

import android.app.Application;

public class AppController extends Application {
    
    // objek singleton untuk register parse
    private static AppController mParseController;

    @Override
    public void onCreate() {
        super.onCreate();
        mParseController = this;
        
        // register with parse
        ParseHelper.registerParse(mParseController);

    }

    public static synchronized AppController getInstance() {
        return mParseController;
    }
}

15. Buat class “ParseHelper.java”di package “helper”.

Class ini berfungsi untuk registrasi device ke Parse.com. Data-data device yang dikirim akan meng’generate “Device Token” secara otomatis. Device Token ini unik untuk setiap device, dan digunakan sebagai “alamat” device oleh server Parse saat mengirim push.

package com.bonioctavianus.parsepushdemo.helper;

import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.bonioctavianus.parsepushdemo.config.PushConfig;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.SaveCallback;

public class ParseHelper {
    private static final String TAG = ParseHelper.class.getSimpleName();

    // method cek application ID dan client key
    public static void verifyParseConfiguration(Context context) {
        if (TextUtils.isEmpty(PushConfig.PARSE_APPLICATION_ID)
                || TextUtils.isEmpty(PushConfig.PARSE_CLIENT_KEY)) {
            Toast.makeText(
                    context,
                    "Isi Application ID dan client Key di PushConfig.java",
                    Toast.LENGTH_LONG).show();
            ((Activity) context).finish();
        }
    }

    // method untuk register aplikasi dengan parse
    public static void registerParse(Context context) {
        Parse.initialize(context, PushConfig.PARSE_APPLICATION_ID,
                PushConfig.PARSE_CLIENT_KEY);
        ParseInstallation.getCurrentInstallation().saveInBackground();

        ParsePush.subscribeInBackground(PushConfig.PARSE_CHANNEL,
                new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        Log.d(TAG, "Register Parse sukses !");
                    }
                });
    }
}

16. Buat class “CustomPushReceiver.java”.

Class ini meng’extends class “ParsePushBroadcastReceiver.java“. Class ini digunakan untuk menerima push, parsing data, dan mentrigger notifikasi.

package com.bonioctavianus.parsepushdemo.helper;

import java.util.Calendar;
import java.util.Date;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.bonioctavianus.parsepushdemo.database.DBAdapter;
import com.parse.ParsePushBroadcastReceiver;

public class CustomPushReceiver extends ParsePushBroadcastReceiver {
    private final String TAG = CustomPushReceiver.class.getSimpleName();
    private NotificationHelper notifHelper;
    private Intent parseIntent;
    private Context mContext;
    private DBAdapter db;

    // konstruktor
    public CustomPushReceiver() {
        super();
    }

    // method yang dicall saat notifikasi push diterima
    @Override
    public void onPushReceive(Context context, Intent intent) {
        super.onPushReceive(context, intent);
        Log.d(TAG, "onPushReceive() called...");

        if (intent != null) {
            this.mContext = context;
            this.parseIntent = intent;
            try {
                JSONObject json = new JSONObject(parseIntent.getExtras()
                        .getString("com.parse.Data")); // key default JSON dari parse -> "com.parse.Data"
                Log.d(TAG, "Push Received : " + json.toString());
                parsePushJson(json);

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    // method untuk ekstrak JSON
    private void parsePushJson(JSONObject json) {
        try {
            // jika "isBackground" == TRUE -> notifikasi tidak akan ditampilkan
            boolean isBackground = json.getBoolean("is_background"); 
            JSONObject data = json.getJSONObject("data");
            String title = data.getString("title");
            String message = data.getString("message");
            
            // untuk mengambil waktu pada saat ini
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            String received_at = DateToDay.setDateNotif(cal);
            
            // save data ke database
            db = new DBAdapter(mContext);
            long result = db.insertNotif(received_at, title, message);
            
            if (result != -1) {
                Log.d(TAG, "Save received push on DB success !");
            } else {
                Log.d(TAG, "Failed save received push on DB :(");
            }

            if (!isBackground) {
                Intent resultIntent = new Intent(mContext,
                        com.bonioctavianus.parsepushdemo.MainActivity.class);
                showNotificationMessage(title, message, resultIntent);
            }

        } catch (JSONException e) {
            Log.e(TAG, "Push message json exception: " + e.getMessage());
        }
    }

    // fire notifikasi
    private void showNotificationMessage(String title, String message,
            Intent intent) {

        notifHelper = new NotificationHelper(mContext);
        intent.putExtras(parseIntent.getExtras());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        notifHelper.showNotification(title, message, intent);
    }
}

17. Buat class “NotificationHelper.java” di package “helper”.

Class ini berfungsi sebagai helper untuk menampilkan notifikasi di system tray jika aplikasi sedang tidak dibuka (not on background), dan mengupdate ListView jika aplikasi sedang dibuka (on background).

package com.bonioctavianus.parsepushdemo.helper;

import java.util.List;

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.os.Build;
import android.support.v7.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;

import com.bonioctavianus.parsepushdemo.R;
import com.bonioctavianus.parsepushdemo.config.PushConfig;

public class NotificationHelper {
    private static final String TAG = NotificationHelper.class.getSimpleName();
    private Context mContext;

    // konstruktor
    public NotificationHelper() {

    }

    // konstruktor
    public NotificationHelper(Context context) {
        this.mContext = context;
    }

    // method untuk menampilkan notifikasi di system tray jika aplikasi sedang tidak dibuka (not on background)
    public void showNotification(String title, String message, Intent intent) {
        if (!TextUtils.isEmpty(title) & !TextUtils.isEmpty(message)) {
            if (isAppIsInBackground(mContext)) {
            Log.d(TAG, "Processing Notification...");
                int icon = R.drawable.ic_launcher;
                int mNotificationId = PushConfig.NOTIFICATION_ID;
                PendingIntent resultPendingIntent = PendingIntent.getActivity(
                        mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

                NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();

                NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                        mContext);
                Notification notification = mBuilder
                        .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
                        .setSmallIcon(icon)
                        .setTicker(title)
                        .setWhen(0)
                        .setAutoCancel(true)
                        .setContentTitle(title)
                        .setStyle(inboxStyle)
                        .setContentIntent(resultPendingIntent)
                        .setSound(
                                RingtoneManager
                                        .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                        .setContentText(message).build();

                NotificationManager notificationManager = (NotificationManager) mContext
                        .getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.notify(mNotificationId, notification);
                
                // intent ke main activity jika aplikasi sedang dibuka (on background)
            } else {
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                mContext.startActivity(intent);
              }
        } else {
            return;
        }
    }
    
    public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String activeProcess : processInfo.pkgList) {
                        if (activeProcess.equals(context.getPackageName())) {
                            isInBackground = false;
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }
 
        return isInBackground;
    }
}

18. Buat class “DateToDay.java” di package “helper”.

Class ini berfungsi sebagai helper class yang mempunyai method untuk menggenerate waktu pada saat ini.

package com.bonioctavianus.parsepushdemo.helper;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateToDay {
    
    // helper method untuk mengambil waktu saat ini
    public static String setDateNotif(Calendar cal) {
        Date date = cal.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        sdf.applyPattern("EEEE, d MMM yyyy - hh:mm:ss");
        String strDate = sdf.format(date);
        return strDate;
    }
}

19. Modifikasi file “MainActivity.java”.

Class ini menampilkan notifikasi yang telah disimpan ke database ke dalam ListView dengan SimpleCursorAdapter. Jika status aplikasi “on Background”, maka ListView akan direfresh setiap kali ada notifikasi baru (pada method “onNewIntent()”).

package com.bonioctavianus.parsepushdemo;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;

import com.bonioctavianus.parsepushdemo.database.DBAdapter;

public class MainActivity extends AppCompatActivity {
    private ListView list;
    private DBAdapter db;
    public android.support.v7.widget.Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mToolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        
        initView();
        setNotif();
    }
    
    private void initView() {
        this.db = new DBAdapter(this);
        this.list = (ListView) findViewById(R.id.list);
    }
    
    // menampilkan notifikasi dengan simple cursor adapter
    private void setNotif() {
        Cursor cNotif = db.getAllNotif();
        if (cNotif.getCount() > 0) {
            
            String[] data = new String[] { DBAdapter.KEY_ROWID, DBAdapter.KEY_DATE, DBAdapter.KEY_TITLE, DBAdapter.KEY_MESSAGE };
            int[] view = new int[] { R.id._id, R.id.date, R.id.title, R.id.message };
            SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.row_list, cNotif, 
                    data, view, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
            this.list.setAdapter(adapter);
        }
    }
    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setNotif();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

20. Modifikasi file “AndroidManifest.xml”.

Diperlukan beberapa permission yang harus ditambahkan di AndroidManifest.xml. Ganti nama package yang harus diganti dengan nama package anda. Disini kita membuat service dari class “com.parse.PushService”. Service ini akan listening setiap push notifications dari server, baik itu dari Google Cloud Messaging (untuk devices yang support Goole Play Support), maupun dari server milik Parse. Untuk aplikasi android ini, pertama-tama sistem Parse akan memerika file AndroidManifest.xml kita, kemudian karena disini kita mendeklarasikan receiver GCM, maka sistem Parse akan menggunakan sistem GCM untuk device yang support Google Play, dan menggunakan server Parse untuk device yang tidak support Google Play.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.bonioctavianus.parsepushdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="23" />
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.GET_TASKS"/>

    <!-- ganti "com.bonioctavianus.parsepushdemo.permission.C2D_MESSAGE" dengan nama package anda + .permission.C2D_MESSAGE -->
    <permission
        android:name="com.bonioctavianus.parsepushdemo.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
 
    <!-- ganti "com.bonioctavianus.parsepushdemo.permission.C2D_MESSAGE" dengan nama package anda + .permission.C2D_MESSAGE -->
    <uses-permission android:name="com.bonioctavianus.parsepushdemo.permission.C2D_MESSAGE" />

    <application
        android:name=".helper.AppController"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/MyTheme" >
        <activity
            android:name=".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>
        
        <!-- Added for Parse push notifications -->
        <service android:name="com.parse.PushService" />
        <receiver
            android:name=".helper.CustomPushReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.parse.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
 
               <!-- ganti dengan nama package anda -->
                <category android:name="com.bonioctavianus.parsepushdemo" />
            </intent-filter>
        </receiver>
 
        <!-- /Added for Parse push notifications -->
        
    </application>

</manifest>

21. Kirim Push dari dashboard Parse

Setelah aplikasi Android berhasil dibuat, sekarang saatnya uji coba mengirimkan push. Masuk ke website Parse, login -> masuk ke dashboard aplikasi -> Core. Disini seharusnya akan muncul satu tabel yang dibuat secara otomatis oleh Parse, yang berisi daftar devices yang sudah terdaftar (pada kasus ini hanya akan ada 1 devices, jika aplikasi baru diinstall pada 1 devices saja). Cek kolom “channels” dan “deviceToken”, kedua kolom ini harus mempunyai nilai eksak, karena jika nilainya “undefined”, maka notifikasi push tidak akan pernah masuk ke device tsb.

Next setelah memastikan “channels” dan “deviceToken” statusnya OK, klik “Push” -> “Send a Push”. Kemudian masukkan data JSON yang akan dikirim dengan key “data”, “title”, “message” (disini kita menggunakan JSON dan key’nya sesuai dengan parser yang disiapkan di class “CustomPushReceiver.java”), seperti pada gambar pada awal post ini. Finally hit “Send Now” ! Jika sukses, akan muncul notifikasi pada system tray device, jika status aplikasi “not on background”, sedangkan jika status aplikasi “on background”, ListView akan merefresh setiap kali ada notifikasi baru.

And so that’s it ! Thx for reading ūüôā

Reference : AndroidHive

6 respons untuk ‚Äė[Android] Membuat Push Notifications dengan Parse‚Äô

  1. message untuk JSON yg dikirim dari dashboard Parse nya apa ya ? format message JSON nya harusnya :
    {
    “data”: {
    “message”: “Ini untuk message”,
    “title”: “Ini untuk judul”
    },
    “is_background”: false
    }

    Suka

  2. gan. kalau saya mau pushnya dari android. misal gini aku mau kasi kabar menggunakan notif. jadi push nya pakai handphone bukan di website parse.com. gimana itu ?

    Suka

    1. Terimakasih atas kunjungannya ūüôā

      sebelumnya ingin memberi tahu kalau Parse.com sudah menutup layanannya, pihak Parse memberitahukan untuk segera melakukan back up data atau migrasi untuk setiap aplikasi yang sebelumnya menggunakan Parse.

      Push dari handphone ke server disebut upstream message. Implementasi yang saya tahu yaitu menggunakan layanan GCM dari Google, atau yang terbaru yaitu FCM dengan CCS.

      Link : https://developers.google.com/cloud-messaging/upstream#receive_xmpp_messages_on_the_app_server

      Garis besar kerjanya adalah aplikasi android membuat message yang akan dikirim ke GCM, yang kemudian diubah ke format stanza (pesan XMPP) oleh GCM. Kemudian stanza ini diteruskan ke server yang kita buat untuk kemudian mengirimkannya balik ke GCM (setelah melalui proses autentikasi, retry jika error koneksi, device tujuan dll.). Setelah itu GCM kemudian mengirim notifikasi ke handphone tujuan. Jadi kita terlebih dahulu harus membuat server sendiri dan mengintegrasikannya dengan GCM.

      Suka

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout /  Ubah )

Foto Google

You are commenting using your Google account. Logout /  Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout /  Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout /  Ubah )

Connecting to %s