aboutsummaryrefslogtreecommitdiff
path: root/androidApp/src
diff options
context:
space:
mode:
Diffstat (limited to 'androidApp/src')
-rw-r--r--androidApp/src/google/AndroidManifest.xml28
-rw-r--r--androidApp/src/google/java/GoogleMainApplication.kt62
-rw-r--r--androidApp/src/google/java/ManagerMessagingService.kt54
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt2
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt38
-rw-r--r--androidApp/src/main/res/drawable/icon_notify.xml28
-rw-r--r--androidApp/src/main/res/values/strings.xml3
7 files changed, 213 insertions, 2 deletions
diff --git a/androidApp/src/google/AndroidManifest.xml b/androidApp/src/google/AndroidManifest.xml
new file mode 100644
index 0000000..f7aea6c
--- /dev/null
+++ b/androidApp/src/google/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="mx.trackermap.TrackerMap.android">
+
+ <application
+ android:name=".GoogleMainApplication"
+ tools:replace="android:name"
+ tools:ignore="GoogleAppIndexingWarning">
+
+ <meta-data
+ android:name="com.google.firebase.messaging.default_notification_channel_id"
+ android:value="@string/notification_channel_id" />
+
+ <meta-data
+ android:name="com.google.firebase.messaging.default_notification_icon"
+ android:resource="@drawable/icon_notify" />
+
+ <service android:exported="false" android:name=".ManagerMessagingService">
+ <intent-filter>
+ <action android:name="com.google.firebase.MESSAGING_EVENT" />
+ </intent-filter>
+ </service>
+
+ </application>
+
+</manifest>
diff --git a/androidApp/src/google/java/GoogleMainApplication.kt b/androidApp/src/google/java/GoogleMainApplication.kt
new file mode 100644
index 0000000..96062e1
--- /dev/null
+++ b/androidApp/src/google/java/GoogleMainApplication.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017 - 2021 Anton Tananaev (anton.tananaev@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package mx.trackermap.TrackerMap.android
+
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.Build
+import androidx.localbroadcastmanager.content.LocalBroadcastManager
+import com.google.firebase.messaging.FirebaseMessaging
+import kotlinx.coroutines.DelicateCoroutinesApi
+import mx.trackermap.TrackerMap.android.session.LoginFragment
+
+@DelicateCoroutinesApi
+class GoogleMainApplication : TrackerApp() {
+
+ override fun onCreate() {
+ super.onCreate()
+ val intentFilter = IntentFilter(LoginFragment.EVENT_LOGIN)
+ LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, intentFilter)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val channel = NotificationChannel(
+ getString(R.string.notification_channel_id),
+ getString(R.string.notification_channel),
+ NotificationManager.IMPORTANCE_DEFAULT
+ )
+ (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(channel)
+ }
+ }
+
+ private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ FirebaseMessaging.getInstance().token.addOnCompleteListener {
+ if (it.isSuccessful) {
+ broadcastToken(it.result)
+ }
+ }
+ }
+ }
+
+ fun broadcastToken(token: String?) {
+ val intent = Intent(LoginFragment.EVENT_TOKEN)
+ intent.putExtra(LoginFragment.KEY_TOKEN, token)
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
+ }
+}
diff --git a/androidApp/src/google/java/ManagerMessagingService.kt b/androidApp/src/google/java/ManagerMessagingService.kt
new file mode 100644
index 0000000..b10475f
--- /dev/null
+++ b/androidApp/src/google/java/ManagerMessagingService.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 - 2021 Anton Tananaev (anton.tananaev@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package mx.trackermap.TrackerMap.android
+
+import android.annotation.SuppressLint
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.Intent
+import android.os.Build
+import androidx.core.app.NotificationCompat
+import com.google.firebase.messaging.FirebaseMessagingService
+import com.google.firebase.messaging.RemoteMessage
+import kotlinx.coroutines.DelicateCoroutinesApi
+import mx.trackermap.TrackerMap.android.units.UnitsActivity
+
+@DelicateCoroutinesApi
+class ManagerMessagingService : FirebaseMessagingService() {
+
+ @SuppressLint("UnspecifiedImmutableFlag")
+ override fun onMessageReceived(remoteMessage: RemoteMessage) {
+ super.onMessageReceived(remoteMessage)
+ val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
+ } else {
+ PendingIntent.FLAG_ONE_SHOT
+ }
+ val pendingIntent = PendingIntent.getActivity(this, 0, Intent(this, UnitsActivity::class.java), flags)
+ val builder = NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
+ .setSmallIcon(R.drawable.icon_notify)
+ .setContentTitle(getString(R.string.app_name))
+ .setContentText(remoteMessage.notification?.body)
+ .setAutoCancel(true)
+ .setContentIntent(pendingIntent)
+ (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).notify(remoteMessage.hashCode(), builder.build())
+ }
+
+ override fun onNewToken(token: String) {
+ super.onNewToken(token)
+ (application as GoogleMainApplication).broadcastToken(token)
+ }
+}
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt
index cdb7102..4cbf8e5 100644
--- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt
@@ -19,7 +19,7 @@ import org.koin.core.logger.Level
import org.koin.dsl.module
@DelicateCoroutinesApi
-class TrackerApp : Application() {
+open class TrackerApp : Application() {
override fun onCreate() {
super.onCreate()
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt
index 674c2d3..185a444 100644
--- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/LoginFragment.kt
@@ -1,6 +1,6 @@
package mx.trackermap.TrackerMap.android.session
-import android.content.Intent
+import android.content.*
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@@ -9,6 +9,8 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.Fragment
+import androidx.localbroadcastmanager.content.LocalBroadcastManager
+import androidx.preference.PreferenceManager
import com.zhuinden.liveevent.observe
import kotlinx.coroutines.DelicateCoroutinesApi
import mx.trackermap.TrackerMap.android.databinding.LoginBinding
@@ -20,6 +22,7 @@ class LoginFragment : Fragment() {
private var _binding: LoginBinding? = null
private val binding get() = _binding!!
private val loginViewModel: LoginViewModel by viewModel()
+ private lateinit var broadcastManager: LocalBroadcastManager
override fun onCreateView(
inflater: LayoutInflater,
@@ -35,9 +38,21 @@ class LoginFragment : Fragment() {
setupEvents()
setupObservers()
+ broadcastManager = LocalBroadcastManager.getInstance(activity!!)
loginViewModel.restoreSession()
}
+ override fun onStart() {
+ super.onStart()
+ val intentFilter = IntentFilter(EVENT_TOKEN)
+ broadcastManager.registerReceiver(broadcastReceiver, intentFilter)
+ }
+
+ override fun onStop() {
+ super.onStop()
+ broadcastManager.unregisterReceiver(broadcastReceiver)
+ }
+
override fun onDestroyView() {
super.onDestroyView()
_binding = null
@@ -72,6 +87,7 @@ class LoginFragment : Fragment() {
Toast.makeText(context, "Failed login", Toast.LENGTH_SHORT).show()
}
LoginViewModel.LoginState.Success -> {
+ broadcastManager.sendBroadcast(Intent(EVENT_LOGIN))
val activity = requireActivity()
val intent = Intent(activity.applicationContext, UnitsActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
@@ -81,4 +97,24 @@ class LoginFragment : Fragment() {
}
}
}
+
+ private val broadcastReceiver = object : BroadcastReceiver() {
+ override fun onReceive(p0: Context?, p1: Intent?) {
+ p1?.getStringExtra(KEY_TOKEN)?.let { token ->
+ PreferenceManager
+ .getDefaultSharedPreferences(activity)
+ .edit()
+ .putString(PREFERENCE_TOKEN, token)
+ .apply()
+ }
+ }
+ }
+
+ companion object {
+ const val EVENT_LOGIN = "eventLogin"
+ const val EVENT_TOKEN = "eventToken"
+ const val KEY_TOKEN = "keyToken"
+
+ const val PREFERENCE_TOKEN = "token"
+ }
} \ No newline at end of file
diff --git a/androidApp/src/main/res/drawable/icon_notify.xml b/androidApp/src/main/res/drawable/icon_notify.xml
new file mode 100644
index 0000000..c92915e
--- /dev/null
+++ b/androidApp/src/main/res/drawable/icon_notify.xml
@@ -0,0 +1,28 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="31.75"
+ android:viewportHeight="31.75">
+ <path
+ android:pathData="m16.7714,15.5323c5.3724,1.0493 7.469,14.6249 7.469,14.6249 0,0 -0.3949,-10.5539 -8.531,-11.6354 -6.4938,-0.8632 -11.1417,7.5606 -11.1417,7.5606 0,0 6.9261,-11.581 12.2037,-10.5502z"
+ android:strokeLineJoin="bevel"
+ android:strokeWidth="1.8058915"
+ android:fillColor="#ff3232"
+ android:strokeColor="#ff3232"
+ android:strokeLineCap="butt"/>
+ <path
+ android:pathData="m18.261,8.9784c5.3724,1.0493 7.469,14.6249 7.469,14.6249 0,0 -0.3949,-10.5539 -8.531,-11.6354 -6.4938,-0.8632 -11.1417,7.5606 -11.1417,7.5606 0,0 6.9261,-11.581 12.2037,-10.5502z"
+ android:strokeLineJoin="bevel"
+ android:strokeWidth="1.8058915"
+ android:fillColor="#ff3232"
+ android:strokeColor="#ff3232"
+ android:strokeLineCap="butt"/>
+ <path
+ android:pathData="m19.6015,2.4245c5.3724,1.0493 7.469,14.6249 7.469,14.6249 0,0 -0.3949,-10.5539 -8.531,-11.6354 -6.4938,-0.8632 -11.1417,7.5606 -11.1417,7.5606 0,0 6.9261,-11.581 12.2037,-10.5502z"
+ android:strokeLineJoin="bevel"
+ android:strokeWidth="1.8058915"
+ android:fillColor="#ff3232"
+ android:strokeColor="#ff3232"
+ android:strokeLineCap="butt"/>
+</vector>
diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml
index b8080f5..5f39ce1 100644
--- a/androidApp/src/main/res/values/strings.xml
+++ b/androidApp/src/main/res/values/strings.xml
@@ -20,6 +20,9 @@
https://mt0.google.com/vt/lyrs=y&amp;hl=en&amp;x={x}&amp;y={y}&amp;z={z}&amp;s=Ga
</string>
+ <string name="notification_channel_id" translatable="false">default</string>
+ <string name="notification_channel" translatable="false">Default</string>
+
<!-- LoginActivity -->
<string name="login_username">Username</string>
<string name="login_password">Password</string>