More work on Android contacts

This commit is contained in:
Juha Heinanen
2022-02-12 14:08:00 +02:00
parent bfecd70422
commit c7dab37e28
17 changed files with 680 additions and 0 deletions

View File

@ -0,0 +1,9 @@
package com.tutpro.baresip
import java.util.ArrayList
class AndroidContact(val id: Long, var name: String, var color: Int, val thumbnailUri: String?) {
val uris = ArrayList<String>()
}

View File

@ -0,0 +1,162 @@
package com.tutpro.baresip
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.*
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.core.app.ActivityCompat
import androidx.core.net.toUri
import com.google.android.material.snackbar.Snackbar
import com.tutpro.baresip.Utils.showSnackBar
import com.tutpro.baresip.databinding.ActivityAndroidContactBinding
class AndroidContactActivity : AppCompatActivity() {
private lateinit var binding: ActivityAndroidContactBinding
private lateinit var layout: LinearLayout
private lateinit var textAvatarView: TextView
private lateinit var cardAvatarView: CardView
private lateinit var cardImageAvatarView: ImageView
private lateinit var nameView: TextView
private lateinit var ulAdapter: AndroidUriListAdapter
private lateinit var aor: String
private lateinit var requestPermissionsLauncher: ActivityResultLauncher<Array<String>>
private var index = 0
private var color = 0
private var id: Long = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAndroidContactBinding.inflate(layoutInflater)
setContentView(binding.root)
layout = binding.ContactView
aor = intent.getStringExtra("aor")!!
index = intent.getIntExtra("index", 0)
textAvatarView = binding.TextAvatar
cardAvatarView = binding.CardAvatar
cardImageAvatarView = binding.ImageAvatar
nameView = binding.Name
val contact = AndroidContactsActivity.androidContacts[index]
val name = contact.name
color = contact.color
id = contact.id
val thumbnailUri = contact.thumbnailUri
if (thumbnailUri != null)
showImageAvatar(thumbnailUri)
else
showTextAvatar(name, color)
title = name
nameView.text = name
val listView = binding.uris
ulAdapter = AndroidUriListAdapter(this, contact.uris, aor)
listView.adapter = ulAdapter
Utils.addActivity("android contact,$aor,$index")
}
override fun onStart() {
super.onStart()
requestPermissionsLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grandResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grandResults)
when (requestCode) {
CONTACT_PERMISSION_REQUEST_CODE -> {
var allowed = true
for (res in grandResults)
allowed = allowed && res == PackageManager.PERMISSION_GRANTED
if (!allowed) {
when {
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CONTACTS) -> {
layout.showSnackBar(
binding.root,
getString(R.string.no_android_contacts),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionsLauncher.launch(permissions)
}
}
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_CONTACTS) -> {
layout.showSnackBar(
binding.root,
getString(R.string.no_android_contacts),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionsLauncher.launch(permissions)
}
}
else -> {
requestPermissionsLauncher.launch(permissions)
}
}
}
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (BaresipService.activities.indexOf("android contact,$aor,$index") == -1) return true
when (item.itemId) {
android.R.id.home -> {
BaresipService.activities.remove("android contact,$aor,$index")
setResult(Activity.RESULT_CANCELED, Intent(this, MainActivity::class.java))
finish()
}
}
return true
}
override fun onBackPressed() {
BaresipService.activities.remove("android contact,$index")
setResult(Activity.RESULT_CANCELED, Intent(this, MainActivity::class.java))
finish()
super.onBackPressed()
}
private fun showTextAvatar(name: String, color: Int) {
textAvatarView.visibility = View.VISIBLE
cardAvatarView.visibility = View.GONE
textAvatarView.background.setTint(color)
textAvatarView.text = "${name[0]}"
}
private fun showImageAvatar(thumbNailUri: String) {
textAvatarView.visibility = View.GONE
cardAvatarView.visibility = View.VISIBLE
cardImageAvatarView.setImageURI(thumbNailUri.toUri())
}
}

View File

@ -0,0 +1,83 @@
package com.tutpro.baresip
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.os.SystemClock
import androidx.appcompat.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.core.content.ContextCompat.startActivity
import androidx.core.net.toUri
import java.io.File
import java.io.IOException
import java.util.*
class AndroidContactListAdapter(private val ctx: Context,
private val rows: ArrayList<AndroidContact>,
private val aor: String) :
ArrayAdapter<AndroidContact>(ctx, R.layout.android_contact_row, rows) {
private val layoutInflater = LayoutInflater.from(context)
private var lastClick: Long = 0
private class ViewHolder(view: View?) {
val textAvatarView = view?.findViewById(R.id.TextAvatar) as TextView
val imageAvatarView = view?.findViewById(R.id.ImageAvatar) as ImageView
val nameView = view?.findViewById(R.id.contactName) as TextView
}
override fun getView(position: Int, view: View?, parent: ViewGroup): View {
val viewHolder: ViewHolder
val rowView: View
if (view == null) {
rowView = layoutInflater.inflate(R.layout.android_contact_row, parent, false)
viewHolder = ViewHolder(rowView)
rowView.tag = viewHolder
} else {
rowView = view
viewHolder = rowView.tag as ViewHolder
}
val contact = rows[position]
val thumbNailUri = contact.thumbnailUri
if (thumbNailUri != null) {
viewHolder.imageAvatarView.setImageURI(thumbNailUri.toUri())
} else {
contact.color = Utils.randomColor()
viewHolder.textAvatarView.background.setTint(contact.color)
if (contact.name.isNotEmpty())
viewHolder.textAvatarView.text = "${contact.name[0]}"
else
viewHolder.textAvatarView.text = ""
viewHolder.imageAvatarView.setImageBitmap(Utils.bitmapFromView(viewHolder.textAvatarView))
}
viewHolder.nameView.text = contact.name
viewHolder.nameView.textSize = 20f
viewHolder.nameView.setPadding(6, 6, 0, 6)
viewHolder.nameView.setOnClickListener {
if (SystemClock.elapsedRealtime() - lastClick > 1000) {
lastClick = SystemClock.elapsedRealtime()
val i = Intent(ctx, AndroidContactActivity::class.java)
val b = Bundle()
b.putString("aor", aor)
b.putInt("index", position)
i.putExtras(b)
startActivity(ctx, i, null)
}
}
return rowView
}
}

View File

@ -0,0 +1,121 @@
package com.tutpro.baresip
import android.app.Activity
import android.content.*
import android.database.Cursor
import android.os.Bundle
import android.os.SystemClock
import android.provider.ContactsContract
import android.view.Menu
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
import com.tutpro.baresip.databinding.ActivityAndroidContactsBinding
class AndroidContactsActivity : AppCompatActivity() {
private lateinit var binding: ActivityAndroidContactsBinding
private lateinit var clAdapter: AndroidContactListAdapter
private lateinit var aor: String
private var lastSwap: Long = 0
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAndroidContactsBinding.inflate(layoutInflater)
setContentView(binding.root)
aor = intent.getStringExtra("aor")!!
val listView = binding.androidContacts
getAndroidContacts(this)
clAdapter = AndroidContactListAdapter(this, androidContacts, aor)
listView.adapter = clAdapter
Utils.addActivity("android contacts,$aor")
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.swap_contacts_icon, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.swapContactsIcon -> {
if (SystemClock.elapsedRealtime() - lastSwap > 1000) {
lastSwap = SystemClock.elapsedRealtime()
BaresipService.activities.remove("android contacts,$aor")
val intent = Intent(this, ContactsActivity::class.java)
intent.putExtra("aor", aor)
startActivity(intent)
finish()
return true
}
}
android.R.id.home -> {
BaresipService.activities.remove("android contacts,$aor")
setResult(Activity.RESULT_OK, Intent())
finish()
}
}
return true
}
override fun onBackPressed() {
BaresipService.activities.remove("android contacts,$aor")
setResult(Activity.RESULT_OK, Intent())
finish()
}
private fun getAndroidContacts(ctx: Context) {
val projection = arrayOf(ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME,
ContactsContract.Data.MIMETYPE, ContactsContract.Data.DATA1,
ContactsContract.Data.PHOTO_THUMBNAIL_URI)
val selection =
ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' OR " +
ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'"
Log.d(TAG, "******* selection = /$selection/")
val cur: Cursor? = ctx.contentResolver.query(ContactsContract.Data.CONTENT_URI, projection,
selection, null, null)
val contacts = HashMap<Long, AndroidContact>()
while (cur != null && cur.moveToNext()) {
val id = cur.getLong(0)
val name = cur.getString(1) // display name
val mime = cur.getString(2) // type of data
val data = cur.getString(3) // data
val thumb = cur.getString(4) // thumbnail
// Log.d(TAG, "****** $id - $name - $mime - $data - $thumb")
val contact = if (contacts.containsKey(id))
contacts[id]!!
else
AndroidContact(id, name, 0, thumb)
if (mime == ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
contact.uris.add("tel:$data")
else if (mime == ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
contact.uris.add("sip:$data")
else
continue
if (!contacts.containsKey(id))
contacts[id] = contact
}
cur?.close()
androidContacts.clear()
for ((_, value) in contacts)
androidContacts.add(value)
return
}
companion object {
val androidContacts = ArrayList<AndroidContact>()
}
}

View File

@ -0,0 +1,76 @@
package com.tutpro.baresip
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageButton
import android.widget.TextView
class AndroidUriListAdapter(private val ctx: Context, private val rows: ArrayList<String>, val aor: String) :
ArrayAdapter<String>(ctx, R.layout.android_uri_row, rows) {
private val layoutInflater = LayoutInflater.from(context)
private class ViewHolder(view: View?) {
val uriView = view?.findViewById(R.id.uri) as TextView
val messageView = view?.findViewById(R.id.message) as ImageButton
val callView = view?.findViewById(R.id.call) as ImageButton
}
override fun getView(position: Int, view: View?, parent: ViewGroup): View {
val viewHolder: ViewHolder
val rowView: View
if (view == null) {
rowView = layoutInflater.inflate(R.layout.android_uri_row, parent, false)
viewHolder = ViewHolder(rowView)
rowView.tag = viewHolder
} else {
rowView = view
viewHolder = rowView.tag as ViewHolder
}
val uri = rows[position]
viewHolder.uriView.text = uri.substringAfter(":")
viewHolder.messageView.setOnClickListener {
val i = Intent(ctx, MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
i.putExtra("action", "message")
val ua = UserAgent.ofAor(aor)
if (ua == null) {
Log.w(TAG, "onClickListener did not find AoR $aor")
} else {
BaresipService.activities.clear()
i.putExtra("uap", ua.uap)
i.putExtra("peer", uri)
(ctx as Activity).startActivity(i)
}
}
viewHolder.callView.setOnClickListener {
val i = Intent(ctx, MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
i.putExtra("action", "call")
val ua = UserAgent.ofAor(aor)
if (ua == null) {
Log.w(TAG, "onClickListener did not find AoR $aor")
} else {
BaresipService.activities.clear()
i.putExtra("uap", ua.uap)
i.putExtra("peer", uri)
(ctx as Activity).startActivity(i)
}
}
return rowView
}
}

View File

@ -77,6 +77,7 @@ class ContactsActivity : AppCompatActivity() {
R.id.swapContactsIcon -> {
if (SystemClock.elapsedRealtime() - lastClick > 1000) {
lastClick = SystemClock.elapsedRealtime()
BaresipService.activities.remove("contacts,$aor")
val intent = Intent(this, AndroidContactsActivity::class.java)
intent.putExtra("aor", aor)
startActivity(intent)

View File

@ -1966,6 +1966,21 @@ class MainActivity : AppCompatActivity() {
i.putExtras(b)
startActivity(i)
}
"android contacts" -> {
val i = Intent(this, AndroidContactsActivity::class.java)
val b = Bundle()
b.putString("aor", activity[1])
i.putExtras(b)
startActivity(i)
}
"android contact" -> {
val i = Intent(this, AndroidContactActivity::class.java)
val b = Bundle()
b.putString("aor", activity[1])
b.putInt("index", activity[2].toInt())
i.putExtras(b)
startActivity(i)
}
"chats" -> {
val i = Intent(this, ChatsActivity::class.java)
val b = Bundle()

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000" android:pathData="M20,15.5C18.8,15.5 17.5,15.3 16.4,14.9C16.3,14.9 16.2,14.9 16.1,14.9C15.8,14.9 15.6,15 15.4,15.2L13.2,17.4C10.4,15.9 8,13.6 6.6,10.8L8.8,8.6C9.1,8.3 9.2,7.9 9,7.6C8.7,6.5 8.5,5.2 8.5,4C8.5,3.5 8,3 7.5,3H4C3.5,3 3,3.5 3,4C3,13.4 10.6,21 20,21C20.5,21 21,20.5 21,20V16.5C21,16 20.5,15.5 20,15.5M5,5H6.5C6.6,5.9 6.8,6.8 7,7.6L5.8,8.8C5.4,7.6 5.1,6.3 5,5M19,19C17.7,18.9 16.4,18.6 15.2,18.2L16.4,17C17.2,17.2 18.1,17.4 19,17.4V19Z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="48dp"
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
android:viewportWidth="24" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17.5,4.5c-1.95,0 -4.05,0.4 -5.5,1.5c-1.45,-1.1 -3.55,-1.5 -5.5,-1.5S2.45,4.9 1,6v14.65c0,0.65 0.73,0.45 0.75,0.45C3.1,20.45 5.05,20 6.5,20c1.95,0 4.05,0.4 5.5,1.5c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.65,0 3.35,0.3 4.75,1.05C22.66,21.26 23,20.86 23,20.6V6C21.51,4.88 19.37,4.5 17.5,4.5zM21,18.5c-1.1,-0.35 -2.3,-0.5 -3.5,-0.5c-1.7,0 -4.15,0.65 -5.5,1.5V8c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.2,0 2.4,0.15 3.5,0.5V18.5z"/>
</vector>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ContactView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="24dp"
android:orientation="vertical">
<TextView
android:id="@+id/TextAvatar"
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_gravity="center_horizontal"
android:scaleType="centerInside"
android:background="@drawable/circle"
android:textSize="72sp"
android:textAllCaps="true"
android:textColor="@android:color/white"
android:gravity="center" >
</TextView>
<androidx.cardview.widget.CardView
android:id="@+id/CardAvatar"
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_gravity="center_horizontal"
android:elevation="12dp"
app:cardCornerRadius="48dp" >
<ImageView
android:id="@+id/ImageAvatar"
android:contentDescription="@string/avatar_image"
android:layout_height="96dp"
android:layout_width="96dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop" >
</ImageView>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/Name"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginTop="24dp"
android:layout_marginBottom="12dp"
android:textColor="@color/colorStrong"
android:textSize="24sp"
tools:ignore="LabelFor">
</TextView>
<ListView
android:id="@+id/uris"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:divider="#00000000"
android:dividerHeight="0dp" >
</ListView>
</LinearLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".AndroidContactsActivity">
<ListView
android:id="@+id/androidContacts"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:divider="#00000000"
android:dividerHeight="10dp" >
</ListView>
</RelativeLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/androidContactRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/TextAvatar"
android:layout_width="36dp"
android:layout_height="36dp"
android:scaleType="centerInside"
android:background="@drawable/circle"
android:textSize="24sp"
android:textAllCaps="true"
android:textColor="@android:color/white"
android:gravity="center"
android:visibility="gone" >
</TextView>
<androidx.cardview.widget.CardView
android:id="@+id/CardAvatar"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:elevation="12dp"
app:cardCornerRadius="18dp" >
<ImageView
android:id="@+id/ImageAvatar"
android:layout_height="36dp"
android:layout_width="36dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:contentDescription="@string/avatar_image">
</ImageView>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/contactName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="41dp"
android:textSize="20sp"
android:layout_marginBottom="6dp">
</TextView>
</RelativeLayout>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/uriRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/uri"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:textSize="18sp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp" >
</TextView>
<ImageButton
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_marginEnd="48dp"
android:layout_marginStart="10dp"
android:src="@drawable/message"
android:background="@null"
android:scaleType="centerCrop"
android:contentDescription="@string/call" >
</ImageButton>
<ImageButton
android:id="@+id/call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:src="@drawable/call"
android:background="@null"
android:scaleType="centerCrop"
android:contentDescription="@string/call" >
</ImageButton>
</RelativeLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/swapContactsIcon"
android:title=""
app:showAsAction="always"
android:icon="@drawable/swap_contacts" />
</menu>

View File

@ -12,6 +12,7 @@
<color name="colorBaresip">#0ca1fd</color>
<color name="colorWhite">#ffffff</color>
<color name="colorBlack">#000000</color>
<color name="colorStrong">@color/colorWhite</color>
<color name="colorGreen">#01df01</color>
<color name="colorRed">#df0101</color>
<color name="colorLight">@color/colorGrayLight</color>

View File

@ -12,6 +12,7 @@
<color name="colorBaresip">#0ca1fd</color>
<color name="colorWhite">#ffffff</color>
<color name="colorBlack">#000000</color>
<color name="colorStrong">@color/colorBlack</color>
<color name="colorGreen">#01df01</color>
<color name="colorRed">#df0101</color>
<color name="colorLight">@color/colorWhite</color>