Skip to content

Commit

Permalink
Implement push notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
tananaev committed Nov 17, 2020
1 parent e803777 commit 85b4f2f
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 12 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ buildscript {

dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.google.gms:google-services:4.2.0'
classpath 'com.google.gms:google-services:4.3.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'io.fabric.tools:gradle:1.29.0'
classpath "io.realm:realm-gradle-plugin:$realm_version"
Expand Down
10 changes: 5 additions & 5 deletions presentation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'realm-android' // Realm needs to be before Kotlin or the build will fail
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
Expand Down Expand Up @@ -187,6 +188,10 @@ dependencies {
implementation project(':data')
implementation project(':domain')

implementation platform('com.google.firebase:firebase-bom:26.1.0')
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-analytics'

withAnalyticsImplementation 'com.google.firebase:firebase-core:16.0.9'
withAnalyticsImplementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'

Expand All @@ -195,8 +200,3 @@ dependencies {
withAnalyticsDebug project(path: ':data', configuration: 'withAnalyticsDebug')
withAnalyticsRelease project(path: ':data', configuration: 'withAnalyticsRelease')
}

if (getGradle().getStartParameter().getTaskRequests().toString().contains("WithAnalytics")) {
apply plugin: 'io.fabric'
apply plugin: 'com.google.gms.google-services'
}
5 changes: 5 additions & 0 deletions presentation/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@
<activity android:name=".feature.backup.BackupActivity" />
<activity android:name=".feature.contacts.ContactsActivity" />

<service android:name=".feature.gateway.GatewayMessagingService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<receiver android:name=".receiver.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.moez.QKSMS.feature.gateway

import android.graphics.Typeface
import android.os.Bundle
import android.text.method.LinkMovementMethod
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import com.google.firebase.messaging.FirebaseMessaging
import com.jakewharton.rxbinding2.view.clicks
import com.moez.QKSMS.R
import com.moez.QKSMS.common.base.QkThemedActivity
Expand All @@ -21,6 +23,7 @@ class GatewayActivity : QkThemedActivity(), GatewayView {
@Inject lateinit var fontProvider: FontProvider
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory

override val tokenClickIntent by lazy { binding.tokenView.clicks().map { binding.tokenView.text.toString() } }
override val stateClickIntent by lazy { binding.serviceButton.clicks() }

private val binding by viewBinding(GatewayActivityBinding::inflate)
Expand All @@ -34,6 +37,9 @@ class GatewayActivity : QkThemedActivity(), GatewayView {
showBackButton(true)
viewModel.bindView(this)

binding.pushDescriptionView.movementMethod = LinkMovementMethod.getInstance()
binding.tokenView.clipToOutline = true

if (!prefs.systemFont.get()) {
fontProvider.getLato { lato ->
val typeface = Typeface.create(lato, Typeface.BOLD)
Expand All @@ -49,6 +55,10 @@ class GatewayActivity : QkThemedActivity(), GatewayView {
}

override fun render(state: GatewayState) {
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
binding.tokenView.text = task.result
}

binding.keyView.text = state.key

binding.serviceButton.setText(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.moez.QKSMS.feature.gateway

import android.annotation.SuppressLint
import android.telephony.SmsManager
import android.widget.Toast
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

@SuppressLint("MissingFirebaseInstanceTokenRefresh")
class GatewayMessagingService : FirebaseMessagingService() {

override fun onMessageReceived(remoteMessage: RemoteMessage) {
val phone = remoteMessage.data["phone"]
val message = remoteMessage.data["message"]
if (phone != null && message != null) {
try {
SmsManager.getDefault().sendTextMessage(phone, null, message, null, null)
} catch (e: Exception) {
Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import io.reactivex.Observable

interface GatewayView : QkView<GatewayState> {

val stateClickIntent: Observable<*>
val tokenClickIntent: Observable<String>

val stateClickIntent: Observable<Unit>

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.moez.QKSMS.feature.gateway

import android.content.ClipboardManager
import android.content.Context
import android.content.Context.CLIPBOARD_SERVICE
import android.content.Intent
import android.content.SharedPreferences
import android.widget.Toast
import androidx.core.content.ContextCompat
import com.moez.QKSMS.R
import com.moez.QKSMS.common.base.QkViewModel
import com.uber.autodispose.android.lifecycle.scope
import com.uber.autodispose.autoDisposable
Expand All @@ -13,6 +17,7 @@ import java.net.NetworkInterface
import java.util.*
import javax.inject.Inject


class GatewayViewModel @Inject constructor(
private val context: Context,
private val sharedPrefs: SharedPreferences
Expand All @@ -32,9 +37,19 @@ class GatewayViewModel @Inject constructor(
}
}

@Suppress("DEPRECATION")
override fun bindView(view: GatewayView) {
super.bindView(view)

val clipboard = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager?

view.tokenClickIntent
.autoDisposable(view.scope())
.subscribe {
clipboard?.text = it
Toast.makeText(context, R.string.gateway_copied_toast, Toast.LENGTH_SHORT).show()
}

view.stateClickIntent
.withLatestFrom(state.map { it.running }) { _, running -> running }
.autoDisposable(view.scope())
Expand Down
39 changes: 35 additions & 4 deletions presentation/src/main/res/layout/gateway_activity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,44 @@
android:layout_width="match_parent"
android:layout_height="56dp" />

<com.moez.QKSMS.common.widget.QkTextView
style="@style/TextPrimary"
<LinearLayout
android:id="@+id/disabledView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gateway_disabled"
android:textColor="?android:attr/textColorPrimary" />
android:orientation="vertical">

<com.moez.QKSMS.common.widget.QkTextView
style="@style/TextPrimary"
android:id="@+id/pushDescriptionView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gateway_push"
android:textColor="?android:attr/textColorPrimary" />

<Space
android:layout_width="match_parent"
android:layout_height="24dp" />

<com.moez.QKSMS.common.widget.TightTextView
style="@style/GatewayTokenTextStyle"
android:id="@+id/tokenView"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
tools:ignore="UnusedAttribute" />

<Space
android:layout_width="match_parent"
android:layout_height="56dp" />

<com.moez.QKSMS.common.widget.QkTextView
style="@style/TextPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gateway_disabled"
android:textColor="?android:attr/textColorPrimary" />

</LinearLayout>

<LinearLayout
android:id="@+id/enabledView"
Expand Down
4 changes: 3 additions & 1 deletion presentation/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
<string name="gateway_start">Start</string>
<string name="gateway_stop">Stop</string>
<string name="gateway_description">Use your phone as an SMS gateway with HTTP API access</string>
<string name="gateway_disabled">Start service using button below to enable gateway</string>
<string name="gateway_disabled">Alternatively you can start server directly on your phone using the action button below</string>
<string name="gateway_push">Use the token below to send SMS via push notifications. For more information check <a href="https://www.traccar.org/http-sms-api/">Traccar documentation</a></string>
<string name="gateway_key_label">Your API key</string>
<string name="gateway_url_label">Local API endpoints</string>
<string name="gateway_snack_title">Enable SMS gateway</string>
<string name="gateway_snack_description">Start service to enable API access</string>
<string name="gateway_snack_button">Manage</string>
<string name="gateway_copied_toast">Copied</string>

<string name="app_name" translatable="false">Traccar SMS Gateway</string>

Expand Down
15 changes: 15 additions & 0 deletions presentation/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,21 @@
<item name="android:textStyle">bold</item>
</style>

<style name="GatewayTokenTextStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">@drawable/rounded_rectangle_outline_22dp</item>
<item name="android:backgroundTint">?android:attr/divider</item>
<item name="android:gravity">center_vertical</item>
<item name="android:minHeight">44dp</item>
<item name="android:paddingBottom">12dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:paddingStart">16dp</item>
<item name="android:paddingTop">12dp</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="textSize">primary</item>
</style>

<style name="ScheduledSampleTextStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
Expand Down

0 comments on commit 85b4f2f

Please sign in to comment.