commit a136f1945830e5e15ecd8ff1edd166680381639c Author: Jirawat Karanwittayakarn Date: Wed Jun 22 18:58:32 2016 +0700 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07286ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +#built application files +*.apk +*.ap_ + +# files for the dex VM +*.dex + +# Java class files +*.class + +# generated files +bin/ +gen/ +out/ + +# Local configuration file (sdk path, etc) +local.properties + +# Windows thumbnail db +Thumbs.db + +# OSX files +.DS_Store + +# Log Files +*.log + +# Android Studio +*.iml +.gradle/ +build/ +captures/ +.navigation/ + +# Intellij IDEA +.idea/ + +# Eclipse project files +.classpath +.project + +# Proguard folder generated by Eclipse +proguard/ + +# Eclipse Metadata +.metadata/ + +# Keystore files +*.jks \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..bcd3bfc --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,33 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 24 + buildToolsVersion "24.0.0" + + defaultConfig { + applicationId "com.example.fcm" + minSdkVersion 16 + targetSdkVersion 24 + versionCode 1 + versionName "1.0" + } + + dexOptions { + incremental true + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:24.0.0' + compile 'com.google.firebase:firebase-messaging:9.0.2' +} + +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..178771a --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "50179465152", + "firebase_url": "https://jirawatee.firebaseio.com", + "project_id": "jirawatee", + "storage_bucket": "jirawatee.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:50179465152:android:94f0681dc821f130", + "android_client_info": { + "package_name": "com.example.fcm" + } + }, + "oauth_client": [ + { + "client_id": "50179465152-uk1oku2q1lifhmoghsmqaqhvcmb2esuk.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDcBjPTACpgYUmPJfcMImnUcJ_VJkCbNyM" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..13afac4 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/Jirawatee/Documents/android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/example/fcm/ApplicationTest.java b/app/src/androidTest/java/com/example/fcm/ApplicationTest.java new file mode 100644 index 0000000..8b76465 --- /dev/null +++ b/app/src/androidTest/java/com/example/fcm/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.example.fcm; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a2b198d --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/fcm/MainActivity.java b/app/src/main/java/com/example/fcm/MainActivity.java new file mode 100644 index 0000000..d256276 --- /dev/null +++ b/app/src/main/java/com/example/fcm/MainActivity.java @@ -0,0 +1,122 @@ +package com.example.fcm; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; + +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.messaging.FirebaseMessaging; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Scanner; + +public class MainActivity extends AppCompatActivity { + private static final String AUTH_KEY = "key=YOUR KEY SERVER"; + private static final String TAG = "MainActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Bundle bundle = getIntent().getExtras(); + + if (bundle != null) { + for (String key : bundle.keySet()) { + Object value = bundle.get(key); + Log.d(TAG, "Key: " + key + " Value: " + value.toString()); + } + } + + findViewById(R.id.subscribeButton).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FirebaseMessaging.getInstance().subscribeToTopic("news"); + Log.d(TAG, "Subscribed to news topic"); + } + }); + + findViewById(R.id.logTokenButton).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, "InstanceID token: " + FirebaseInstanceId.getInstance().getToken()); + } + }); + + findViewById(R.id.send).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new Thread(new Runnable() { + @Override + public void run() { + pushNotification(FirebaseInstanceId.getInstance().getToken()); + } + }).start(); + } + }); + } + + private void pushNotification(String token) { + JSONObject jPayload = new JSONObject(); + JSONObject jNotification = new JSONObject(); + JSONObject jData = new JSONObject(); + try { + jNotification.put("title", "Google I/O 2016"); + jNotification.put("text", "Firebase Cloud Messaging (App)"); + jNotification.put("sound", "default"); + jNotification.put("badge", "1"); + jNotification.put("click_action", "OPEN_ACTIVITY_1"); + + jData.put("picture_url", "http://opsbug.com/static/google-io.jpg"); + + jPayload.put("to", token); + //jPayload.put("to", "/topics/news"); + //jPayload.put("condition", "'logined' in topics || 'news' in topics"); + //jPayload.put("registration_ids", jData); + jPayload.put("priority", "high"); + jPayload.put("notification", jNotification); + jPayload.put("data", jData); + + URL url = new URL("https://fcm.googleapis.com/fcm/send"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Authorization", AUTH_KEY); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setDoOutput(true); + + // Send FCM message content. + OutputStream outputStream = conn.getOutputStream(); + outputStream.write(jPayload.toString().getBytes()); + + // Read FCM response. + InputStream inputStream = conn.getInputStream(); + final String resp = convertStreamToString(inputStream); + + Handler h = new Handler(Looper.getMainLooper()); + h.post(new Runnable() { + @Override + public void run() { + Log.e("Response", resp); + //txtStatus.setText(resp); + } + }); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + } + + private String convertStreamToString(InputStream is) { + Scanner s = new Scanner(is).useDelimiter("\\A"); + return s.hasNext() ? s.next().replace(",", ",\n") : ""; + } +} diff --git a/app/src/main/java/com/example/fcm/MyFirebaseInstanceIDService.java b/app/src/main/java/com/example/fcm/MyFirebaseInstanceIDService.java new file mode 100644 index 0000000..2d2b95d --- /dev/null +++ b/app/src/main/java/com/example/fcm/MyFirebaseInstanceIDService.java @@ -0,0 +1,32 @@ +package com.example.fcm; + +import android.util.Log; + +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.FirebaseInstanceIdService; + +public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { + private static final String TAG = "MyFirebaseIIDService"; + + @Override + public void onTokenRefresh() { + super.onTokenRefresh(); + + String refreshedToken = FirebaseInstanceId.getInstance().getToken(); + Log.d(TAG, "Refreshed token: " + refreshedToken); + + sendRegistrationToServer(refreshedToken); + } + + private void sendRegistrationToServer(String token) { + // Add custom implementation, as needed. + } + + /* + The token may be rotated whenever: + 1. The app deletes Instance ID + 2. The app is restored on a new device + 3. The user uninstalls/reinstall the app + 4. The user clears app data. + */ +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fcm/MyFirebaseMessagingService.java b/app/src/main/java/com/example/fcm/MyFirebaseMessagingService.java new file mode 100644 index 0000000..0bd540b --- /dev/null +++ b/app/src/main/java/com/example/fcm/MyFirebaseMessagingService.java @@ -0,0 +1,70 @@ +package com.example.fcm; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.media.RingtoneManager; +import android.support.v4.app.NotificationCompat; + +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; + +import java.io.IOException; +import java.net.URL; +import java.util.Map; + +public class MyFirebaseMessagingService extends FirebaseMessagingService { + @Override + public void onMessageReceived(RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + + // If the application is in the foreground handle both data and notification messages here. + // Also if you intend on generating your own notifications as a result of a received FCM + // message, here is where that should be initiated. See sendNotification method below. + + RemoteMessage.Notification notification = remoteMessage.getNotification(); + Map map = remoteMessage.getData(); + + sendNotification(notification.getTitle(), notification.getBody(), map); + } + + private void sendNotification(String title, String body, Map map) { + Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); + + Intent intent = new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); + + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) + .setContentTitle(title) + .setContentText(body) + .setAutoCancel(true) + .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) + .setContentIntent(pendingIntent) + .setContentInfo(title) + .setLargeIcon(icon) + .setSmallIcon(R.mipmap.ic_launcher); + + try { + String picture_url = map.get("picture_url"); + if (picture_url != null && !"".equals(picture_url)) { + URL url = new URL(picture_url); + Bitmap bigPicture = BitmapFactory.decodeStream(url.openConnection().getInputStream()); + notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(bigPicture).setSummaryText(body)); + } + } catch (IOException e) { + e.printStackTrace(); + } + + notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE); + notificationBuilder.setLights(Color.YELLOW, 1000, 300); + + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(0, notificationBuilder.build()); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/fcm/SecondActivity.java b/app/src/main/java/com/example/fcm/SecondActivity.java new file mode 100644 index 0000000..f828e6f --- /dev/null +++ b/app/src/main/java/com/example/fcm/SecondActivity.java @@ -0,0 +1,24 @@ +package com.example.fcm; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; + +public class SecondActivity extends AppCompatActivity { + private static final String TAG = "SecondActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_second); + + Bundle bundle = getIntent().getExtras(); + + if (bundle != null) { + for (String key : bundle.keySet()) { + Object value = bundle.get(key); + Log.d(TAG, "Key: " + key + " Value: " + value.toString()); + } + } + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..00a3daa --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,45 @@ + + + + + + + +