Meilleur support des NotificationChannel d'Android O

This commit is contained in:
odrling 2018-03-17 14:37:53 +01:00
parent ec8a3cf5b2
commit 00099ce046
7 changed files with 138 additions and 61 deletions

View file

@ -55,15 +55,22 @@
</intent-filter>
</receiver>
<receiver android:name=".messages.NornLocaleChangedReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED"/>
</intent-filter>
</receiver>
<receiver
android:name=".messages.NornSentReceiver"
android:enabled="true"
android:exported="true" />
android:enabled="true"/>
<receiver
android:name=".messages.NornDeliveredReceiver"
android:enabled="true"
android:exported="true"/>
android:enabled="true"/>
<service android:name=".messages.NornMessageService"
android:enabled="true"

View file

@ -10,6 +10,7 @@ import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import xyz.johnny.norntalk.database.NornDatabase
import xyz.johnny.norntalk.messages.NornNotification
import xyz.johnny.norntalk.security.Security
@ -47,13 +48,47 @@ class SplashActivity : AppCompatActivity() {
*/
fun checkperm(perm: String) = ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED
/**
* Méthode permettant d'effectuer des opérations en parallèle
*
* @param function Fonction contenant l'opération à effectuer en parallèle
* @return Tâche correspondant à l'opération
*/
@SuppressLint("StaticFieldLeak")
private fun load_helper(function: () -> Any): AsyncTask<Void, Void, Unit> {
return object : AsyncTask<Void, Void, Unit>() {
override fun doInBackground(vararg params: Void?) {
function()
}
}
}
/**
* Charger l'ensemble des singletons de Security
*
* @return Tâches correspondants aux opérations
*/
fun load(): Array<AsyncTask<Void, Void, Unit>> {
val tasks = arrayOf(
load_helper { Security.random },
load_helper { Security.curve },
load_helper { Security.barcodeEncoder },
load_helper { NornNotification.createChannel(this) },
load_helper { NornDatabase.getNornDatabase(this) }
)
tasks.forEach { it.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) }
return tasks
}
@SuppressLint("StaticFieldLeak")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// lancer les tâches en arrière plan
this._tasks = Security.load(this)
NornDatabase.getNornDatabase(this)
this._tasks = this.load()
// trouver les permissions non acceptées par l'utilisateur
val permissions = all_permissions.filter { this.checkperm(it) }.toTypedArray()

View file

@ -0,0 +1,23 @@
package xyz.johnny.norntalk.messages
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
/**
* Actions effectuées lorsque l'utilisateur change la langue du système.
* Change le nom et la description de la chaîne de notification sur Android O.
*/
class NornLocaleChangedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(this::class.java.simpleName, "Locale changed")
if (intent.action == Intent.ACTION_LOCALE_CHANGED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
NornNotification.updateChannel(context)
}
}
}

View file

@ -7,7 +7,6 @@ import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.preference.PreferenceManager
import android.support.v4.app.NotificationCompat
@ -37,25 +36,76 @@ class NornNotification private constructor(val conversationId: Int, val context:
*/
private val notifications = SparseArray<NornNotification>()
@TargetApi(Build.VERSION_CODES.O)
/**
* Le pattern des vibrations des notifications
*/
private val vibrationPattern = longArrayOf(300, 300, 300, 300, 300)
private var _channelMessages: NotificationChannel? = null
/**
* Instance de NotificationChannel pour Android O
*/
private val channelMessages get() = _channelMessages!!
private const val channelId = "messages"
@TargetApi(Build.VERSION_CODES.O)
fun updateChannel(context: Context) {
if (this._channelMessages == null) {
createChannel(context)
} else {
channelMessages.name = context.getString(R.string.channel_messages)
channelMessages.description = context.getString(R.string.channel_description_messages)
// register the notification channel
val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channelMessages)
}
}
@TargetApi(Build.VERSION_CODES.O)
/**
* Crée la chaîne de notification sur Android O
*
* @param context Contexte courant
*/
fun createChannel(context: Context) {
val name = context.getString(R.string.channel_messages)
val importance = NotificationManager.IMPORTANCE_HIGH
_channelMessages = NotificationChannel(channelId, name, importance)
channelMessages.enableLights(true)
channelMessages.lightColor = context.getColor(R.color.colorPrimary)
channelMessages.enableVibration(true)
channelMessages.vibrationPattern = vibrationPattern
this.updateChannel(context)
}
@TargetApi(Build.VERSION_CODES.O)
/**
* Méthode retournant un builder pour différentes versions d'Android
*
* @param context Contexte courant
*/
fun getBuilder(context: Context): NotificationCompat.Builder {
val channelId = "messages"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "messages"
val description = "Messages"
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(channelId, name, importance)
channel.description = description
// Register the channel with the system
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
createChannel(context)
val builder = NotificationCompat.Builder(context, channelId)
builder.setLights(context.getColor(R.color.colorPrimary), 2000, 500)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
builder.setVibrate(vibrationPattern)
builder.priority = NotificationCompat.PRIORITY_HIGH
}
return NotificationCompat.Builder(context, channelId)
// assigner une icone, un pattern de vibrations et de clignottement de la LED du téléphone
builder.setSmallIcon(R.drawable.ic_message)
return builder
}
/**
@ -128,12 +178,6 @@ class NornNotification private constructor(val conversationId: Int, val context:
// conserver la notification dans l'association
notifications.put(conversationId, this)
// assigner une icone, un pattern de vibrations et de clignottement de la LED du téléphone
this.builder.setSmallIcon(R.drawable.ic_message)
this.builder.setVibrate(longArrayOf(300, 300, 300, 300, 300))
this.builder.setLights(Color.WHITE, 1000, 500)
this.builder.priority = NotificationCompat.PRIORITY_HIGH
// assigner le style à la notification
this.builder.setStyle(this.messagingStyle)

View file

@ -1,8 +1,5 @@
package xyz.johnny.norntalk.security
import android.annotation.SuppressLint
import android.content.Context
import android.os.AsyncTask
import com.journeyapps.barcodescanner.BarcodeEncoder
import org.whispersystems.curve25519.Curve25519
import java.security.SecureRandom
@ -27,37 +24,4 @@ object Security {
*/
val barcodeEncoder by lazy { BarcodeEncoder() }
/**
* Méthode permettant d'effectuer des opérations en parallèle
*
* @param function Fonction contenant l'opération à effectuer en parallèle
* @return Tâche correspondant à l'opération
*/
@SuppressLint("StaticFieldLeak")
private fun load_helper(function: () -> Any): AsyncTask<Void, Void, Unit> {
return object : AsyncTask<Void, Void, Unit>() {
override fun doInBackground(vararg params: Void?) {
function()
}
}
}
/**
* Charger l'ensemble des singletons de Security
*
* @return Tâches correspondants aux opérations
*/
fun load(context: Context): Array<AsyncTask<Void, Void, Unit>> {
val tasks = arrayOf(
load_helper { this.random },
load_helper { this.curve },
load_helper { this.barcodeEncoder }
)
tasks.forEach { it.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) }
return tasks
}
}

View file

@ -42,4 +42,6 @@
<string name="generating_qrcode">QR code en cours de génération</string>
<string name="qrcode_generated">QR code généré</string>
<string name="invalid_number">Numéro de téléphone invalide</string>
<string name="channel_messages">Messages</string>
<string name="channel_description_messages">Messages reçus</string>
</resources>

View file

@ -43,4 +43,6 @@
<string name="generating_qrcode">Generating QR code</string>
<string name="qrcode_generated">QR code generated</string>
<string name="invalid_number">Invalid sms number</string>
<string name="channel_messages">Messages</string>
<string name="channel_description_messages">Messages received</string>
</resources>