1. open android studio and make new project.
2. create 4 folder under your package. "activity", "app", "gcm", "helper"
3. open file gradle under app, and paste this code. so, sync this project
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:design:23.1.1'
compile 'com.mcxiaoke.volley:library-aar:1.0.0'
compile 'com.android.support:recyclerview-v7:23.1.1'
3. move MainActivity.java to activity package.4. create Config.java, and paste this code
public class Config {
// flag to identify whether to show single line
// or multi line text in push notification tray
public static boolean appendNotificationMessages = true;
// global topic to receive app wide push notifications
public static final String TOPIC_GLOBAL = "global";
// broadcast receiver intent filters
public static final String SENT_TOKEN_TO_SERVER = "sentTokenToServer";
public static final String REGISTRATION_COMPLETE = "registrationComplete";
public static final String PUSH_NOTIFICATION = "pushNotification";
// type of push messages
public static final int PUSH_TYPE_CHATROOM = 1;
public static final int PUSH_TYPE_USER = 2;
// id to handle the notification in the notification try
public static final int NOTIFICATION_ID = 100;
public static final int NOTIFICATION_ID_BIG_IMAGE = 101;
}
5. create MyApplication under app directory, and paste this codepublic class MyApplication extends Application { public static final String TAG = MyApplication.class .getSimpleName(); private static MyApplication mInstance; private MyPreferenceManager pref; @Override public void onCreate() { super.onCreate(); mInstance = this; } public static synchronized MyApplication getInstance() { return mInstance; } public MyPreferenceManager getPrefManager() { if (pref == null) { pref = new MyPreferenceManager(this); } return pref; } }
6. create NotificationUtils.java and paste this code
public class NotificationUtils {
private static String TAG = NotificationUtils.class.getSimpleName();
private Context mContext;
public NotificationUtils() {
}
public NotificationUtils(Context mContext) {
this.mContext = mContext;
}
public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
showNotificationMessage(title, message, timeStamp, intent, null);
}
public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
// Check for empty push message
if (TextUtils.isEmpty(message))
return;
// notification icon
final int icon = R.mipmap.ic_launcher;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + mContext.getPackageName() + "/raw/notification");
if (!TextUtils.isEmpty(imageUrl)) {
if (imageUrl != null && imageUrl.length() > 4 && Patterns.WEB_URL.matcher(imageUrl).matches()) {
Bitmap bitmap = getBitmapFromURL(imageUrl);
if (bitmap != null) {
showBigNotification(bitmap, mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
} else {
showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
}
}
} else {
showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
playNotificationSound();
}
}
private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
if (Config.appendNotificationMessages) {
// store the notification in shared pref first
MyApplication.getInstance().getPrefManager().addNotification(message);
// get the notifications from shared preferences
String oldNotification = MyApplication.getInstance().getPrefManager().getNotifications();
List<String> messages = Arrays.asList(oldNotification.split("\\|"));
for (int i = messages.size() - 1; i >= 0; i--) {
inboxStyle.addLine(messages.get(i));
}
} else {
inboxStyle.addLine(message);
}
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(inboxStyle)
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Config.NOTIFICATION_ID, notification);
}
private void showBigNotification(Bitmap bitmap, NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
bigPictureStyle.setBigContentTitle(title);
bigPictureStyle.setSummaryText(Html.fromHtml(message).toString());
bigPictureStyle.bigPicture(bitmap);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(bigPictureStyle)
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Config.NOTIFICATION_ID_BIG_IMAGE, notification);
}
/**
* Downloading push notification image before displaying it in
* the notification tray
*/
public Bitmap getBitmapFromURL(String strURL) {
try {
URL url = new URL(strURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
// Playing notification sound
public void playNotificationSound() {
try {
Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + MyApplication.getInstance().getApplicationContext().getPackageName() + "/raw/notification");
Ringtone r = RingtoneManager.getRingtone(MyApplication.getInstance().getApplicationContext(), alarmSound);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Method checks if the app is in background or not
*/
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;
}
// Clears notification tray messages
public static void clearNotifications() {
NotificationManager notificationManager = (NotificationManager) MyApplication.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
public static long getTimeMilliSec(String timeStamp) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = format.parse(timeStamp);
return date.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
}
public class MyInstanceIDListenerService extends InstanceIDListenerService { private static final String TAG = MyInstanceIDListenerService.class.getSimpleName(); /** * Called if InstanceID token is updated. This may occur if the security of * the previous token had been compromised. This call is initiated by the * InstanceID provider. */ @Override public void onTokenRefresh() { Log.e(TAG, "onTokenRefresh"); // Fetch updated Instance ID token and notify our app's server of any changes (if applicable). Intent intent = new Intent(this, GcmIntentService.class); startService(intent); } }
8. create MyGcmPushReceiver.java and paste this code
public class MyGcmPushReceiver extends GcmListenerService { private static final String TAG = MyGcmPushReceiver.class.getSimpleName(); private NotificationUtils notificationUtils; /** * Called when message is received. * * @param from SenderID of the sender. * @param bundle Data bundle containing message data as key/value pairs. * For Set of keys use data.keySet(). */ @Override public void onMessageReceived(String from, Bundle bundle) { String title = bundle.getString("title"); String message = bundle.getString("message"); String image = bundle.getString("image"); String timestamp = bundle.getString("created_at"); Log.e(TAG, "From: " + from); Log.e(TAG, "Title: " + title); Log.e(TAG, "message: " + message); Log.e(TAG, "image: " + image); Log.e(TAG, "timestamp: " + timestamp); if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) { // app is in foreground, broadcast the push message Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION); pushNotification.putExtra("message", message); LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification); // play notification sound NotificationUtils notificationUtils = new NotificationUtils(); notificationUtils.playNotificationSound(); } else { Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class); resultIntent.putExtra("message", message); if (TextUtils.isEmpty(image)) { showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent); } else { showNotificationMessageWithBigImage(getApplicationContext(), title, message, timestamp, resultIntent, image); } } } /** * Showing notification with text only */ private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) { notificationUtils = new NotificationUtils(context); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); notificationUtils.showNotificationMessage(title, message, timeStamp, intent); } /** * Showing notification with text and image */ private void showNotificationMessageWithBigImage(Context context, String title, String message, String timeStamp, Intent intent, String imageUrl) { notificationUtils = new NotificationUtils(context); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl); } }
9. create GcmIntentService.java under gcm package and paste this code
public class GcmIntentService extends IntentService { private static final String TAG = GcmIntentService.class.getSimpleName(); public GcmIntentService() { super(TAG); } public static final String KEY = "key"; public static final String TOPIC = "topic"; public static final String SUBSCRIBE = "subscribe"; public static final String UNSUBSCRIBE = "unsubscribe"; @Override protected void onHandleIntent(Intent intent) { String key = intent.getStringExtra(KEY); switch (key) { case SUBSCRIBE: // subscribe to a topic String topic = intent.getStringExtra(TOPIC); subscribeToTopic(topic); break; case UNSUBSCRIBE: String topic1 = intent.getStringExtra(TOPIC); unsubscribeFromTopic(topic1); break; default: // if key is not specified, register with GCM registerGCM(); } } /** * Registering with GCM and obtaining the gcm registration id */ private void registerGCM() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); String token = null; try { InstanceID instanceID = InstanceID.getInstance(this); token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); Log.e(TAG, "GCM Registration Token: " + token); // sending the registration id to our server sendRegistrationToServer(token); sharedPreferences.edit().putBoolean(Config.SENT_TOKEN_TO_SERVER, true).apply(); } catch (Exception e) { Log.e(TAG, "Failed to complete token refresh", e); sharedPreferences.edit().putBoolean(Config.SENT_TOKEN_TO_SERVER, false).apply(); } // Notify UI that registration has completed, so the progress indicator can be hidden. Intent registrationComplete = new Intent(Config.REGISTRATION_COMPLETE); registrationComplete.putExtra("token", token); LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete); } private void sendRegistrationToServer(final String token) { // Send the registration token to our server // to keep it in MySQL } /** * Subscribe to a topic */ public void subscribeToTopic(String topic) { GcmPubSub pubSub = GcmPubSub.getInstance(getApplicationContext()); InstanceID instanceID = InstanceID.getInstance(getApplicationContext()); String token = null; try { token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); if (token != null) { pubSub.subscribe(token, "/topics/" + topic, null); Log.e(TAG, "Subscribed to topic: " + topic); } else { Log.e(TAG, "error: gcm registration id is null"); } } catch (IOException e) { Log.e(TAG, "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage()); Toast.makeText(getApplicationContext(), "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); } } public void unsubscribeFromTopic(String topic) { GcmPubSub pubSub = GcmPubSub.getInstance(getApplicationContext()); InstanceID instanceID = InstanceID.getInstance(getApplicationContext()); String token = null; try { token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); if (token != null) { pubSub.unsubscribe(token, ""); Log.e(TAG, "Unsubscribed from topic: " + topic); } else { Log.e(TAG, "error: gcm registration id is null"); } } catch (IOException e) { Log.e(TAG, "Topic unsubscribe error. Topic: " + topic + ", error: " + e.getMessage()); Toast.makeText(getApplicationContext(), "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); } } }
10. MyPreferenceManager.java under helper folder and paste this code
public class MyPreferenceManager { private String TAG = MyPreferenceManager.class.getSimpleName(); // Shared Preferences SharedPreferences pref; // Editor for Shared preferences SharedPreferences.Editor editor; // Context Context _context; // Shared pref mode int PRIVATE_MODE = 0; // Sharedpref file name private static final String PREF_NAME = "androidhive_gcm"; // All Shared Preferences Keys private static final String KEY_USER_ID = "user_id"; private static final String KEY_USER_NAME = "user_name"; private static final String KEY_USER_EMAIL = "user_email"; private static final String KEY_NOTIFICATIONS = "notifications"; // Constructor public MyPreferenceManager(Context context) { this._context = context; pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE); editor = pref.edit(); } public void addNotification(String notification) { // get old notifications String oldNotifications = getNotifications(); if (oldNotifications != null) { oldNotifications += "|" + notification; } else { oldNotifications = notification; } editor.putString(KEY_NOTIFICATIONS, oldNotifications); editor.commit(); } public String getNotifications() { return pref.getString(KEY_NOTIFICATIONS, null); } public void clear() { editor.clear(); editor.commit(); } }
11. open Manifests.xml, and configure until same whit this code
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ipb.iot.ardhi.skripsian"> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="android.permission.INTERNET" /> <!-- needed for older devices - used to check app background / foreground status --> <uses-permission android:name="android.permission.GET_TASKS" /> <!-- START Added for GCM --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <permission android:name="ipb.iot.ardhi.skripsian.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="ipb.iot.ardhi.skripsian.permission.C2D_MESSAGE" /> <!-- END Added for GCM --> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:name=".app.MyApplication" android:theme="@style/AppTheme"> <activity android:name=".activity.MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- START Added for GCM --> <receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="ipb.iot.ardhi.skripsian" /> </intent-filter> </receiver> <service android:name=".gcm.MyGcmPushReceiver" android:exported="false"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> </intent-filter> </service> <service android:name=".gcm.GcmIntentService" android:exported="false"> <intent-filter> <action android:name="com.google.android.gms.iid.InstanceID" /> </intent-filter> </service> <!-- END Added for GCM --> </application> </manifest>
12. style.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
</resources>
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout 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" tools:context=".activity.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_height="wrap_content" android:layout_width="match_parent" 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> <!--<include layout="@layout/content_main"/>--> </android.support.design.widget.CoordinatorLayout>
14. run this project to your phone
15. you will get token number
16. open rest client in chrome
17. Click send
18. in your phone you will get this
19. you have to what that do with this code. hehe
until on it this tutorial, i will write another tutorial how to handle notification to change activity to our application.
ref:http://www.androidhive.info/2016/02/android-push-notifications-using-gcm-php-mysql-realtime-chat-app-part-2
No comments:
Post a Comment