diff --git a/android/app/build.gradle b/android/app/build.gradle index 451b93955ea8ee0de9da610ffe0dd59f04e0dbbc..9c38f4fd9cca1e44a5a2cac2103f8f1318723e90 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -27,8 +27,9 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' - implementation 'com.google.firebase:firebase-core:16.0.6' + implementation 'com.google.firebase:firebase-core:16.0.7' implementation 'com.google.firebase:firebase-database:16.0.6' + implementation 'com.google.firebase:firebase-messaging:17.4.0' implementation 'com.github.bumptech.glide:glide:4.9.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0' implementation 'de.hdodenhof:circleimageview:3.0.0' diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a6afddc2d7a9fe14cb6be792b89a7865768700fc..25becf504cecf68fd653042db4d43bf9f8765b36 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,21 +9,41 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> + <!-- <service --> + <!-- android:name=".service.PushNotificationService" --> + <!-- android:enabled="true" --> + <!-- android:exported="true"/> --> + <!-- + Set custom default icon. This is used when no icon is set for incoming notification messages. + See README(https://goo.gl/l4GJaQ) for more. + --> + <!-- <meta-data --> + <!-- android:name="com.google.firebase.messaging.default_notification_icon" --> + <!-- android:resource="@drawable/logo" /> --> + <!-- <!– Set color used with incoming notification messages. This is used when no color is set for the incoming --> + <!-- notification message. See README(https://goo.gl/6BKBk7) for more. –> --> + <!-- <meta-data --> + <!-- android:name="com.google.firebase.messaging.default_notification_color" --> + <!-- android:resource="@color/colorAccent" /> --> + <service android:name=".service.PushNotificationService"> + <intent-filter> + <action android:name="com.google.firebase.MESSAGING_EVENT" /> + </intent-filter> + </service> + <activity android:name=".MainActivity" android:label="@string/app_name" - android:theme="@style/AppTheme.NoActionBar"> - </activity> - + android:theme="@style/AppTheme.NoActionBar" /> <activity android:name=".AuthActivity" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - </application> </manifest> \ No newline at end of file diff --git a/android/app/src/main/java/com/chatman/AuthActivity.java b/android/app/src/main/java/com/chatman/AuthActivity.java index 894c3d93f2544f8151a9848968ff158f8fe64fd2..00fe30d56838e03e4b3d4437e661b79593c78969 100644 --- a/android/app/src/main/java/com/chatman/AuthActivity.java +++ b/android/app/src/main/java/com/chatman/AuthActivity.java @@ -22,6 +22,7 @@ import com.chatman.helper.PreferencesHelper; import com.chatman.model.User; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; +import com.google.firebase.FirebaseApp; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.ValueEventListener; diff --git a/android/app/src/main/java/com/chatman/BotFragment.java b/android/app/src/main/java/com/chatman/BotFragment.java index 254883abd9dc124eea6f5391a9f1d04515b10f4e..335c477001b5261012790647e55fe892a18eef8d 100644 --- a/android/app/src/main/java/com/chatman/BotFragment.java +++ b/android/app/src/main/java/com/chatman/BotFragment.java @@ -1,12 +1,15 @@ package com.chatman; import android.content.Context; +import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; /** @@ -41,7 +44,8 @@ public class BotFragment extends Fragment { Bundle savedInstanceState) { // Inflate the layout for this fragment - return inflater.inflate(R.layout.fragment_bot, container, false); + View view = inflater.inflate(R.layout.fragment_bot, container, false); + return view; } public void onButtonPressed(Uri uri) { diff --git a/android/app/src/main/java/com/chatman/MainActivity.java b/android/app/src/main/java/com/chatman/MainActivity.java index a3bbfaa6982c82732e7a08e3c9f7785bc746b63c..8b39b3bd351d6dfa1b4ced4a50807624c4a31cf4 100644 --- a/android/app/src/main/java/com/chatman/MainActivity.java +++ b/android/app/src/main/java/com/chatman/MainActivity.java @@ -1,17 +1,24 @@ package com.chatman; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.media.RingtoneManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.BottomNavigationView; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; +import android.support.v4.app.NotificationCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.View; import android.support.design.widget.NavigationView; import android.support.v4.view.GravityCompat; @@ -25,8 +32,14 @@ import android.widget.ImageView; import com.bumptech.glide.Glide; import com.chatman.adapter.ChatListAdapter; +import com.chatman.helper.FirebaseHelper; import com.chatman.helper.PreferencesHelper; import com.chatman.model.ChatList; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.FirebaseApp; +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.InstanceIdResult; import java.util.ArrayList; import java.util.Date; @@ -53,7 +66,6 @@ public class MainActivity extends AppCompatActivity implements case R.id.navigation_bot: loadFragment(new BotFragment()); break; } - return true; } }; @@ -69,6 +81,9 @@ public class MainActivity extends AppCompatActivity implements setSupportActionBar(toolbar); context = this; + FirebaseHelper.dbUser.child(PreferencesHelper.getUserFirebaseKey(this)).child("key").setValue(PreferencesHelper.getToken(this)); + + // Bottom Navigation Bar bottomNavbar = findViewById(R.id.navigation); bottomNavbar.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); diff --git a/android/app/src/main/java/com/chatman/helper/PreferencesHelper.java b/android/app/src/main/java/com/chatman/helper/PreferencesHelper.java index cb40a7370a4bc3192da96ef830d0d592f482bf0d..ad0608739f20ec2396251add9a961b0cc2c6bf77 100644 --- a/android/app/src/main/java/com/chatman/helper/PreferencesHelper.java +++ b/android/app/src/main/java/com/chatman/helper/PreferencesHelper.java @@ -9,6 +9,7 @@ public class PreferencesHelper { public static final String USER_FIREBASE_KEY = "user_firebase_key"; public static final String USER_NAME = "user_name"; public static final String HAS_LOGIN = "has_login"; + public static final String TOKEN= "token"; private static void setBooleanPreferences(Context context, String key, boolean value) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); @@ -71,4 +72,12 @@ public class PreferencesHelper { return getBooleanPreferences(context, HAS_LOGIN); } + public static void setToken(Context context, String string) { + setStringPreferences(context, TOKEN, string); + } + + public static String getToken(Context context) { + return getStringPreferences(context, TOKEN); + } + } diff --git a/android/app/src/main/java/com/chatman/service/PushNotificationService.java b/android/app/src/main/java/com/chatman/service/PushNotificationService.java new file mode 100644 index 0000000000000000000000000000000000000000..4d73cbf329c44fc329a3385a35e347c8ddf2f26f --- /dev/null +++ b/android/app/src/main/java/com/chatman/service/PushNotificationService.java @@ -0,0 +1,98 @@ +package com.chatman.service; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Build; +import android.os.IBinder; +import android.support.v4.app.NotificationCompat; +import android.util.Log; + +import com.chatman.MainActivity; +import com.chatman.R; +import com.chatman.helper.FirebaseHelper; +import com.chatman.helper.PreferencesHelper; +import com.google.firebase.FirebaseApp; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; + +public class PushNotificationService extends FirebaseMessagingService { + + private static final String TAG = PushNotificationService.class.getSimpleName(); + private static final int NOTIFICATION_ID = 0; + + @Override + public void onMessageReceived(RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + Log.d(TAG, "onMessageReceived: " + remoteMessage.getData()); + Log.d(TAG, "onMessageReceived: notification body " + remoteMessage.getNotification().getBody()); + sendNotification(remoteMessage.getNotification().getBody(), remoteMessage.getNotification().getTitle()); + } + + @Override + public void onNewToken(String s) { + super.onNewToken(s); + PreferencesHelper.setToken(this, s); + Log.d(TAG, "onNewToken: " + s); + Log.d(TAG, "onNewToken: " + PreferencesHelper.getUserFirebaseKey(this)); + } + + private void sendNotification(String messageBody, String title) { + + NotificationManager mNotifyManager = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + + // Notification channels are only available in OREO and higher. + // So, add a check on SDK version. + if (android.os.Build.VERSION.SDK_INT >= + android.os.Build.VERSION_CODES.O) { + + // Create the NotificationChannel with all the parameters. + NotificationChannel notificationChannel = new NotificationChannel + (getString(R.string.default_notification_channel_id), + getString(R.string.default_notification_channel_name), + NotificationManager.IMPORTANCE_HIGH); + + notificationChannel.enableLights(true); + notificationChannel.setLightColor(Color.RED); + notificationChannel.enableVibration(true); + notificationChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), null); + notificationChannel.setDescription + (getString(R.string.notification_channel_description)); + mNotifyManager.createNotificationChannel(notificationChannel); + } + + NotificationCompat.Builder notifyBuilder = getNotificationBuilder(title, messageBody); + + mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build()); + } + + private NotificationCompat.Builder getNotificationBuilder(String title, String text) { + + // Set up the pending intent that is delivered when the notification + // is clicked. + Intent notificationIntent = new Intent(this, MainActivity.class); + PendingIntent notificationPendingIntent = PendingIntent.getActivity + (this, NOTIFICATION_ID, notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + + // Build the notification with all of the parameters. + NotificationCompat.Builder notifyBuilder = new NotificationCompat + .Builder(this, getString(R.string.default_notification_channel_id)) + .setContentTitle(title) + .setContentText(text) + .setSmallIcon(R.drawable.ic_launcher_foreground) + .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) + .setAutoCancel(true).setContentIntent(notificationPendingIntent) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setDefaults(NotificationCompat.DEFAULT_ALL); + return notifyBuilder; + } +} diff --git a/android/app/src/main/res/drawable-anydpi-v24/ic_update.xml b/android/app/src/main/res/drawable-anydpi-v24/ic_update.xml new file mode 100644 index 0000000000000000000000000000000000000000..b582d07163933dd7eb830f1ee1e98fccf4a3a3be --- /dev/null +++ b/android/app/src/main/res/drawable-anydpi-v24/ic_update.xml @@ -0,0 +1,13 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="26.086956" + android:viewportHeight="26.086956" + android:tint="#FFFFFF"> + <group android:translateX="1.0434783" + android:translateY="1.0434783"> + <path + android:fillColor="#FF000000" + android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/> + </group> +</vector> diff --git a/android/app/src/main/res/drawable-hdpi/ic_update.png b/android/app/src/main/res/drawable-hdpi/ic_update.png new file mode 100644 index 0000000000000000000000000000000000000000..43d78bdb293a268102f222a6a31940a38c527d72 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/ic_update.png differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_update.png b/android/app/src/main/res/drawable-mdpi/ic_update.png new file mode 100644 index 0000000000000000000000000000000000000000..e424146397593ac15cb9f19e25e8bb776784ad58 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/ic_update.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_update.png b/android/app/src/main/res/drawable-xhdpi/ic_update.png new file mode 100644 index 0000000000000000000000000000000000000000..e10c3a90707297f85575d694314f21a9409d6aea Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/ic_update.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_update.png b/android/app/src/main/res/drawable-xxhdpi/ic_update.png new file mode 100644 index 0000000000000000000000000000000000000000..fd75de1a80cde216b141828c2007457f1bc18594 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/ic_update.png differ diff --git a/android/app/src/main/res/layout/fragment_bot.xml b/android/app/src/main/res/layout/fragment_bot.xml index d530ae6f203fd6e89b42678291a1ad5e48838968..abf2be519d08e0c5dd395d865bd67daa4b3646ad 100644 --- a/android/app/src/main/res/layout/fragment_bot.xml +++ b/android/app/src/main/res/layout/fragment_bot.xml @@ -7,8 +7,15 @@ <!-- TODO: Update blank fragment layout --> <TextView + android:id="@+id/tv_hello" android:layout_width="match_parent" android:layout_height="match_parent" android:text="Bot fragment" /> + <Button + android:id="@+id/btn" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="tombol"/> + </FrameLayout> \ No newline at end of file diff --git a/android/app/src/main/res/layout/fragment_chat_bot.xml b/android/app/src/main/res/layout/fragment_chat_bot.xml index ba28517a12dc44df14de9166846b0e9534cc7e69..037c7383712b3d07021c9cc79fb9fc69ad1bf870 100644 --- a/android/app/src/main/res/layout/fragment_chat_bot.xml +++ b/android/app/src/main/res/layout/fragment_chat_bot.xml @@ -7,6 +7,7 @@ <!-- TODO: Update blank fragment layout --> <TextView + android:id="@+id/tv_hello" android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/hello_blank_fragment" /> diff --git a/android/app/src/main/res/values-v21/strings.xml b/android/app/src/main/res/values-v21/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..7710771fb8ee24861c56d21fc5440387fb2f3cda --- /dev/null +++ b/android/app/src/main/res/values-v21/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="notification_channel_description">Notifikasi dari chat</string> +</resources> \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index ba5a5b4cf63d82f5b95b21bbb5e563b185c3f2fc..a34e93cd269513b4edfcdf2a95fcb392da4a9e07 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -25,5 +25,21 @@ <string name="navigation_profile">Profile</string> <string name="navigation_home">Home</string> <string name="navigation_bot">Bot</string> + + <!-- Notification ID --> + <string name="default_notification_channel_id">NOTIF_MANTAP_CHATMAN</string> + <string name="default_notification_channel_name" translatable="true">Message</string> + <string name="notification_channel_description">Notifikasi dari chat</string> + + + <string name="notification_title">You\'ve been notified!</string> + <string name="notification_text">This is your notification text.</string> + <string name="update">Update Notification</string> + <string name="notify_me">Notify Me!</string> + <string name="update_me">Update Me!</string> + <string name="cancel_me">Cancel Me!</string> + <string name="notification_updated">Notification Updated!</string> + <string name="notification_channel_name">Mascot Notification</string> + </resources> diff --git a/android/build.gradle b/android/build.gradle index a031681257d46336e6e694c3157e5499ca5cab6a..dc659fc5bc608e7ac614fd84c4364ffa73c1a620 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.3.1' - classpath 'com.google.gms:google-services:4.0.1' + classpath 'com.google.gms:google-services:4.2.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }