diff --git a/OsmAnd-telegram/AndroidManifest.xml b/OsmAnd-telegram/AndroidManifest.xml
index 9b89517512..f5f012c063 100644
--- a/OsmAnd-telegram/AndroidManifest.xml
+++ b/OsmAnd-telegram/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml b/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml
index 7d5f238f99..b196c0372b 100644
--- a/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml
+++ b/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml
@@ -200,8 +200,8 @@
diff --git a/OsmAnd-telegram/res/layout/user_list_item.xml b/OsmAnd-telegram/res/layout/user_list_item.xml
index 4f9647b080..d9cec851a1 100644
--- a/OsmAnd-telegram/res/layout/user_list_item.xml
+++ b/OsmAnd-telegram/res/layout/user_list_item.xml
@@ -22,8 +22,8 @@
64dp
14dp
- 40dp
+ 24dp
+ 40dp
12dp
20dp
diff --git a/OsmAnd-telegram/res/values/strings.xml b/OsmAnd-telegram/res/values/strings.xml
index 910a6482ab..c88b4420d7 100644
--- a/OsmAnd-telegram/res/values/strings.xml
+++ b/OsmAnd-telegram/res/values/strings.xml
@@ -1,4 +1,10 @@
+ Change battery optimization settings, for stable location sharing
+ Background work
+ For stable sharing of your position in the background, it is advisable to disable battery optimization for OsmAnd Telegram.\n\nIf optimization is enabled, the system may automatically turn off the application running in the background (when the screen is locked and/or the app is minimized). This happens without notification and causes the geo position broadcast to stop.
+ Sharing in the background
+ Go to settings
+ Later
Not sent yet
Not found yet
Re-send location
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
index a1d2c9bef3..0f59fc24a4 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
@@ -67,6 +67,8 @@ private const val LIVE_NOW_SORT_TYPE_KEY = "live_now_sort_type"
private const val SHARE_CHATS_INFO_KEY = "share_chats_info"
+private const val BATTERY_OPTIMISATION_ASKED = "battery_optimisation_asked"
+
class TelegramSettings(private val app: TelegramApplication) {
private var shareChatsInfo = ConcurrentHashMap()
@@ -91,6 +93,8 @@ class TelegramSettings(private val app: TelegramApplication) {
val gpsAndLocPrefs = listOf(SendMyLocPref(), StaleLocPref(), LocHistoryPref())
+ var batteryOptimisationAsked = false
+
init {
updatePrefs()
read()
@@ -208,7 +212,7 @@ class TelegramSettings(private val app: TelegramApplication) {
SharingStatusType.NO_GPS
} else {
var sendChatsErrors = false
- shareChatsInfo.forEach { _, shareInfo ->
+ shareChatsInfo.forEach { (_, shareInfo) ->
if (shareInfo.hasSharingError || shareInfo.lastSuccessfulSendTimeMs == -1L) {
sendChatsErrors = true
locationTime = shareInfo.lastSuccessfulSendTimeMs
@@ -274,6 +278,8 @@ class TelegramSettings(private val app: TelegramApplication) {
edit.putString(LIVE_NOW_SORT_TYPE_KEY, liveNowSortType.name)
+ edit.putBoolean(BATTERY_OPTIMISATION_ASKED, batteryOptimisationAsked)
+
try {
val jArray = JSONArray()
shareChatsInfo.forEach { (chatId, chatInfo) ->
@@ -332,6 +338,8 @@ class TelegramSettings(private val app: TelegramApplication) {
liveNowSortType = LiveNowSortType.valueOf(
prefs.getString(LIVE_NOW_SORT_TYPE_KEY, LiveNowSortType.SORT_BY_GROUP.name)
)
+
+ batteryOptimisationAsked = prefs.getBoolean(BATTERY_OPTIMISATION_ASKED,false)
}
private fun parseShareChatsInfo(json: JSONArray) {
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt
index 4cb3125c0b..cf21651e84 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt
@@ -335,12 +335,10 @@ class TelegramHelper private constructor() {
}
}
- fun getUserGreyPhotoPath(user: TdApi.User): String? {
- return if (hasGrayscaleUserPhoto(user.id)) {
- "$appDir/$GRAYSCALE_PHOTOS_DIR${user.id}$GRAYSCALE_PHOTOS_EXT"
- } else {
- null
- }
+ fun getUserGreyPhotoPath(user: TdApi.User?) = when {
+ user == null -> null
+ hasGrayscaleUserPhoto(user.id) -> "$appDir/$GRAYSCALE_PHOTOS_DIR${user.id}$GRAYSCALE_PHOTOS_EXT"
+ else -> null
}
fun getOsmAndBotDeviceName(message: TdApi.Message): String {
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/BatteryOptimizationBottomSheet.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/BatteryOptimizationBottomSheet.kt
new file mode 100644
index 0000000000..258015d897
--- /dev/null
+++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/BatteryOptimizationBottomSheet.kt
@@ -0,0 +1,91 @@
+package net.osmand.telegram.ui
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.PowerManager
+import android.provider.Settings
+import android.support.design.widget.BottomSheetBehavior
+import android.support.v4.app.DialogFragment
+import android.support.v4.app.FragmentManager
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import net.osmand.PlatformUtil
+import net.osmand.telegram.R
+import net.osmand.telegram.TelegramApplication
+import net.osmand.telegram.ui.views.BottomSheetDialog
+
+class BatteryOptimizationBottomSheet : DialogFragment() {
+
+ private val app: TelegramApplication
+ get() = activity?.application as TelegramApplication
+
+ private val log = PlatformUtil.getLog(BatteryOptimizationBottomSheet::class.java)
+
+ override fun onCreateDialog(savedInstanceState: Bundle?) = BottomSheetDialog(context!!)
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ val mainView = inflater.inflate(R.layout.bottom_sheet_battery_optimization, container, false)
+
+ mainView.findViewById(R.id.scroll_view_container).setOnClickListener { dismiss() }
+
+ BottomSheetBehavior.from(mainView.findViewById(R.id.scroll_view))
+ .setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
+
+ override fun onStateChanged(bottomSheet: View, newState: Int) {
+ if (newState == BottomSheetBehavior.STATE_HIDDEN) {
+ dismiss()
+ }
+ }
+
+ override fun onSlide(bottomSheet: View, slideOffset: Float) {}
+ })
+
+ mainView.findViewById(R.id.secondary_btn).apply {
+ setText(R.string.shared_string_later)
+ setOnClickListener { dismiss() }
+ }
+
+ mainView.findViewById(R.id.primary_btn).apply {
+ setText(R.string.go_to_settings)
+ setOnClickListener {
+ if (Build.VERSION.SDK_INT > 26) {
+ val pkg = app.packageName
+ val pm = app.getSystemService(PowerManager::class.java)
+ if (pm != null) {
+ val intent = if (!pm.isIgnoringBatteryOptimizations(pkg)) {
+ Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).setData(Uri.parse("package:$pkg"))
+ } else {
+ Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)
+ }
+ if (intent.resolveActivity(app.packageManager) != null) {
+ startActivity(intent)
+ } else {
+ log.error("No Intent available to handle action")
+ }
+ }
+ }
+ dismiss()
+ }
+ }
+
+ return mainView
+ }
+
+ companion object {
+
+ private const val TAG = "BatteryOptimizationBottomSheet"
+
+ fun showInstance(fm: FragmentManager): Boolean {
+ return try {
+ BatteryOptimizationBottomSheet().show(fm, TAG)
+ true
+ } catch (e: RuntimeException) {
+ false
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt
index cac0f6a229..684c5b954f 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt
@@ -245,6 +245,12 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
sharingMode = settings.hasAnyChatToShareLocation()
clearSelection()
updateContent()
+ if (sharingMode && !settings.batteryOptimisationAsked && Build.VERSION.SDK_INT >= 26) {
+ fragmentManager?.also { fm ->
+ BatteryOptimizationBottomSheet.showInstance(fm)
+ settings.batteryOptimisationAsked = true
+ }
+ }
}
DisableSharingBottomSheet.SHARING_DISABLED_REQUEST_CODE -> {
sharingMode = false
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt
index 9e79964551..1d749d87fb 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt
@@ -1,6 +1,7 @@
package net.osmand.telegram.ui
import android.content.Intent
+import android.os.Build
import android.os.Bundle
import android.support.v4.app.FragmentManager
import android.support.v7.widget.ListPopupWindow
@@ -15,6 +16,7 @@ import net.osmand.telegram.TelegramSettings
import net.osmand.telegram.TelegramSettings.DurationPref
import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.utils.AndroidUtils
+import org.drinkless.td.libcore.telegram.TdApi
class SettingsDialogFragment : BaseDialogFragment() {
@@ -50,6 +52,19 @@ class SettingsDialogFragment : BaseDialogFragment() {
}
}
+ if (Build.VERSION.SDK_INT >= 26) {
+ inflater.inflate(R.layout.item_with_desc_and_right_value, container, false).apply {
+ findViewById(R.id.icon).setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_background_work))
+ findViewById(R.id.title).text = getText(R.string.background_work)
+ findViewById(R.id.description).text = getText(R.string.background_work_description)
+ findViewById(R.id.value).visibility = View.GONE
+ setOnClickListener {
+ fragmentManager?.also { BatteryOptimizationBottomSheet.showInstance(it) }
+ }
+ container.addView(this)
+ }
+ }
+
container = mainView.findViewById(R.id.osmand_connect_container)
for (appConn in TelegramSettings.AppConnect.values()) {
val pack = appConn.appPackage
@@ -141,11 +156,15 @@ class SettingsDialogFragment : BaseDialogFragment() {
private fun addItemToContainer(inflater: LayoutInflater, container: ViewGroup, tag: String, title: String) {
inflater.inflate(R.layout.item_with_rb_and_btn, container, false).apply {
+ val checked = tag == settings.currentSharingMode
+
+ setupSharingModeIcon(this, checked, telegramHelper.getCurrentUser(), tag)
+
findViewById(R.id.title).text = title
findViewById(R.id.primary_btn).visibility = View.GONE
findViewById(R.id.radio_button).apply {
visibility = View.VISIBLE
- isChecked = tag == settings.currentSharingMode
+ isChecked = checked
}
setOnClickListener {
settings.currentSharingMode = tag
@@ -186,12 +205,31 @@ class SettingsDialogFragment : BaseDialogFragment() {
}
}
+ private fun setupSharingModeIcon(view: View, checked: Boolean, user: TdApi.User?, tag: String) {
+ if (tag == user?.id.toString()) {
+ val path = if (checked) {
+ telegramHelper.getUserPhotoPath(user)
+ } else {
+ telegramHelper.getUserGreyPhotoPath(user)
+ }
+ TelegramUiHelper.setupPhoto(app, view.findViewById(R.id.icon), path, R.drawable.img_user_picture, false)
+ } else {
+ val icon = if (checked) {
+ uiUtils.getActiveIcon(R.drawable.ic_device_picture)
+ } else {
+ uiUtils.getThemedIcon(R.drawable.ic_device_picture)
+ }
+ view.findViewById(R.id.icon).setImageDrawable(icon)
+ }
+ }
+
private fun updateSelectedSharingMode() {
view?.findViewById(R.id.share_as_container)?.apply {
for (i in 0 until childCount) {
getChildAt(i).apply {
- findViewById(R.id.radio_button).isChecked =
- tag == settings.currentSharingMode
+ val checked = tag == app.settings.currentSharingMode
+ setupSharingModeIcon(this, checked, telegramHelper.getCurrentUser(), tag.toString())
+ findViewById(R.id.radio_button).isChecked = checked
}
}
}