Merge pull request #5667 from osmandapp/AddChatIdsToDuration
Add chat ids to duration in settings
This commit is contained in:
commit
af7c9bed4b
6 changed files with 72 additions and 40 deletions
|
@ -1,6 +1,7 @@
|
||||||
package net.osmand.telegram
|
package net.osmand.telegram
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import net.osmand.telegram.helpers.TelegramHelper
|
||||||
import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants
|
import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants
|
||||||
import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants
|
import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants
|
||||||
|
|
||||||
|
@ -18,10 +19,14 @@ private const val SEND_MY_LOCATION_INTERVAL_DEFAULT = 5L * 1000 // 5 seconds
|
||||||
private const val USER_LOCATION_EXPIRE_TIME_KEY = "user_location_expire_time"
|
private const val USER_LOCATION_EXPIRE_TIME_KEY = "user_location_expire_time"
|
||||||
private const val USER_LOCATION_EXPIRE_TIME_DEFAULT = 15L * 60 * 1000 // 15 minutes
|
private const val USER_LOCATION_EXPIRE_TIME_DEFAULT = 15L * 60 * 1000 // 15 minutes
|
||||||
|
|
||||||
|
private const val DEFAULT_VISIBLE_TIME_SECONDS = 60 * 60L // 1 hour
|
||||||
|
|
||||||
private const val TITLES_REPLACED_WITH_IDS = "changed_to_chat_id"
|
private const val TITLES_REPLACED_WITH_IDS = "changed_to_chat_id"
|
||||||
|
|
||||||
class TelegramSettings(private val app: TelegramApplication) {
|
class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
|
var chatLivePeriods = mutableMapOf<Long, Long>()
|
||||||
|
|
||||||
private var shareLocationChats: Set<Long> = emptySet()
|
private var shareLocationChats: Set<Long> = emptySet()
|
||||||
private var showOnMapChats: Set<Long> = emptySet()
|
private var showOnMapChats: Set<Long> = emptySet()
|
||||||
|
|
||||||
|
@ -52,20 +57,34 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
val showOnMapChats = showOnMapChats.toMutableList()
|
val showOnMapChats = showOnMapChats.toMutableList()
|
||||||
showOnMapChats.intersect(presentChatIds)
|
showOnMapChats.intersect(presentChatIds)
|
||||||
this.showOnMapChats = showOnMapChats.toHashSet()
|
this.showOnMapChats = showOnMapChats.toHashSet()
|
||||||
|
|
||||||
|
chatLivePeriods = chatLivePeriods.filter { (key, _) ->
|
||||||
|
presentChatIds.contains(key)
|
||||||
|
}.toMutableMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shareLocationToChat(chatId: Long, share: Boolean) {
|
fun shareLocationToChat(chatId: Long, share: Boolean, livePeriod: Long = DEFAULT_VISIBLE_TIME_SECONDS) {
|
||||||
val shareLocationChats = shareLocationChats.toMutableList()
|
val shareLocationChats = shareLocationChats.toMutableList()
|
||||||
if (share) {
|
if (share) {
|
||||||
|
val lp: Long = when {
|
||||||
|
livePeriod < TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong()
|
||||||
|
livePeriod > TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong()
|
||||||
|
else -> livePeriod
|
||||||
|
}
|
||||||
|
chatLivePeriods[chatId] = lp
|
||||||
shareLocationChats.add(chatId)
|
shareLocationChats.add(chatId)
|
||||||
} else {
|
} else {
|
||||||
shareLocationChats.remove(chatId)
|
shareLocationChats.remove(chatId)
|
||||||
|
chatLivePeriods.remove(chatId)
|
||||||
}
|
}
|
||||||
this.shareLocationChats = shareLocationChats.toHashSet()
|
this.shareLocationChats = shareLocationChats.toHashSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getChatLivePeriod(chatId: Long) = chatLivePeriods[chatId]
|
||||||
|
|
||||||
fun stopSharingLocationToChats() {
|
fun stopSharingLocationToChats() {
|
||||||
this.shareLocationChats = emptySet()
|
this.shareLocationChats = emptySet()
|
||||||
|
this.chatLivePeriods.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showChatOnMap(chatId: Long, show: Boolean) {
|
fun showChatOnMap(chatId: Long, show: Boolean) {
|
||||||
|
|
|
@ -38,9 +38,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
lastLocation = location
|
lastLocation = location
|
||||||
|
|
||||||
if (location != null && app.isInternetConnectionAvailable) {
|
if (location != null && app.isInternetConnectionAvailable) {
|
||||||
val shareLocationChats = app.settings.getShareLocationChats()
|
val chatLivePeriods = app.settings.chatLivePeriods
|
||||||
if (shareLocationChats.isNotEmpty()) {
|
if (chatLivePeriods.isNotEmpty()) {
|
||||||
app.telegramHelper.sendLiveLocationMessage(shareLocationChats, MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC, location.latitude, location.longitude)
|
app.telegramHelper.sendLiveLocationMessage(chatLivePeriods, location.latitude, location.longitude)
|
||||||
}
|
}
|
||||||
lastLocationMessageSentTime = System.currentTimeMillis()
|
lastLocationMessageSentTime = System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,15 +385,15 @@ class TelegramHelper private constructor() {
|
||||||
* @latitude Latitude of the location
|
* @latitude Latitude of the location
|
||||||
* @longitude Longitude of the location
|
* @longitude Longitude of the location
|
||||||
*/
|
*/
|
||||||
fun sendLiveLocationMessage(chatIds: List<Long>, livePeriod: Int, latitude: Double, longitude: Double): Boolean {
|
fun sendLiveLocationMessage(chatLivePeriods: Map<Long, Long>, latitude: Double, longitude: Double): Boolean {
|
||||||
if (!requestingActiveLiveLocationMessages && haveAuthorization) {
|
if (!requestingActiveLiveLocationMessages && haveAuthorization) {
|
||||||
if (needRefreshActiveLiveLocationMessages) {
|
if (needRefreshActiveLiveLocationMessages) {
|
||||||
getActiveLiveLocationMessages {
|
getActiveLiveLocationMessages {
|
||||||
sendLiveLocationImpl(chatIds, livePeriod, latitude, longitude)
|
sendLiveLocationImpl(chatLivePeriods, latitude, longitude)
|
||||||
}
|
}
|
||||||
needRefreshActiveLiveLocationMessages = false
|
needRefreshActiveLiveLocationMessages = false
|
||||||
} else {
|
} else {
|
||||||
sendLiveLocationImpl(chatIds, livePeriod, latitude, longitude)
|
sendLiveLocationImpl(chatLivePeriods, latitude, longitude)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -428,24 +428,24 @@ class TelegramHelper private constructor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendLiveLocationImpl(chatIds: List<Long>, livePeriod: Int, latitude: Double, longitude: Double) {
|
private fun sendLiveLocationImpl(chatLivePeriods: Map<Long, Long>, latitude: Double, longitude: Double) {
|
||||||
val lp = when {
|
|
||||||
livePeriod < MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
|
||||||
livePeriod > MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
|
||||||
else -> livePeriod
|
|
||||||
}
|
|
||||||
val location = TdApi.Location(latitude, longitude)
|
val location = TdApi.Location(latitude, longitude)
|
||||||
val content = TdApi.InputMessageLocation(location, lp)
|
chatLivePeriods.forEach { chatId, livePeriod ->
|
||||||
|
val content = TdApi.InputMessageLocation(location, livePeriod.toInt())
|
||||||
for (chatId in chatIds) {
|
|
||||||
val msgId = chatLiveMessages[chatId]
|
val msgId = chatLiveMessages[chatId]
|
||||||
if (msgId != null) {
|
if (msgId != null) {
|
||||||
if (msgId != 0L) {
|
if (msgId != 0L) {
|
||||||
client?.send(TdApi.EditMessageLiveLocation(chatId, msgId, null, location), liveLocationMessageUpdatesHandler)
|
client?.send(
|
||||||
|
TdApi.EditMessageLiveLocation(chatId, msgId, null, location),
|
||||||
|
liveLocationMessageUpdatesHandler
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
chatLiveMessages[chatId] = 0L
|
chatLiveMessages[chatId] = 0L
|
||||||
client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), liveLocationMessageUpdatesHandler)
|
client?.send(
|
||||||
|
TdApi.SendMessage(chatId, 0, false, true, null, content),
|
||||||
|
liveLocationMessageUpdatesHandler
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
if (AndroidUtils.isLocationPermissionAvailable(this)) {
|
if (AndroidUtils.isLocationPermissionAvailable(this)) {
|
||||||
app.locationProvider.resumeAllUpdates()
|
app.locationProvider.resumeAllUpdates()
|
||||||
} else {
|
} else {
|
||||||
requestLocationPermission()
|
AndroidUtils.requestLocationPermission(this)
|
||||||
}
|
}
|
||||||
if (settings.hasAnyChatToShowOnMap() && osmandAidlHelper.isOsmandNotInstalled()) {
|
if (settings.hasAnyChatToShowOnMap() && osmandAidlHelper.isOsmandNotInstalled()) {
|
||||||
showOsmandMissingDialog()
|
showOsmandMissingDialog()
|
||||||
|
@ -373,10 +373,6 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requestLocationPermission() {
|
|
||||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_LOCATION)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
if (grantResults.isEmpty()) {
|
if (grantResults.isEmpty()) {
|
||||||
|
@ -475,7 +471,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
if (settings.hasAnyChatToShareLocation()) {
|
if (settings.hasAnyChatToShareLocation()) {
|
||||||
if (!AndroidUtils.isLocationPermissionAvailable(view.context)) {
|
if (!AndroidUtils.isLocationPermissionAvailable(view.context)) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
requestLocationPermission()
|
AndroidUtils.requestLocationPermission(this@MainActivity)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
app.shareLocationHelper.startSharingLocation()
|
app.shareLocationHelper.startSharingLocation()
|
||||||
|
|
|
@ -11,12 +11,12 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
|
||||||
import net.osmand.telegram.R
|
import net.osmand.telegram.R
|
||||||
import net.osmand.telegram.TelegramApplication
|
import net.osmand.telegram.TelegramApplication
|
||||||
import net.osmand.telegram.helpers.ShareLocationHelper
|
import net.osmand.telegram.helpers.ShareLocationHelper
|
||||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||||
import net.osmand.telegram.ui.SetTimeDialogFragment.SetTimeListAdapter.ChatViewHolder
|
import net.osmand.telegram.ui.SetTimeDialogFragment.SetTimeListAdapter.ChatViewHolder
|
||||||
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
@ -26,13 +26,14 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
get() = activity?.application as TelegramApplication
|
get() = activity?.application as TelegramApplication
|
||||||
|
|
||||||
private val telegramHelper get() = app.telegramHelper
|
private val telegramHelper get() = app.telegramHelper
|
||||||
|
private val settings get() = app.settings
|
||||||
|
|
||||||
private val adapter = SetTimeListAdapter()
|
private val adapter = SetTimeListAdapter()
|
||||||
|
|
||||||
private lateinit var timeForAllTitle: TextView
|
private lateinit var timeForAllTitle: TextView
|
||||||
private lateinit var timeForAllValue: TextView
|
private lateinit var timeForAllValue: TextView
|
||||||
|
|
||||||
private val chatIdsToDuration = HashMap<Long, Long>()
|
private val chatLivePeriods = HashMap<Long, Long>()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -76,7 +77,15 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
view.findViewById<TextView>(R.id.primary_btn).apply {
|
view.findViewById<TextView>(R.id.primary_btn).apply {
|
||||||
text = getString(R.string.shared_string_share)
|
text = getString(R.string.shared_string_share)
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
Toast.makeText(context, "Share", Toast.LENGTH_SHORT).show()
|
if (!AndroidUtils.isLocationPermissionAvailable(view.context)) {
|
||||||
|
AndroidUtils.requestLocationPermission(activity!!)
|
||||||
|
} else {
|
||||||
|
chatLivePeriods.forEach { chatId, livePeriod ->
|
||||||
|
settings.shareLocationToChat(chatId, true, livePeriod)
|
||||||
|
}
|
||||||
|
app.shareLocationHelper.startSharingLocation()
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,25 +100,26 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
val chats = mutableListOf<Long>()
|
val chats = mutableListOf<Long>()
|
||||||
for ((id, duration) in chatIdsToDuration) {
|
for ((id, livePeriod) in chatLivePeriods) {
|
||||||
chats.add(id)
|
chats.add(id)
|
||||||
chats.add(duration)
|
chats.add(livePeriod)
|
||||||
}
|
}
|
||||||
outState.putLongArray(CHATS_KEY, chats.toLongArray())
|
outState.putLongArray(CHATS_KEY, chats.toLongArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readFromBundle(bundle: Bundle?) {
|
private fun readFromBundle(bundle: Bundle?) {
|
||||||
chatIdsToDuration.clear()
|
chatLivePeriods.clear()
|
||||||
bundle?.getLongArray(CHATS_KEY)?.also {
|
bundle?.getLongArray(CHATS_KEY)?.also {
|
||||||
for (i in 0 until it.size step 2) {
|
for (i in 0 until it.size step 2) {
|
||||||
chatIdsToDuration[it[i]] = it[i + 1]
|
val livePeriod = settings.getChatLivePeriod(it[i])
|
||||||
|
chatLivePeriods[it[i]] = livePeriod ?: it[i + 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTimeForAll(useDefValue: Boolean = false): Long {
|
private fun getTimeForAll(useDefValue: Boolean = false): Long {
|
||||||
val returnVal = if (useDefValue) DEFAULT_VISIBLE_TIME_SECONDS else NO_VALUE
|
val returnVal = if (useDefValue) DEFAULT_VISIBLE_TIME_SECONDS else NO_VALUE
|
||||||
val iterator = chatIdsToDuration.values.iterator()
|
val iterator = chatLivePeriods.values.iterator()
|
||||||
if (!iterator.hasNext()) {
|
if (!iterator.hasNext()) {
|
||||||
return returnVal
|
return returnVal
|
||||||
}
|
}
|
||||||
|
@ -127,7 +137,7 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
if (timeForAll != NO_VALUE) {
|
if (timeForAll != NO_VALUE) {
|
||||||
timeForAllTitle.text = getString(R.string.visible_time_for_all)
|
timeForAllTitle.text = getString(R.string.visible_time_for_all)
|
||||||
timeForAllValue.visibility = View.VISIBLE
|
timeForAllValue.visibility = View.VISIBLE
|
||||||
timeForAllValue.text = formatDuration(timeForAll)
|
timeForAllValue.text = formatLivePeriod(timeForAll)
|
||||||
} else {
|
} else {
|
||||||
timeForAllTitle.text = getString(R.string.set_visible_time_for_all)
|
timeForAllTitle.text = getString(R.string.set_visible_time_for_all)
|
||||||
timeForAllValue.visibility = View.GONE
|
timeForAllValue.visibility = View.GONE
|
||||||
|
@ -136,7 +146,7 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
|
|
||||||
private fun selectDuration(id: Long? = null) {
|
private fun selectDuration(id: Long? = null) {
|
||||||
val timeForAll = getTimeForAll(true)
|
val timeForAll = getTimeForAll(true)
|
||||||
val defSeconds = if (id == null) timeForAll else chatIdsToDuration[id] ?: timeForAll
|
val defSeconds = if (id == null) timeForAll else chatLivePeriods[id] ?: timeForAll
|
||||||
val (defHours, defMinutes) = secondsToHoursAndMinutes(defSeconds)
|
val (defHours, defMinutes) = secondsToHoursAndMinutes(defSeconds)
|
||||||
TimePickerDialog(
|
TimePickerDialog(
|
||||||
context,
|
context,
|
||||||
|
@ -145,10 +155,10 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
TimeUnit.MINUTES.toSeconds(minutes.toLong())
|
TimeUnit.MINUTES.toSeconds(minutes.toLong())
|
||||||
if (seconds >= ShareLocationHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC) {
|
if (seconds >= ShareLocationHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC) {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
chatIdsToDuration[id] = seconds
|
chatLivePeriods[id] = seconds
|
||||||
} else {
|
} else {
|
||||||
chatIdsToDuration.keys.forEach {
|
chatLivePeriods.keys.forEach {
|
||||||
chatIdsToDuration[it] = seconds
|
chatLivePeriods[it] = seconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateTimeForAllRow()
|
updateTimeForAllRow()
|
||||||
|
@ -164,7 +174,7 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
return Pair(hours.toInt(), minutes.toInt())
|
return Pair(hours.toInt(), minutes.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatDuration(seconds: Long): String {
|
private fun formatLivePeriod(seconds: Long): String {
|
||||||
val (hours, minutes) = secondsToHoursAndMinutes(seconds)
|
val (hours, minutes) = secondsToHoursAndMinutes(seconds)
|
||||||
return when {
|
return when {
|
||||||
hours != 0 && minutes == 0 -> getString(R.string.hours_format, hours)
|
hours != 0 && minutes == 0 -> getString(R.string.hours_format, hours)
|
||||||
|
@ -175,7 +185,7 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
|
|
||||||
private fun updateList() {
|
private fun updateList() {
|
||||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||||
telegramHelper.getChatList().filter { chatIdsToDuration.keys.contains(it.chatId) }
|
telegramHelper.getChatList().filter { chatLivePeriods.keys.contains(it.chatId) }
|
||||||
.forEach { orderedChat ->
|
.forEach { orderedChat ->
|
||||||
telegramHelper.getChat(orderedChat.chatId)?.also { chats.add(it) }
|
telegramHelper.getChat(orderedChat.chatId)?.also { chats.add(it) }
|
||||||
}
|
}
|
||||||
|
@ -204,7 +214,7 @@ class SetTimeDialogFragment : DialogFragment() {
|
||||||
holder.description?.text = "Some description" // FIXME
|
holder.description?.text = "Some description" // FIXME
|
||||||
holder.textInArea?.apply {
|
holder.textInArea?.apply {
|
||||||
visibility = View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
chatIdsToDuration[chat.id]?.also { text = formatDuration(it) }
|
chatLivePeriods[chat.id]?.also { text = formatLivePeriod(it) }
|
||||||
}
|
}
|
||||||
holder.bottomShadow?.visibility = View.GONE
|
holder.bottomShadow?.visibility = View.GONE
|
||||||
holder.itemView.setOnClickListener {
|
holder.itemView.setOnClickListener {
|
||||||
|
|
|
@ -19,6 +19,8 @@ import android.view.inputmethod.InputMethodManager
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object AndroidUtils {
|
object AndroidUtils {
|
||||||
|
|
||||||
|
private const val PERMISSION_REQUEST_LOCATION = 1
|
||||||
|
|
||||||
private fun isHardwareKeyboardAvailable(context: Context): Boolean {
|
private fun isHardwareKeyboardAvailable(context: Context): Boolean {
|
||||||
return context.resources.configuration.keyboard != Configuration.KEYBOARD_NOKEYS
|
return context.resources.configuration.keyboard != Configuration.KEYBOARD_NOKEYS
|
||||||
|
@ -50,6 +52,11 @@ object AndroidUtils {
|
||||||
return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|
return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun requestLocationPermission(activity: Activity) {
|
||||||
|
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_LOCATION)
|
||||||
|
}
|
||||||
|
|
||||||
fun dpToPx(ctx: Context, dp: Float): Int {
|
fun dpToPx(ctx: Context, dp: Float): Int {
|
||||||
val r = ctx.resources
|
val r = ctx.resources
|
||||||
return TypedValue.applyDimension(
|
return TypedValue.applyDimension(
|
||||||
|
|
Loading…
Reference in a new issue