diff --git a/OsmAnd-telegram/AndroidManifest.xml b/OsmAnd-telegram/AndroidManifest.xml
index 3b98f7e1e8..a1863ff954 100644
--- a/OsmAnd-telegram/AndroidManifest.xml
+++ b/OsmAnd-telegram/AndroidManifest.xml
@@ -33,25 +33,14 @@
-
+
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/OsmAnd-telegram/res/values/strings.xml b/OsmAnd-telegram/res/values/strings.xml
index ca33f3ca50..87e368618c 100644
--- a/OsmAnd-telegram/res/values/strings.xml
+++ b/OsmAnd-telegram/res/values/strings.xml
@@ -27,7 +27,7 @@
Pause
Start
Stop
- OsmAnd Telegram location service
+ OsmAnd Telegram service
OsmAnd logo
You need to install free or paid version of OsmAnd first
Install OsmAnd
diff --git a/OsmAnd-telegram/src/net/osmand/PlatformUtil.java b/OsmAnd-telegram/src/net/osmand/PlatformUtil.java
index 06759253ff..9ec83421ae 100644
--- a/OsmAnd-telegram/src/net/osmand/PlatformUtil.java
+++ b/OsmAnd-telegram/src/net/osmand/PlatformUtil.java
@@ -4,143 +4,143 @@ import org.apache.commons.logging.Log;
public class PlatformUtil {
- public static String TAG = "net.osmand";
- private static class OsmandLogImplementation implements Log {
+ public static String TAG = "net.osmand";
- private final String fullName;
- private final String name;
+ private static class OsmandLogImplementation implements Log {
- public OsmandLogImplementation(String name){
- this.fullName = name;
- this.name = fullName.substring(fullName.lastIndexOf('.') + 1);
- }
+ private final String fullName;
+ private final String name;
- @Override
- public void trace(Object message) {
- if(isTraceEnabled()){
- android.util.Log.d(TAG, name + " " + message);
- }
- }
+ public OsmandLogImplementation(String name) {
+ this.fullName = name;
+ this.name = fullName.substring(fullName.lastIndexOf('.') + 1);
+ }
- @Override
- public void trace(Object message, Throwable t) {
- if(isTraceEnabled()){
- android.util.Log.d(TAG, name + " " + message, t);
- }
- }
+ @Override
+ public void trace(Object message) {
+ if (isTraceEnabled()) {
+ android.util.Log.d(TAG, name + " " + message);
+ }
+ }
- @Override
- public void debug(Object message) {
- if(isDebugEnabled()){
- android.util.Log.d(TAG, name + " " + message);
- }
- }
+ @Override
+ public void trace(Object message, Throwable t) {
+ if (isTraceEnabled()) {
+ android.util.Log.d(TAG, name + " " + message, t);
+ }
+ }
- @Override
- public void debug(Object message, Throwable t) {
- if(isDebugEnabled()){
- android.util.Log.d(TAG, name + " " + message, t);
- }
- }
+ @Override
+ public void debug(Object message) {
+ if (isDebugEnabled()) {
+ android.util.Log.d(TAG, name + " " + message);
+ }
+ }
- @Override
- public void error(Object message) {
- if(isErrorEnabled()){
- android.util.Log.e(TAG, name + " " + message);
- }
- }
+ @Override
+ public void debug(Object message, Throwable t) {
+ if (isDebugEnabled()) {
+ android.util.Log.d(TAG, name + " " + message, t);
+ }
+ }
- @Override
- public void error(Object message, Throwable t) {
- if(isErrorEnabled()){
- android.util.Log.e(TAG, name + " " + message, t);
- }
- }
+ @Override
+ public void error(Object message) {
+ if (isErrorEnabled()) {
+ android.util.Log.e(TAG, name + " " + message);
+ }
+ }
- @Override
- public void fatal(Object message) {
- if(isFatalEnabled()){
- android.util.Log.e(TAG, name + " " + message);
- }
+ @Override
+ public void error(Object message, Throwable t) {
+ if (isErrorEnabled()) {
+ android.util.Log.e(TAG, name + " " + message, t);
+ }
+ }
- }
+ @Override
+ public void fatal(Object message) {
+ if (isFatalEnabled()) {
+ android.util.Log.e(TAG, name + " " + message);
+ }
- @Override
- public void fatal(Object message, Throwable t) {
- if(isFatalEnabled()){
- android.util.Log.e(TAG, name + " " + message, t);
- }
- }
+ }
- @Override
- public void info(Object message) {
- if(isInfoEnabled()){
- android.util.Log.i(TAG, name + " " + message);
- }
- }
+ @Override
+ public void fatal(Object message, Throwable t) {
+ if (isFatalEnabled()) {
+ android.util.Log.e(TAG, name + " " + message, t);
+ }
+ }
- @Override
- public void info(Object message, Throwable t) {
- if(isInfoEnabled()){
- android.util.Log.i(TAG, name + " " + message, t);
- }
- }
+ @Override
+ public void info(Object message) {
+ if (isInfoEnabled()) {
+ android.util.Log.i(TAG, name + " " + message);
+ }
+ }
- @Override
- public boolean isTraceEnabled() {
- return android.util.Log.isLoggable(TAG, android.util.Log.VERBOSE);
- }
+ @Override
+ public void info(Object message, Throwable t) {
+ if (isInfoEnabled()) {
+ android.util.Log.i(TAG, name + " " + message, t);
+ }
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return android.util.Log.isLoggable(TAG, android.util.Log.VERBOSE);
+ }
+ @Override
+ public boolean isDebugEnabled() {
+ // For debug purposes always true
+ // return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
+ return true;
+ }
- @Override
- public boolean isDebugEnabled() {
- // For debug purposes always true
- // return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
- return true;
- }
+ @Override
+ public boolean isErrorEnabled() {
+ return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
+ }
- @Override
- public boolean isErrorEnabled() {
- return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
- }
+ @Override
+ public boolean isFatalEnabled() {
+ return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
+ }
- @Override
- public boolean isFatalEnabled() {
- return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
- }
+ @Override
+ public boolean isInfoEnabled() {
+ return android.util.Log.isLoggable(TAG, android.util.Log.INFO);
+ }
- @Override
- public boolean isInfoEnabled() {
- return android.util.Log.isLoggable(TAG, android.util.Log.INFO);
- }
+ @Override
+ public boolean isWarnEnabled() {
+ return android.util.Log.isLoggable(TAG, android.util.Log.WARN);
+ }
- @Override
- public boolean isWarnEnabled() {
- return android.util.Log.isLoggable(TAG, android.util.Log.WARN);
- }
+ @Override
+ public void warn(Object message) {
+ if (isWarnEnabled()) {
+ android.util.Log.w(TAG, name + " " + message);
+ }
+ }
- @Override
- public void warn(Object message) {
- if(isWarnEnabled()){
- android.util.Log.w(TAG, name + " " + message);
- }
- }
+ @Override
+ public void warn(Object message, Throwable t) {
+ if (isWarnEnabled()) {
+ android.util.Log.w(TAG, name + " " + message, t);
+ }
+ }
+ }
- @Override
- public void warn(Object message, Throwable t) {
- if(isWarnEnabled()){
- android.util.Log.w(TAG, name + " " + message, t);
- }
- }
- }
+ public static Log getLog(String name) {
+ return new OsmandLogImplementation(name);
+ }
- public static Log getLog(String name){
- return new OsmandLogImplementation(name);
- }
-
- public static Log getLog(Class> cl){
- return getLog(cl.getName());
- }
+ public static Log getLog(Class> cl) {
+ return getLog(cl.getName());
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/LoginDialogFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/LoginDialogFragment.kt
index 66b840bd13..41abbe5289 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/LoginDialogFragment.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/LoginDialogFragment.kt
@@ -17,182 +17,182 @@ import net.osmand.PlatformUtil
class LoginDialogFragment : DialogFragment() {
- companion object {
+ companion object {
- private const val TAG = "LoginDialogFragment"
- private val LOG = PlatformUtil.getLog(LoginDialogFragment::class.java)
+ private const val TAG = "LoginDialogFragment"
+ private val LOG = PlatformUtil.getLog(LoginDialogFragment::class.java)
- private const val ENTER_PHONE_NUMBER_PARAM_KEY: String = "enter_phone_number_param_key"
- private const val ENTER_CODE_PARAM_KEY = "enter_code_param_key"
- private const val ENTER_PASSWORD_PARAM_KEY = "enter_password_param_key"
- private const val SHOW_PROGRESS_PARAM_KEY = "show_progress_param_key"
+ private const val ENTER_PHONE_NUMBER_PARAM_KEY: String = "enter_phone_number_param_key"
+ private const val ENTER_CODE_PARAM_KEY = "enter_code_param_key"
+ private const val ENTER_PASSWORD_PARAM_KEY = "enter_password_param_key"
+ private const val SHOW_PROGRESS_PARAM_KEY = "show_progress_param_key"
- fun showDialog(fragmentManager: FragmentManager, vararg loginDialogType: LoginDialogType) {
- try {
- var fragment = getFragment(fragmentManager)
- if (fragment == null) {
- fragment = LoginDialogFragment()
- val args = Bundle()
- for (t in loginDialogType) {
- args.putBoolean(t.paramKey, true)
- }
- fragment.arguments = args
- fragment.show(fragmentManager, TAG)
- } else {
- fragment.updateDialog(*loginDialogType)
- }
- } catch (e: RuntimeException) {
- LOG.error(e)
- }
- }
+ fun showDialog(fragmentManager: FragmentManager, vararg loginDialogType: LoginDialogType) {
+ try {
+ var fragment = getFragment(fragmentManager)
+ if (fragment == null) {
+ fragment = LoginDialogFragment()
+ val args = Bundle()
+ for (t in loginDialogType) {
+ args.putBoolean(t.paramKey, true)
+ }
+ fragment.arguments = args
+ fragment.show(fragmentManager, TAG)
+ } else {
+ fragment.updateDialog(*loginDialogType)
+ }
+ } catch (e: RuntimeException) {
+ LOG.error(e)
+ }
+ }
- fun dismiss(fragmentManager: FragmentManager) {
- val loginDialogFragment = getFragment(fragmentManager)
- loginDialogFragment?.dismissedManually = true
- loginDialogFragment?.dismiss()
- }
+ fun dismiss(fragmentManager: FragmentManager) {
+ val loginDialogFragment = getFragment(fragmentManager)
+ loginDialogFragment?.dismissedManually = true
+ loginDialogFragment?.dismiss()
+ }
- private fun getFragment(fragmentManager: FragmentManager): LoginDialogFragment? {
- return fragmentManager.findFragmentByTag(TAG) as LoginDialogFragment?
- }
- }
+ private fun getFragment(fragmentManager: FragmentManager): LoginDialogFragment? {
+ return fragmentManager.findFragmentByTag(TAG) as LoginDialogFragment?
+ }
+ }
- private var loginDialogActiveTypes: Set? = null
+ private var loginDialogActiveTypes: Set? = null
- private var dismissedManually = false
+ private var dismissedManually = false
- enum class LoginDialogType(val paramKey: String, val viewId: Int, val editorId: Int) {
- ENTER_PHONE_NUMBER(ENTER_PHONE_NUMBER_PARAM_KEY, R.id.enterPhoneNumberLayout, R.id.phoneNumberEditText),
- ENTER_CODE(ENTER_CODE_PARAM_KEY, R.id.enterCodeLayout, R.id.codeEditText),
- ENTER_PASSWORD(ENTER_PASSWORD_PARAM_KEY, R.id.enterPasswordLayout, R.id.passwordEditText),
- SHOW_PROGRESS(SHOW_PROGRESS_PARAM_KEY, R.id.progressLayout, 0);
- }
+ enum class LoginDialogType(val paramKey: String, val viewId: Int, val editorId: Int) {
+ ENTER_PHONE_NUMBER(ENTER_PHONE_NUMBER_PARAM_KEY, R.id.enterPhoneNumberLayout, R.id.phoneNumberEditText),
+ ENTER_CODE(ENTER_CODE_PARAM_KEY, R.id.enterCodeLayout, R.id.codeEditText),
+ ENTER_PASSWORD(ENTER_PASSWORD_PARAM_KEY, R.id.enterPasswordLayout, R.id.passwordEditText),
+ SHOW_PROGRESS(SHOW_PROGRESS_PARAM_KEY, R.id.progressLayout, 0);
+ }
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setStyle(DialogFragment.STYLE_NO_FRAME, R.style.AppTheme_NoActionbar)
- val activity = requireActivity()
- val window = activity.window
- window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
- }
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setStyle(DialogFragment.STYLE_NO_FRAME, R.style.AppTheme_NoActionbar)
+ val activity = requireActivity()
+ val window = activity.window
+ window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
+ }
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- val loginDialogActiveTypes: MutableSet = HashSet()
+ val loginDialogActiveTypes: MutableSet = HashSet()
- val args = savedInstanceState ?: arguments
- if (args != null) {
- for (t in LoginDialogType.values()) {
- if (args.getBoolean(t.paramKey, false)) {
- loginDialogActiveTypes.add(t)
- }
- }
- }
+ val args = savedInstanceState ?: arguments
+ if (args != null) {
+ for (t in LoginDialogType.values()) {
+ if (args.getBoolean(t.paramKey, false)) {
+ loginDialogActiveTypes.add(t)
+ }
+ }
+ }
- this.loginDialogActiveTypes = loginDialogActiveTypes
+ this.loginDialogActiveTypes = loginDialogActiveTypes
- val view = inflater.inflate(R.layout.login_dialog, container)
- buildDialog(view)
- return view
- }
+ val view = inflater.inflate(R.layout.login_dialog, container)
+ buildDialog(view)
+ return view
+ }
- override fun onDismiss(dialog: DialogInterface?) {
- super.onDismiss(dialog)
- if (!dismissedManually) {
- getMainActivity()?.closeTelegram()
- }
- }
+ override fun onDismiss(dialog: DialogInterface?) {
+ super.onDismiss(dialog)
+ if (!dismissedManually) {
+ getMainActivity()?.closeTelegram()
+ }
+ }
- private fun buildDialog(view: View?) {
- val loginDialogActiveTypes = this.loginDialogActiveTypes
- var hasProgress = false
- var focusRequested = false
- for (t in LoginDialogType.values()) {
- val layout: View? = view?.findViewById(t.viewId)
- val contains = loginDialogActiveTypes?.contains(t) ?: false
- when {
- contains -> {
- if (t == LoginDialogType.SHOW_PROGRESS) {
- hasProgress = true
- }
- if (layout != null) {
- layout.visibility = View.VISIBLE
- val editText: EditText? = layout.findViewById(t.editorId)
- if (editText != null) {
- editText.setOnEditorActionListener { _, actionId, _ ->
- if (actionId == EditorInfo.IME_ACTION_DONE) {
- applyAuthParam(t, editText.text.toString())
- return@setOnEditorActionListener true
- }
- false
- }
- if (!focusRequested) {
- editText.requestFocus()
- AndroidUtils.softKeyboardDelayed(editText)
- focusRequested = true
- }
- }
- }
- }
- else -> layout?.visibility = View.GONE
- }
- }
- val continueButton: Button? = view?.findViewById(R.id.continueButton)
- if (continueButton != null) {
- continueButton.isEnabled = !hasProgress
- if (hasProgress) {
- continueButton.setOnClickListener(null)
- } else {
- continueButton.setOnClickListener {
- for (t in LoginDialogType.values()) {
- val layout: View? = view.findViewById(t.viewId)
- val contains = loginDialogActiveTypes?.contains(t) ?: false
- if (contains && layout != null) {
- val editText: EditText? = layout.findViewById(t.editorId)
- if (editText != null) {
- applyAuthParam(t, editText.text.toString())
- }
- }
- }
- }
- }
- }
- val cancelButton: Button? = view?.findViewById(R.id.calcelButton)
- cancelButton?.setOnClickListener {
- dismiss()
- }
- }
+ private fun buildDialog(view: View?) {
+ val loginDialogActiveTypes = this.loginDialogActiveTypes
+ var hasProgress = false
+ var focusRequested = false
+ for (t in LoginDialogType.values()) {
+ val layout: View? = view?.findViewById(t.viewId)
+ val contains = loginDialogActiveTypes?.contains(t) ?: false
+ when {
+ contains -> {
+ if (t == LoginDialogType.SHOW_PROGRESS) {
+ hasProgress = true
+ }
+ if (layout != null) {
+ layout.visibility = View.VISIBLE
+ val editText: EditText? = layout.findViewById(t.editorId)
+ if (editText != null) {
+ editText.setOnEditorActionListener { _, actionId, _ ->
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ applyAuthParam(t, editText.text.toString())
+ return@setOnEditorActionListener true
+ }
+ false
+ }
+ if (!focusRequested) {
+ editText.requestFocus()
+ AndroidUtils.softKeyboardDelayed(editText)
+ focusRequested = true
+ }
+ }
+ }
+ }
+ else -> layout?.visibility = View.GONE
+ }
+ }
+ val continueButton: Button? = view?.findViewById(R.id.continueButton)
+ if (continueButton != null) {
+ continueButton.isEnabled = !hasProgress
+ if (hasProgress) {
+ continueButton.setOnClickListener(null)
+ } else {
+ continueButton.setOnClickListener {
+ for (t in LoginDialogType.values()) {
+ val layout: View? = view.findViewById(t.viewId)
+ val contains = loginDialogActiveTypes?.contains(t) ?: false
+ if (contains && layout != null) {
+ val editText: EditText? = layout.findViewById(t.editorId)
+ if (editText != null) {
+ applyAuthParam(t, editText.text.toString())
+ }
+ }
+ }
+ }
+ }
+ }
+ val cancelButton: Button? = view?.findViewById(R.id.calcelButton)
+ cancelButton?.setOnClickListener {
+ dismiss()
+ }
+ }
- private fun applyAuthParam(t: LoginDialogType, value: String) {
- getMainActivity()?.applyAuthParam(this, t, value)
- }
+ private fun applyAuthParam(t: LoginDialogType, value: String) {
+ getMainActivity()?.applyAuthParam(this, t, value)
+ }
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- val loginDialogActiveTypes = this.loginDialogActiveTypes
- if (loginDialogActiveTypes != null) {
- for (t in loginDialogActiveTypes) {
- outState.putBoolean(t.paramKey, true)
- }
- }
- }
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ val loginDialogActiveTypes = this.loginDialogActiveTypes
+ if (loginDialogActiveTypes != null) {
+ for (t in loginDialogActiveTypes) {
+ outState.putBoolean(t.paramKey, true)
+ }
+ }
+ }
- private fun getMainActivity(): MainActivity? {
- val activity = this.activity
- return if (activity != null) {
- activity as MainActivity
- } else {
- null
- }
- }
+ private fun getMainActivity(): MainActivity? {
+ val activity = this.activity
+ return if (activity != null) {
+ activity as MainActivity
+ } else {
+ null
+ }
+ }
- fun updateDialog(vararg loginDialogType: LoginDialogType) {
- val loginDialogActiveTypes: MutableSet = HashSet()
- for (t in loginDialogType) {
- loginDialogActiveTypes.add(t)
- }
- this.loginDialogActiveTypes = loginDialogActiveTypes
+ fun updateDialog(vararg loginDialogType: LoginDialogType) {
+ val loginDialogActiveTypes: MutableSet = HashSet()
+ for (t in loginDialogType) {
+ loginDialogActiveTypes.add(t)
+ }
+ this.loginDialogActiveTypes = loginDialogActiveTypes
- buildDialog(view)
- }
+ buildDialog(view)
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt b/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt
index 66e0356a30..4828358de2 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt
@@ -23,370 +23,376 @@ import org.drinkless.td.libcore.telegram.TdApi
class MainActivity : AppCompatActivity(), TelegramListener {
- companion object {
- private const val PERMISSION_REQUEST_LOCATION = 1
+ companion object {
+ private const val PERMISSION_REQUEST_LOCATION = 1
- private const val LOGIN_MENU_ID = 0
- private const val LOGOUT_MENU_ID = 1
- private const val PROGRESS_MENU_ID = 2
- }
+ private const val LOGIN_MENU_ID = 0
+ private const val LOGOUT_MENU_ID = 1
+ private const val PROGRESS_MENU_ID = 2
+ }
- private val log = PlatformUtil.getLog(TelegramHelper::class.java)
+ private val log = PlatformUtil.getLog(TelegramHelper::class.java)
- private var telegramAuthorizationRequestHandler: TelegramAuthorizationRequestHandler? = null
- private var paused: Boolean = false
+ private var telegramAuthorizationRequestHandler: TelegramAuthorizationRequestHandler? = null
+ private var paused: Boolean = false
- private lateinit var chatsView: RecyclerView
- private lateinit var chatViewAdapter: ChatsAdapter
- private lateinit var chatViewManager: RecyclerView.LayoutManager
+ private lateinit var chatsView: RecyclerView
+ private lateinit var chatViewAdapter: ChatsAdapter
+ private lateinit var chatViewManager: RecyclerView.LayoutManager
- private val app: TelegramApplication
- get() = application as TelegramApplication
+ private val app: TelegramApplication
+ get() = application as TelegramApplication
- private val telegramHelper get() = app.telegramHelper
- private val osmandHelper get() = app.osmandHelper
- private val settings get() = app.settings
+ private val telegramHelper get() = app.telegramHelper
+ private val osmandHelper get() = app.osmandHelper
+ private val settings get() = app.settings
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
- paused = false
+ paused = false
- chatViewManager = LinearLayoutManager(this)
- chatViewAdapter = ChatsAdapter()
+ chatViewManager = LinearLayoutManager(this)
+ chatViewAdapter = ChatsAdapter()
- chatsView = findViewById(R.id.groups_view).apply {
- //setHasFixedSize(true)
+ chatsView = findViewById(R.id.groups_view).apply {
+ //setHasFixedSize(true)
- // use a linear layout manager
- layoutManager = chatViewManager
+ // use a linear layout manager
+ layoutManager = chatViewManager
- // specify an viewAdapter (see also next example)
- adapter = chatViewAdapter
+ // specify an viewAdapter (see also next example)
+ adapter = chatViewAdapter
- }
+ }
- telegramAuthorizationRequestHandler = telegramHelper.setTelegramAuthorizationRequestHandler(object : TelegramAuthorizationRequestListener {
- override fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType) {
- runOnUi {
- showLoginDialog(parameterType)
- }
- }
+ telegramAuthorizationRequestHandler = telegramHelper.setTelegramAuthorizationRequestHandler(object : TelegramAuthorizationRequestListener {
+ override fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType) {
+ runOnUi {
+ showLoginDialog(parameterType)
+ }
+ }
- override fun onTelegramAuthorizationRequestError(code: Int, message: String) {
- runOnUi {
- Toast.makeText(this@MainActivity, "$code - $message", Toast.LENGTH_LONG).show()
- }
- }
- })
- telegramHelper.listener = this
- telegramHelper.init()
- }
+ override fun onTelegramAuthorizationRequestError(code: Int, message: String) {
+ runOnUi {
+ Toast.makeText(this@MainActivity, "$code - $message", Toast.LENGTH_LONG).show()
+ }
+ }
+ })
+ telegramHelper.listener = this
+ telegramHelper.init()
+ }
- override fun onResume() {
- super.onResume()
- paused = false
+ override fun onResume() {
+ super.onResume()
+ paused = false
- invalidateOptionsMenu()
- updateTitle()
+ invalidateOptionsMenu()
+ updateTitle()
- if (settings.hasAnyChatToShareLocation() && !AndroidUtils.isLocationPermissionAvailable(this)) {
- requestLocationPermission()
- } else if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
- showOsmandMissingDialog()
- }
- }
+ if (settings.hasAnyChatToShareLocation() && !AndroidUtils.isLocationPermissionAvailable(this)) {
+ requestLocationPermission()
+ } else if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
+ showOsmandMissingDialog()
+ }
+ }
- override fun onPause() {
- super.onPause()
- paused = true
- }
+ override fun onPause() {
+ super.onPause()
+ paused = true
+ }
- override fun onStop() {
- super.onStop()
- settings.save()
- }
+ override fun onStop() {
+ super.onStop()
+ settings.save()
+ }
- override fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState,
- newTelegramAuthorizationState: TelegramAuthorizationState) {
- runOnUi {
- val fm = supportFragmentManager
- when (newTelegramAuthorizationState) {
- TelegramAuthorizationState.READY,
- TelegramAuthorizationState.CLOSED,
- TelegramAuthorizationState.UNKNOWN -> LoginDialogFragment.dismiss(fm)
- else -> Unit
- }
- invalidateOptionsMenu()
- updateTitle()
+ override fun onDestroy() {
+ super.onDestroy()
- when (newTelegramAuthorizationState) {
- TelegramAuthorizationState.READY -> {
- updateChatsList()
- }
- TelegramAuthorizationState.CLOSED,
- TelegramAuthorizationState.UNKNOWN -> {
- chatViewAdapter.chats = emptyList()
- }
- else -> Unit
- }
- }
- }
+ app.cleanupResources()
+ }
- override fun onTelegramChatsRead() {
- runOnUi {
- removeNonexistingChatsFromSettings()
- updateChatsList()
- }
- }
+ override fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState,
+ newTelegramAuthorizationState: TelegramAuthorizationState) {
+ runOnUi {
+ val fm = supportFragmentManager
+ when (newTelegramAuthorizationState) {
+ TelegramAuthorizationState.READY,
+ TelegramAuthorizationState.CLOSED,
+ TelegramAuthorizationState.UNKNOWN -> LoginDialogFragment.dismiss(fm)
+ else -> Unit
+ }
+ invalidateOptionsMenu()
+ updateTitle()
- override fun onTelegramChatsChanged() {
- runOnUi {
- updateChatsList()
- }
- }
+ when (newTelegramAuthorizationState) {
+ TelegramAuthorizationState.READY -> {
+ updateChatsList()
+ }
+ TelegramAuthorizationState.CLOSED,
+ TelegramAuthorizationState.UNKNOWN -> {
+ chatViewAdapter.chats = emptyList()
+ }
+ else -> Unit
+ }
+ }
+ }
- override fun onTelegramError(code: Int, message: String) {
- runOnUi {
- Toast.makeText(this@MainActivity, "$code - $message", Toast.LENGTH_LONG).show()
- }
- }
+ override fun onTelegramChatsRead() {
+ runOnUi {
+ removeNonexistingChatsFromSettings()
+ updateChatsList()
+ }
+ }
- override fun onSendLiveLicationError(code: Int, message: String) {
- log.error("Send live location error: $code - $message")
- app.isInternetConnectionAvailable(true)
- }
+ override fun onTelegramChatsChanged() {
+ runOnUi {
+ updateChatsList()
+ }
+ }
- private fun removeNonexistingChatsFromSettings() {
- val presentChatTitles = telegramHelper.getChatTitles()
- settings.removeNonexistingChats(presentChatTitles)
- }
+ override fun onTelegramError(code: Int, message: String) {
+ runOnUi {
+ Toast.makeText(this@MainActivity, "$code - $message", Toast.LENGTH_LONG).show()
+ }
+ }
- private fun updateChatsList() {
- val chatList = telegramHelper.getChatList()
- val chats: MutableList = mutableListOf()
- for (orderedChat in chatList) {
- val chat = telegramHelper.getChat(orderedChat.chatId)
- if (chat != null) {
- chats.add(chat)
- }
- }
- chatViewAdapter.chats = chats
- }
+ override fun onSendLiveLicationError(code: Int, message: String) {
+ log.error("Send live location error: $code - $message")
+ app.isInternetConnectionAvailable(true)
+ }
- fun logoutTelegram(silent: Boolean = false) {
- if (telegramHelper.getTelegramAuthorizationState() == TelegramAuthorizationState.READY) {
- telegramHelper.logout()
- } else {
- invalidateOptionsMenu()
- updateTitle()
- if (!silent) {
- Toast.makeText(this, R.string.not_logged_in, Toast.LENGTH_SHORT).show()
- }
- }
- }
+ private fun removeNonexistingChatsFromSettings() {
+ val presentChatTitles = telegramHelper.getChatTitles()
+ settings.removeNonexistingChats(presentChatTitles)
+ }
- fun closeTelegram() {
- telegramHelper.close()
- }
+ private fun updateChatsList() {
+ val chatList = telegramHelper.getChatList()
+ val chats: MutableList = mutableListOf()
+ for (orderedChat in chatList) {
+ val chat = telegramHelper.getChat(orderedChat.chatId)
+ if (chat != null) {
+ chats.add(chat)
+ }
+ }
+ chatViewAdapter.chats = chats
+ }
- private fun runOnUi(action: (() -> Unit)) {
- if (!paused) {
- runOnUiThread(action)
- }
- }
+ fun logoutTelegram(silent: Boolean = false) {
+ if (telegramHelper.getTelegramAuthorizationState() == TelegramAuthorizationState.READY) {
+ telegramHelper.logout()
+ } else {
+ invalidateOptionsMenu()
+ updateTitle()
+ if (!silent) {
+ Toast.makeText(this, R.string.not_logged_in, Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
- override fun onOptionsItemSelected(item: MenuItem?): Boolean {
- return when (item?.itemId) {
- LOGIN_MENU_ID -> {
- telegramHelper.init()
- true
- }
- LOGOUT_MENU_ID -> {
- logoutTelegram()
- true
- }
- else -> super.onOptionsItemSelected(item)
- }
- }
+ fun closeTelegram() {
+ telegramHelper.close()
+ }
- override fun onCreateOptionsMenu(menu: Menu?): Boolean {
- if (menu != null) {
- menu.clear()
- when (telegramHelper.getTelegramAuthorizationState()) {
- TelegramAuthorizationState.UNKNOWN,
- TelegramAuthorizationState.WAIT_PARAMETERS,
- TelegramAuthorizationState.WAIT_PHONE_NUMBER,
- TelegramAuthorizationState.WAIT_CODE,
- TelegramAuthorizationState.WAIT_PASSWORD,
- TelegramAuthorizationState.LOGGING_OUT,
- TelegramAuthorizationState.CLOSING -> createProgressMenuItem(menu)
- TelegramAuthorizationState.READY -> createMenuItem(menu, LOGOUT_MENU_ID, R.string.shared_string_logout,
- MenuItem.SHOW_AS_ACTION_WITH_TEXT or MenuItem.SHOW_AS_ACTION_ALWAYS)
- TelegramAuthorizationState.CLOSED -> createMenuItem(menu, LOGIN_MENU_ID, R.string.shared_string_login,
- MenuItem.SHOW_AS_ACTION_WITH_TEXT or MenuItem.SHOW_AS_ACTION_ALWAYS)
- }
- }
- return super.onCreateOptionsMenu(menu)
- }
+ private fun runOnUi(action: (() -> Unit)) {
+ if (!paused) {
+ runOnUiThread(action)
+ }
+ }
- private fun createMenuItem(m: Menu, id: Int, titleRes: Int, menuItemType: Int): MenuItem {
- val menuItem = m.add(0, id, 0, titleRes)
- menuItem.setOnMenuItemClickListener { item -> onOptionsItemSelected(item) }
- menuItem.setShowAsAction(menuItemType)
- return menuItem
- }
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+ return when (item?.itemId) {
+ LOGIN_MENU_ID -> {
+ telegramHelper.init()
+ true
+ }
+ LOGOUT_MENU_ID -> {
+ logoutTelegram()
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+ }
- private fun createProgressMenuItem(m: Menu): MenuItem {
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ if (menu != null) {
+ menu.clear()
+ when (telegramHelper.getTelegramAuthorizationState()) {
+ TelegramAuthorizationState.UNKNOWN,
+ TelegramAuthorizationState.WAIT_PARAMETERS,
+ TelegramAuthorizationState.WAIT_PHONE_NUMBER,
+ TelegramAuthorizationState.WAIT_CODE,
+ TelegramAuthorizationState.WAIT_PASSWORD,
+ TelegramAuthorizationState.LOGGING_OUT,
+ TelegramAuthorizationState.CLOSING -> createProgressMenuItem(menu)
+ TelegramAuthorizationState.READY -> createMenuItem(menu, LOGOUT_MENU_ID, R.string.shared_string_logout,
+ MenuItem.SHOW_AS_ACTION_WITH_TEXT or MenuItem.SHOW_AS_ACTION_ALWAYS)
+ TelegramAuthorizationState.CLOSED -> createMenuItem(menu, LOGIN_MENU_ID, R.string.shared_string_login,
+ MenuItem.SHOW_AS_ACTION_WITH_TEXT or MenuItem.SHOW_AS_ACTION_ALWAYS)
+ }
+ }
+ return super.onCreateOptionsMenu(menu)
+ }
- val menuItem = m.add(0, PROGRESS_MENU_ID, 0, "")
- menuItem.actionView = layoutInflater.inflate(R.layout.action_progress_bar, null)
- menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
- return menuItem
- }
+ private fun createMenuItem(m: Menu, id: Int, titleRes: Int, menuItemType: Int): MenuItem {
+ val menuItem = m.add(0, id, 0, titleRes)
+ menuItem.setOnMenuItemClickListener { item -> onOptionsItemSelected(item) }
+ menuItem.setShowAsAction(menuItemType)
+ return menuItem
+ }
- private fun updateTitle() {
- title = when (telegramHelper.getTelegramAuthorizationState()) {
+ private fun createProgressMenuItem(m: Menu): MenuItem {
- TelegramAuthorizationState.UNKNOWN,
- TelegramAuthorizationState.WAIT_PHONE_NUMBER,
- TelegramAuthorizationState.WAIT_CODE,
- TelegramAuthorizationState.WAIT_PASSWORD,
- TelegramAuthorizationState.READY,
- TelegramAuthorizationState.CLOSED -> getString(R.string.app_name)
+ val menuItem = m.add(0, PROGRESS_MENU_ID, 0, "")
+ menuItem.actionView = layoutInflater.inflate(R.layout.action_progress_bar, null)
+ menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
+ return menuItem
+ }
- TelegramAuthorizationState.WAIT_PARAMETERS -> getString(R.string.initialization) + "..."
- TelegramAuthorizationState.LOGGING_OUT -> getString(R.string.logging_out) + "..."
- TelegramAuthorizationState.CLOSING -> getString(R.string.closing) + "..."
- }
- }
+ private fun updateTitle() {
+ title = when (telegramHelper.getTelegramAuthorizationState()) {
- private fun showLoginDialog(telegramAuthenticationParameterType: TelegramAuthenticationParameterType) {
- when (telegramAuthenticationParameterType) {
- TelegramAuthenticationParameterType.PHONE_NUMBER -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PHONE_NUMBER)
- TelegramAuthenticationParameterType.CODE -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_CODE)
- TelegramAuthenticationParameterType.PASSWORD -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PASSWORD)
- }
- }
+ TelegramAuthorizationState.UNKNOWN,
+ TelegramAuthorizationState.WAIT_PHONE_NUMBER,
+ TelegramAuthorizationState.WAIT_CODE,
+ TelegramAuthorizationState.WAIT_PASSWORD,
+ TelegramAuthorizationState.READY,
+ TelegramAuthorizationState.CLOSED -> getString(R.string.app_name)
- fun applyAuthParam(loginDialogFragment: LoginDialogFragment?, loginDialogType: LoginDialogType, text: String) {
- loginDialogFragment?.updateDialog(LoginDialogType.SHOW_PROGRESS)
- when (loginDialogType) {
- LoginDialogType.ENTER_PHONE_NUMBER -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.PHONE_NUMBER, text)
- LoginDialogType.ENTER_CODE -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.CODE, text)
- LoginDialogType.ENTER_PASSWORD -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.PASSWORD, text)
- else -> Unit
- }
- }
+ TelegramAuthorizationState.WAIT_PARAMETERS -> getString(R.string.initialization) + "..."
+ TelegramAuthorizationState.LOGGING_OUT -> getString(R.string.logging_out) + "..."
+ TelegramAuthorizationState.CLOSING -> getString(R.string.closing) + "..."
+ }
+ }
- private fun requestLocationPermission() {
- ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_LOCATION)
- }
+ private fun showLoginDialog(telegramAuthenticationParameterType: TelegramAuthenticationParameterType) {
+ when (telegramAuthenticationParameterType) {
+ TelegramAuthenticationParameterType.PHONE_NUMBER -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PHONE_NUMBER)
+ TelegramAuthenticationParameterType.CODE -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_CODE)
+ TelegramAuthenticationParameterType.PASSWORD -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PASSWORD)
+ }
+ }
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- when (requestCode) {
- PERMISSION_REQUEST_LOCATION -> {
- if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- if (settings.hasAnyChatToShareLocation()) {
- app.shareLocationHelper.startSharingLocation()
- }
- }
- if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
- showOsmandMissingDialog()
- }
- }
- }
- }
+ fun applyAuthParam(loginDialogFragment: LoginDialogFragment?, loginDialogType: LoginDialogType, text: String) {
+ loginDialogFragment?.updateDialog(LoginDialogType.SHOW_PROGRESS)
+ when (loginDialogType) {
+ LoginDialogType.ENTER_PHONE_NUMBER -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.PHONE_NUMBER, text)
+ LoginDialogType.ENTER_CODE -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.CODE, text)
+ LoginDialogType.ENTER_PASSWORD -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.PASSWORD, text)
+ else -> Unit
+ }
+ }
- fun showOsmandMissingDialog() {
- OsmandMissingDialogFragment().show(supportFragmentManager, null)
- }
+ private fun requestLocationPermission() {
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_LOCATION)
+ }
- class OsmandMissingDialogFragment : DialogFragment() {
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ when (requestCode) {
+ PERMISSION_REQUEST_LOCATION -> {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ if (settings.hasAnyChatToShareLocation()) {
+ app.shareLocationHelper.startSharingLocation()
+ }
+ }
+ if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
+ showOsmandMissingDialog()
+ }
+ }
+ }
+ }
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val builder = AlertDialog.Builder(requireContext())
- builder.setView(R.layout.install_osmand_dialog)
- .setNegativeButton("Cancel", null)
- .setPositiveButton("Install", { _, _ ->
- val intent = Intent()
- intent.data = Uri.parse("market://details?id=net.osmand.plus")
- startActivity(intent)
- })
- return builder.create()
- }
- }
+ fun showOsmandMissingDialog() {
+ OsmandMissingDialogFragment().show(supportFragmentManager, null)
+ }
- inner class ChatsAdapter :
- RecyclerView.Adapter() {
+ class OsmandMissingDialogFragment : DialogFragment() {
- var chats: List = emptyList()
- set(value) {
- field = value
- notifyDataSetChanged()
- }
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val builder = AlertDialog.Builder(requireContext())
+ builder.setView(R.layout.install_osmand_dialog)
+ .setNegativeButton("Cancel", null)
+ .setPositiveButton("Install", { _, _ ->
+ val intent = Intent()
+ intent.data = Uri.parse("market://details?id=net.osmand.plus")
+ startActivity(intent)
+ })
+ return builder.create()
+ }
+ }
- inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
- val icon: AppCompatImageView? = view.findViewById(R.id.icon)
- val groupName: AppCompatTextView? = view.findViewById(R.id.name)
- val shareLocationSwitch: SwitchCompat? = view.findViewById(R.id.share_location_switch)
- val showOnMapSwitch: SwitchCompat? = view.findViewById(R.id.show_on_map_switch)
- }
+ inner class ChatsAdapter :
+ RecyclerView.Adapter() {
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatsAdapter.ViewHolder {
- val view = LayoutInflater.from(parent.context).inflate(R.layout.chat_list_item, parent, false)
- return ViewHolder(view)
- }
+ var chats: List = emptyList()
+ set(value) {
+ field = value
+ notifyDataSetChanged()
+ }
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val chatTitle = chats[position].title
- holder.groupName?.text = chatTitle
+ inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
+ val icon: AppCompatImageView? = view.findViewById(R.id.icon)
+ val groupName: AppCompatTextView? = view.findViewById(R.id.name)
+ val shareLocationSwitch: SwitchCompat? = view.findViewById(R.id.share_location_switch)
+ val showOnMapSwitch: SwitchCompat? = view.findViewById(R.id.show_on_map_switch)
+ }
- holder.shareLocationSwitch?.setOnCheckedChangeListener(null)
- holder.shareLocationSwitch?.isChecked = settings.isSharingLocationToChat(chatTitle)
- holder.shareLocationSwitch?.setOnCheckedChangeListener { view, isChecked ->
- settings.shareLocationToChat(chatTitle, isChecked)
- if (settings.hasAnyChatToShareLocation()) {
- if (!AndroidUtils.isLocationPermissionAvailable(view.context)) {
- if (isChecked) {
- requestLocationPermission()
- }
- } else {
- app.shareLocationHelper.startSharingLocation()
- }
- } else {
- app.shareLocationHelper.stopSharingLocation()
- }
- }
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatsAdapter.ViewHolder {
+ val view = LayoutInflater.from(parent.context).inflate(R.layout.chat_list_item, parent, false)
+ return ViewHolder(view)
+ }
- holder.showOnMapSwitch?.setOnCheckedChangeListener(null)
- holder.showOnMapSwitch?.isChecked = settings.isShowingChatOnMap(chatTitle)
- holder.showOnMapSwitch?.setOnCheckedChangeListener { _, isChecked ->
- settings.showChatOnMap(chatTitle, isChecked)
- if (settings.hasAnyChatToShowOnMap()) {
- if (osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
- if (isChecked) {
- showOsmandMissingDialog()
- }
- } else {
- if (isChecked) {
- app.showLocationHelper.showChatMessages(chatTitle)
- } else {
- app.showLocationHelper.hideChatMessages(chatTitle)
- }
- app.showLocationHelper.startShowingLocation()
- }
- } else {
- app.showLocationHelper.stopShowingLocation()
- if (!isChecked) {
- app.showLocationHelper.hideChatMessages(chatTitle)
- }
- }
- }
- }
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val chatTitle = chats[position].title
+ holder.groupName?.text = chatTitle
- override fun getItemCount() = chats.size
- }
+ holder.shareLocationSwitch?.setOnCheckedChangeListener(null)
+ holder.shareLocationSwitch?.isChecked = settings.isSharingLocationToChat(chatTitle)
+ holder.shareLocationSwitch?.setOnCheckedChangeListener { view, isChecked ->
+ settings.shareLocationToChat(chatTitle, isChecked)
+ if (settings.hasAnyChatToShareLocation()) {
+ if (!AndroidUtils.isLocationPermissionAvailable(view.context)) {
+ if (isChecked) {
+ requestLocationPermission()
+ }
+ } else {
+ app.shareLocationHelper.startSharingLocation()
+ }
+ } else {
+ app.shareLocationHelper.stopSharingLocation()
+ }
+ }
+
+ holder.showOnMapSwitch?.setOnCheckedChangeListener(null)
+ holder.showOnMapSwitch?.isChecked = settings.isShowingChatOnMap(chatTitle)
+ holder.showOnMapSwitch?.setOnCheckedChangeListener { _, isChecked ->
+ settings.showChatOnMap(chatTitle, isChecked)
+ if (settings.hasAnyChatToShowOnMap()) {
+ if (osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
+ if (isChecked) {
+ showOsmandMissingDialog()
+ }
+ } else {
+ if (isChecked) {
+ app.showLocationHelper.showChatMessages(chatTitle)
+ } else {
+ app.showLocationHelper.hideChatMessages(chatTitle)
+ }
+ app.showLocationHelper.startShowingLocation()
+ }
+ } else {
+ app.showLocationHelper.stopShowingLocation()
+ if (!isChecked) {
+ app.showLocationHelper.hideChatMessages(chatTitle)
+ }
+ }
+ }
+ }
+
+ override fun getItemCount() = chats.size
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt
index 3cc75dd9eb..81e849a079 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt
@@ -12,128 +12,117 @@ import net.osmand.telegram.helpers.ShareLocationHelper
import net.osmand.telegram.helpers.ShowLocationHelper
import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.notifications.NotificationHelper
-import net.osmand.telegram.services.MyLocationService
-import net.osmand.telegram.services.UserLocationService
import net.osmand.telegram.utils.AndroidUtils
class TelegramApplication : Application() {
- val telegramHelper = TelegramHelper.instance
- lateinit var settings: TelegramSettings private set
- lateinit var shareLocationHelper: ShareLocationHelper private set
- lateinit var showLocationHelper: ShowLocationHelper private set
- lateinit var notificationHelper: NotificationHelper private set
- lateinit var osmandHelper: OsmandAidlHelper private set
+ val telegramHelper = TelegramHelper.instance
+ lateinit var settings: TelegramSettings private set
+ lateinit var shareLocationHelper: ShareLocationHelper private set
+ lateinit var showLocationHelper: ShowLocationHelper private set
+ lateinit var notificationHelper: NotificationHelper private set
+ lateinit var osmandHelper: OsmandAidlHelper private set
- var myLocationService: MyLocationService? = null
- var userLocationService: UserLocationService? = null
+ var telegramService: TelegramService? = null
- private val uiHandler = Handler()
+ private val uiHandler = Handler()
- private val lastTimeInternetConnectionChecked: Long = 0
- private var internetConnectionAvailable = true
+ private val lastTimeInternetConnectionChecked: Long = 0
+ private var internetConnectionAvailable = true
- override fun onCreate() {
- super.onCreate()
- telegramHelper.appDir = filesDir.absolutePath
+ override fun onCreate() {
+ super.onCreate()
+ telegramHelper.appDir = filesDir.absolutePath
- settings = TelegramSettings(this)
- osmandHelper = OsmandAidlHelper(this)
- shareLocationHelper = ShareLocationHelper(this)
- showLocationHelper = ShowLocationHelper(this)
- notificationHelper = NotificationHelper(this)
+ settings = TelegramSettings(this)
+ osmandHelper = OsmandAidlHelper(this)
+ shareLocationHelper = ShareLocationHelper(this)
+ showLocationHelper = ShowLocationHelper(this)
+ notificationHelper = NotificationHelper(this)
- if (settings.hasAnyChatToShareLocation() && AndroidUtils.isLocationPermissionAvailable(this)) {
- shareLocationHelper.startSharingLocation()
- }
- if (settings.hasAnyChatToShowOnMap()) {
- showLocationHelper.startShowingLocation()
- }
- }
+ if (settings.hasAnyChatToShareLocation() && AndroidUtils.isLocationPermissionAvailable(this)) {
+ shareLocationHelper.startSharingLocation()
+ }
+ if (settings.hasAnyChatToShowOnMap()) {
+ showLocationHelper.startShowingLocation()
+ }
+ }
- override fun onTerminate() {
- super.onTerminate()
- // TODO close telegram api in appropriate place
- osmandHelper.cleanupResources()
- telegramHelper.close()
- }
+ fun cleanupResources() {
+ osmandHelper.cleanupResources()
+ telegramHelper.close()
+ }
- val isWifiConnected: Boolean
- get() {
- val mgr = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
- val ni = mgr.activeNetworkInfo
- return ni != null && ni.type == ConnectivityManager.TYPE_WIFI
- }
+ val isWifiConnected: Boolean
+ get() {
+ val mgr = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ val ni = mgr.activeNetworkInfo
+ return ni != null && ni.type == ConnectivityManager.TYPE_WIFI
+ }
- private val isInternetConnected: Boolean
- get() {
- val mgr = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
- val active = mgr.activeNetworkInfo
- if (active == null) {
- return false
- } else {
- val state = active.state
- return state != NetworkInfo.State.DISCONNECTED && state != NetworkInfo.State.DISCONNECTING
- }
- }
+ private val isInternetConnected: Boolean
+ get() {
+ val mgr = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ val active = mgr.activeNetworkInfo
+ if (active == null) {
+ return false
+ } else {
+ val state = active.state
+ return state != NetworkInfo.State.DISCONNECTED && state != NetworkInfo.State.DISCONNECTING
+ }
+ }
- // Check internet connection available every 15 seconds
- val isInternetConnectionAvailable: Boolean
- get() = isInternetConnectionAvailable(false)
+ // Check internet connection available every 15 seconds
+ val isInternetConnectionAvailable: Boolean
+ get() = isInternetConnectionAvailable(false)
- fun isInternetConnectionAvailable(update: Boolean): Boolean {
- val delta = System.currentTimeMillis() - lastTimeInternetConnectionChecked
- if (delta < 0 || delta > 15000 || update) {
- internetConnectionAvailable = isInternetConnected
- }
- return internetConnectionAvailable
- }
+ fun isInternetConnectionAvailable(update: Boolean): Boolean {
+ val delta = System.currentTimeMillis() - lastTimeInternetConnectionChecked
+ if (delta < 0 || delta > 15000 || update) {
+ internetConnectionAvailable = isInternetConnected
+ }
+ return internetConnectionAvailable
+ }
- fun startMyLocationService(restart: Boolean = false) {
- val serviceIntent = Intent(this, MyLocationService::class.java)
+ private fun startTelegramService(intent: Int) {
+ var i = intent
+ val serviceIntent = Intent(this, TelegramService::class.java)
- val myLocationService = myLocationService
- if (myLocationService != null && restart) {
- myLocationService.stopSelf()
- }
- if (myLocationService == null || restart) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- startForegroundService(serviceIntent)
- } else {
- startService(serviceIntent)
- }
- }
- }
+ val telegramService = telegramService
+ if (telegramService != null) {
+ i = intent or telegramService.usedBy
+ telegramService.stopSelf()
+ }
- fun stopMyLocationService() {
- myLocationService?.stopIfNeeded(this)
- }
+ serviceIntent.putExtra(TelegramService.USAGE_INTENT, i)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ startForegroundService(serviceIntent)
+ } else {
+ startService(serviceIntent)
+ }
+ }
- fun startUserLocationService(restart: Boolean = false) {
- val serviceIntent = Intent(this, UserLocationService::class.java)
+ fun startMyLocationService() {
+ startTelegramService(TelegramService.USED_BY_MY_LOCATION)
+ }
- val userLocationService = userLocationService
- if (userLocationService != null && restart) {
- userLocationService.stopSelf()
- }
- if (userLocationService == null || restart) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- startForegroundService(serviceIntent)
- } else {
- startService(serviceIntent)
- }
- }
- }
+ fun stopMyLocationService() {
+ telegramService?.stopIfNeeded(this, TelegramService.USED_BY_MY_LOCATION)
+ }
- fun stopUserLocationService() {
- userLocationService?.stopIfNeeded(this)
- }
+ fun startUserLocationService() {
+ startTelegramService(TelegramService.USED_BY_USERS_LOCATIONS)
+ }
- fun runInUIThread(action: (() -> Unit)) {
- uiHandler.post(action)
- }
+ fun stopUserLocationService() {
+ telegramService?.stopIfNeeded(this, TelegramService.USED_BY_USERS_LOCATIONS)
+ }
- fun runInUIThread(action: (() -> Unit), delay: Long) {
- uiHandler.postDelayed(action, delay)
- }
+ fun runInUIThread(action: (() -> Unit)) {
+ uiHandler.post(action)
+ }
+
+ fun runInUIThread(action: (() -> Unit), delay: Long) {
+ uiHandler.postDelayed(action, delay)
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt
new file mode 100644
index 0000000000..0f0b0937c1
--- /dev/null
+++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt
@@ -0,0 +1,169 @@
+package net.osmand.telegram
+
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.location.Location
+import android.location.LocationListener
+import android.location.LocationManager
+import android.os.*
+import android.util.Log
+import android.widget.Toast
+import net.osmand.PlatformUtil
+import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener
+import org.drinkless.td.libcore.telegram.TdApi
+import java.util.concurrent.Executors
+
+class TelegramService : Service(), LocationListener, TelegramIncomingMessagesListener {
+
+ private fun app() = application as TelegramApplication
+ private val binder = LocationServiceBinder()
+ private val executor = Executors.newSingleThreadExecutor()
+
+ var handler: Handler? = null
+ var usedBy = 0
+
+ class LocationServiceBinder : Binder()
+
+ override fun onBind(intent: Intent): IBinder? {
+ return binder
+ }
+
+ fun stopIfNeeded(ctx: Context, usageIntent: Int) {
+ if (usedBy and usageIntent > 0) {
+ usedBy -= usageIntent
+ }
+ if (usedBy == 0) {
+ val serviceIntent = Intent(ctx, TelegramService::class.java)
+ ctx.stopService(serviceIntent)
+ }
+ }
+
+ override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+ val app = app()
+ handler = Handler()
+ usedBy = intent.getIntExtra(USAGE_INTENT, 0)
+
+ app.telegramService = this
+ app.telegramHelper.incomingMessagesListener = this
+
+ if (needLocation()) {
+ // request location updates
+ val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
+ try {
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this@TelegramService)
+ } catch (e: SecurityException) {
+ Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
+ Log.d(PlatformUtil.TAG, "Location service permission not granted")
+ } catch (e: IllegalArgumentException) {
+ Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show()
+ Log.d(PlatformUtil.TAG, "GPS location provider not available")
+ }
+ }
+
+ val locationNotification = app.notificationHelper.locationNotification
+ val notification = app.notificationHelper.buildNotification(locationNotification)
+ startForeground(locationNotification.telegramNotificationId, notification)
+ app.notificationHelper.refreshNotification(locationNotification.type)
+ return Service.START_REDELIVER_INTENT
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ val app = app()
+ app.telegramHelper.incomingMessagesListener = null
+ app.telegramService = null
+
+ usedBy = 0
+
+ // remove updates
+ val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
+ try {
+ locationManager.removeUpdates(this)
+ } catch (e: SecurityException) {
+ Log.d(PlatformUtil.TAG, "Location service permission not granted")
+ }
+
+ // remove notification
+ stopForeground(java.lang.Boolean.TRUE)
+ }
+
+ private fun needLocation(): Boolean {
+ return (usedBy and USED_BY_MY_LOCATION) > 0
+ }
+
+ override fun onLocationChanged(l: Location?) {
+ if (l != null) {
+ val location = convertLocation(l)
+ app().shareLocationHelper.updateLocation(location)
+ }
+ }
+
+ override fun onProviderDisabled(provider: String) {
+ Toast.makeText(this, getString(R.string.location_service_no_gps_available), Toast.LENGTH_LONG).show()
+ }
+
+
+ override fun onProviderEnabled(provider: String) {}
+
+
+ override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
+
+ override fun onTaskRemoved(rootIntent: Intent) {
+ val app = app()
+ if (app.telegramService != null) {
+ // Do not stop service after UI task was dismissed
+ //this@TelegramService.stopSelf()
+ }
+ }
+
+ override fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message) {
+ val app = app()
+ if (app.settings.isShowingChatOnMap(chatTitle)) {
+ ShowMessagesTask(app, chatTitle).executeOnExecutor(executor, *messages)
+ }
+ }
+
+ private class ShowMessagesTask(private val app: TelegramApplication, private val chatTitle: String) : AsyncTask() {
+
+ override fun doInBackground(vararg messages: TdApi.Message): Void? {
+ for (message in messages) {
+ app.showLocationHelper.showLocationOnMap(chatTitle, message)
+ }
+ return null
+ }
+ }
+
+ companion object {
+
+ const val USED_BY_MY_LOCATION: Int = 1
+ const val USED_BY_USERS_LOCATIONS: Int = 2
+ const val USAGE_INTENT = "SERVICE_USED_BY"
+
+ fun convertLocation(l: Location?): net.osmand.Location? {
+ if (l == null) {
+ return null
+ }
+ val r = net.osmand.Location(l.provider)
+ r.latitude = l.latitude
+ r.longitude = l.longitude
+ r.time = l.time
+ if (l.hasAccuracy()) {
+ r.accuracy = l.accuracy
+ }
+ if (l.hasSpeed()) {
+ r.speed = l.speed
+ }
+ if (l.hasAltitude()) {
+ r.altitude = l.altitude
+ }
+ if (l.hasBearing()) {
+ r.bearing = l.bearing
+ }
+ if (l.hasAltitude()) {
+ r.altitude = l.altitude
+ }
+ return r
+ }
+ }
+}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
index e3d30dc18b..95205f7d3e 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
@@ -6,128 +6,128 @@ import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants
class TelegramSettings(private val app: TelegramApplication) {
- companion object {
+ companion object {
- private const val SETTINGS_NAME = "osmand_telegram_settings"
+ private const val SETTINGS_NAME = "osmand_telegram_settings"
- private const val SHARE_LOCATION_CHATS_KEY = "share_location_chats"
- private const val SHOW_ON_MAP_CHATS_KEY = "show_on_map_chats"
+ private const val SHARE_LOCATION_CHATS_KEY = "share_location_chats"
+ private const val SHOW_ON_MAP_CHATS_KEY = "show_on_map_chats"
- private const val METRICS_CONSTANTS_KEY = "metrics_constants"
- private const val SPEED_CONSTANTS_KEY = "speed_constants"
+ private const val METRICS_CONSTANTS_KEY = "metrics_constants"
+ private const val SPEED_CONSTANTS_KEY = "speed_constants"
- private const val SHOW_NOTIFICATION_ALWAYS_KEY = "show_notification_always"
- }
+ private const val SHOW_NOTIFICATION_ALWAYS_KEY = "show_notification_always"
+ }
- private var shareLocationChats: Set = emptySet()
- private var showOnMapChats: Set = emptySet()
+ private var shareLocationChats: Set = emptySet()
+ private var showOnMapChats: Set = emptySet()
- var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS
- var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR
+ var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS
+ var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR
- var showNotificationAlways = true
+ var showNotificationAlways = true
- init {
- read()
- }
+ init {
+ read()
+ }
- fun hasAnyChatToShareLocation(): Boolean {
- return shareLocationChats.isNotEmpty()
- }
+ fun hasAnyChatToShareLocation(): Boolean {
+ return shareLocationChats.isNotEmpty()
+ }
- fun isSharingLocationToChat(chatTitle: String): Boolean {
- return shareLocationChats.contains(chatTitle)
- }
+ fun isSharingLocationToChat(chatTitle: String): Boolean {
+ return shareLocationChats.contains(chatTitle)
+ }
- fun hasAnyChatToShowOnMap(): Boolean {
- return showOnMapChats.isNotEmpty()
- }
+ fun hasAnyChatToShowOnMap(): Boolean {
+ return showOnMapChats.isNotEmpty()
+ }
- fun isShowingChatOnMap(chatTitle: String): Boolean {
- return showOnMapChats.contains(chatTitle)
- }
+ fun isShowingChatOnMap(chatTitle: String): Boolean {
+ return showOnMapChats.contains(chatTitle)
+ }
- fun removeNonexistingChats(presentChatTitles: List) {
- val shareLocationChats = shareLocationChats.toMutableList()
- shareLocationChats.intersect(presentChatTitles)
- this.shareLocationChats = shareLocationChats.toHashSet()
+ fun removeNonexistingChats(presentChatTitles: List) {
+ val shareLocationChats = shareLocationChats.toMutableList()
+ shareLocationChats.intersect(presentChatTitles)
+ this.shareLocationChats = shareLocationChats.toHashSet()
- val showOnMapChats = showOnMapChats.toMutableList()
- showOnMapChats.intersect(presentChatTitles)
- this.showOnMapChats = showOnMapChats.toHashSet()
- }
+ val showOnMapChats = showOnMapChats.toMutableList()
+ showOnMapChats.intersect(presentChatTitles)
+ this.showOnMapChats = showOnMapChats.toHashSet()
+ }
- fun shareLocationToChat(chatTitle: String, share: Boolean) {
- val shareLocationChats = shareLocationChats.toMutableList()
- if (share) {
- shareLocationChats.add(chatTitle)
- } else {
- shareLocationChats.remove(chatTitle)
- }
- this.shareLocationChats = shareLocationChats.toHashSet()
- }
+ fun shareLocationToChat(chatTitle: String, share: Boolean) {
+ val shareLocationChats = shareLocationChats.toMutableList()
+ if (share) {
+ shareLocationChats.add(chatTitle)
+ } else {
+ shareLocationChats.remove(chatTitle)
+ }
+ this.shareLocationChats = shareLocationChats.toHashSet()
+ }
- fun showChatOnMap(chatTitle: String, show: Boolean) {
- val showOnMapChats = showOnMapChats.toMutableList()
- if (show) {
- showOnMapChats.add(chatTitle)
- } else {
- showOnMapChats.remove(chatTitle)
- }
- this.showOnMapChats = showOnMapChats.toHashSet()
- }
+ fun showChatOnMap(chatTitle: String, show: Boolean) {
+ val showOnMapChats = showOnMapChats.toMutableList()
+ if (show) {
+ showOnMapChats.add(chatTitle)
+ } else {
+ showOnMapChats.remove(chatTitle)
+ }
+ this.showOnMapChats = showOnMapChats.toHashSet()
+ }
- fun getShareLocationChats() = ArrayList(shareLocationChats)
- fun getShowOnMapChats() = ArrayList(showOnMapChats)
+ fun getShareLocationChats() = ArrayList(shareLocationChats)
+ fun getShowOnMapChats() = ArrayList(showOnMapChats)
- fun getShowOnMapChatsCount() = showOnMapChats.size
+ fun getShowOnMapChatsCount() = showOnMapChats.size
- fun save() {
- val prefs = app.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE)
- val edit = prefs.edit()
+ fun save() {
+ val prefs = app.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE)
+ val edit = prefs.edit()
- val shareLocationChatsSet = mutableSetOf()
- val shareLocationChats = ArrayList(shareLocationChats)
- for (chatTitle in shareLocationChats) {
- shareLocationChatsSet.add(chatTitle)
- }
- edit.putStringSet(SHARE_LOCATION_CHATS_KEY, shareLocationChatsSet)
+ val shareLocationChatsSet = mutableSetOf()
+ val shareLocationChats = ArrayList(shareLocationChats)
+ for (chatTitle in shareLocationChats) {
+ shareLocationChatsSet.add(chatTitle)
+ }
+ edit.putStringSet(SHARE_LOCATION_CHATS_KEY, shareLocationChatsSet)
- val showOnMapChatsSet = mutableSetOf()
- val showOnMapChats = ArrayList(showOnMapChats)
- for (chatTitle in showOnMapChats) {
- showOnMapChatsSet.add(chatTitle)
- }
- edit.putStringSet(SHOW_ON_MAP_CHATS_KEY, showOnMapChatsSet)
+ val showOnMapChatsSet = mutableSetOf()
+ val showOnMapChats = ArrayList(showOnMapChats)
+ for (chatTitle in showOnMapChats) {
+ showOnMapChatsSet.add(chatTitle)
+ }
+ edit.putStringSet(SHOW_ON_MAP_CHATS_KEY, showOnMapChatsSet)
- edit.putString(METRICS_CONSTANTS_KEY, metricsConstants.name)
- edit.putString(SPEED_CONSTANTS_KEY, speedConstants.name)
+ edit.putString(METRICS_CONSTANTS_KEY, metricsConstants.name)
+ edit.putString(SPEED_CONSTANTS_KEY, speedConstants.name)
- edit.putBoolean(SHOW_NOTIFICATION_ALWAYS_KEY, showNotificationAlways)
+ edit.putBoolean(SHOW_NOTIFICATION_ALWAYS_KEY, showNotificationAlways)
- edit.apply()
- }
+ edit.apply()
+ }
- fun read() {
- val prefs = app.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE)
+ fun read() {
+ val prefs = app.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE)
- val shareLocationChats = mutableSetOf()
- val shareLocationChatsSet = prefs.getStringSet(SHARE_LOCATION_CHATS_KEY, mutableSetOf())
- for (chatTitle in shareLocationChatsSet) {
- shareLocationChats.add(chatTitle)
- }
- this.shareLocationChats = shareLocationChats
+ val shareLocationChats = mutableSetOf()
+ val shareLocationChatsSet = prefs.getStringSet(SHARE_LOCATION_CHATS_KEY, mutableSetOf())
+ for (chatTitle in shareLocationChatsSet) {
+ shareLocationChats.add(chatTitle)
+ }
+ this.shareLocationChats = shareLocationChats
- val showOnMapChats = mutableSetOf()
- val showOnMapChatsSet = prefs.getStringSet(SHOW_ON_MAP_CHATS_KEY, mutableSetOf())
- for (chatTitle in showOnMapChatsSet) {
- showOnMapChats.add(chatTitle)
- }
- this.showOnMapChats = showOnMapChats
+ val showOnMapChats = mutableSetOf()
+ val showOnMapChatsSet = prefs.getStringSet(SHOW_ON_MAP_CHATS_KEY, mutableSetOf())
+ for (chatTitle in showOnMapChatsSet) {
+ showOnMapChats.add(chatTitle)
+ }
+ this.showOnMapChats = showOnMapChats
- metricsConstants = MetricsConstants.valueOf(prefs.getString(METRICS_CONSTANTS_KEY, MetricsConstants.KILOMETERS_AND_METERS.name))
- speedConstants = SpeedConstants.valueOf(prefs.getString(SPEED_CONSTANTS_KEY, SpeedConstants.KILOMETERS_PER_HOUR.name))
+ metricsConstants = MetricsConstants.valueOf(prefs.getString(METRICS_CONSTANTS_KEY, MetricsConstants.KILOMETERS_AND_METERS.name))
+ speedConstants = SpeedConstants.valueOf(prefs.getString(SPEED_CONSTANTS_KEY, SpeedConstants.KILOMETERS_PER_HOUR.name))
- showNotificationAlways = prefs.getBoolean(SHOW_NOTIFICATION_ALWAYS_KEY, true)
- }
+ showNotificationAlways = prefs.getBoolean(SHOW_NOTIFICATION_ALWAYS_KEY, true)
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt
index e1c69c6081..6c0f64cb40 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt
@@ -48,788 +48,788 @@ import java.util.*
class OsmandAidlHelper(private val app: Application) {
- companion object {
- private const val OSMAND_FREE_PACKAGE_NAME = "net.osmand"
- private const val OSMAND_PLUS_PACKAGE_NAME = "net.osmand.plus"
- private var OSMAND_PACKAGE_NAME = OSMAND_PLUS_PACKAGE_NAME
- }
-
- private var mIOsmAndAidlInterface: IOsmAndAidlInterface? = null
-
- var initialized: Boolean = false
- private set
-
- var bound: Boolean = false
- private set
-
- var listener: OsmandHelperListener? = null
-
- interface OsmandHelperListener {
- fun onOsmandConnectionStateChanged(connected: Boolean)
- }
-
- /**
- * Class for interacting with the main interface of the service.
- */
- private val mConnection = object : ServiceConnection {
- override fun onServiceConnected(className: ComponentName,
- service: IBinder) {
- // This is called when the connection with the service has been
- // established, giving us the service object we can use to
- // interact with the service. We are communicating with our
- // service through an IDL interface, so get a client-side
- // representation of that from the raw service object.
- mIOsmAndAidlInterface = IOsmAndAidlInterface.Stub.asInterface(service)
- initialized = true
- Toast.makeText(app, "OsmAnd connected", Toast.LENGTH_SHORT).show()
- listener?.onOsmandConnectionStateChanged(true)
- }
-
- override fun onServiceDisconnected(className: ComponentName) {
- // This is called when the connection with the service has been
- // unexpectedly disconnected -- that is, its process crashed.
- mIOsmAndAidlInterface = null
- Toast.makeText(app, "OsmAnd disconnected", Toast.LENGTH_SHORT).show()
- listener?.onOsmandConnectionStateChanged(false)
- }
- }
-
- fun isOsmandBound(): Boolean {
- return bound
- }
-
- fun isOsmandConnected(): Boolean {
- return mIOsmAndAidlInterface != null
- }
-
- /**
- * Get list of active GPX files.
- *
- * @return list of active gpx files.
- */
- val activeGpxFiles: List?
- get() {
- if (mIOsmAndAidlInterface != null) {
- try {
- val res = ArrayList()
- if (mIOsmAndAidlInterface!!.getActiveGpx(res)) {
- return res
- }
- } catch (e: Throwable) {
- e.printStackTrace()
- }
-
- }
- return null
- }
-
- init {
- when {
- bindService(OSMAND_PLUS_PACKAGE_NAME) -> {
- OSMAND_PACKAGE_NAME = OSMAND_PLUS_PACKAGE_NAME
- bound = true
- }
- bindService(OSMAND_FREE_PACKAGE_NAME) -> {
- OSMAND_PACKAGE_NAME = OSMAND_FREE_PACKAGE_NAME
- bound = true
- }
- else -> {
- bound = false
- initialized = true
- }
- }
- }
-
- private fun bindService(packageName: String): Boolean {
- return if (mIOsmAndAidlInterface == null) {
- val intent = Intent("net.osmand.aidl.OsmandAidlService")
- intent.`package` = packageName
- app.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
- } else {
- true
- }
- }
-
- fun cleanupResources() {
- if (mIOsmAndAidlInterface != null) {
- app.unbindService(mConnection)
- }
- }
-
- fun refreshMap(): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.refreshMap()
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Add favorite group with given params.
- *
- * @param name - group name.
- * @param color - group color. Can be one of: "red", "orange", "yellow",
- * "lightgreen", "green", "lightblue", "blue", "purple", "pink", "brown".
- * @param visible - group visibility.
- */
- fun addFavoriteGroup(name: String, color: String, visible: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val favoriteGroup = AFavoriteGroup(name, color, visible)
- return mIOsmAndAidlInterface!!.addFavoriteGroup(AddFavoriteGroupParams(favoriteGroup))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Update favorite group with given params.
- *
- * @param namePrev - group name (current).
- * @param colorPrev - group color (current).
- * @param visiblePrev - group visibility (current).
- * @param nameNew - group name (new).
- * @param colorNew - group color (new).
- * @param visibleNew - group visibility (new).
- */
- fun updateFavoriteGroup(namePrev: String, colorPrev: String, visiblePrev: Boolean,
- nameNew: String, colorNew: String, visibleNew: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val favoriteGroupPrev = AFavoriteGroup(namePrev, colorPrev, visiblePrev)
- val favoriteGroupNew = AFavoriteGroup(nameNew, colorNew, visibleNew)
- return mIOsmAndAidlInterface!!.updateFavoriteGroup(UpdateFavoriteGroupParams(favoriteGroupPrev, favoriteGroupNew))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Remove favorite group with given name.
- *
- * @param name - name of favorite group.
- */
- fun removeFavoriteGroup(name: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val favoriteGroup = AFavoriteGroup(name, "", false)
- return mIOsmAndAidlInterface!!.removeFavoriteGroup(RemoveFavoriteGroupParams(favoriteGroup))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Add favorite at given location with given params.
- *
- * @param lat - latitude.
- * @param lon - longitude.
- * @param name - name of favorite item.
- * @param description - description of favorite item.
- * @param category - category of favorite item.
- * @param color - color of favorite item. Can be one of: "red", "orange", "yellow",
- * "lightgreen", "green", "lightblue", "blue", "purple", "pink", "brown".
- * @param visible - should favorite item be visible after creation.
- */
- fun addFavorite(lat: Double, lon: Double, name: String, description: String,
- category: String, color: String, visible: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val favorite = AFavorite(lat, lon, name, description, category, color, visible)
- return mIOsmAndAidlInterface!!.addFavorite(AddFavoriteParams(favorite))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Update favorite at given location with given params.
- *
- * @param latPrev - latitude (current favorite).
- * @param lonPrev - longitude (current favorite).
- * @param namePrev - name of favorite item (current favorite).
- * @param categoryPrev - category of favorite item (current favorite).
- * @param latNew - latitude (new favorite).
- * @param lonNew - longitude (new favorite).
- * @param nameNew - name of favorite item (new favorite).
- * @param descriptionNew - description of favorite item (new favorite).
- * @param categoryNew - category of favorite item (new favorite). Use only to create a new category,
- * not to update an existing one. If you want to update an existing category,
- * use the [.updateFavoriteGroup] method.
- * @param colorNew - color of new category. Can be one of: "red", "orange", "yellow",
- * "lightgreen", "green", "lightblue", "blue", "purple", "pink", "brown".
- * @param visibleNew - should new category be visible after creation.
- */
- fun updateFavorite(latPrev: Double, lonPrev: Double, namePrev: String, categoryPrev: String,
- latNew: Double, lonNew: Double, nameNew: String, descriptionNew: String,
- categoryNew: String, colorNew: String, visibleNew: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val favoritePrev = AFavorite(latPrev, lonPrev, namePrev, "", categoryPrev, "", false)
- val favoriteNew = AFavorite(latNew, lonNew, nameNew, descriptionNew, categoryNew, colorNew, visibleNew)
- return mIOsmAndAidlInterface!!.updateFavorite(UpdateFavoriteParams(favoritePrev, favoriteNew))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Remove favorite at given location with given params.
- *
- * @param lat - latitude.
- * @param lon - longitude.
- * @param name - name of favorite item.
- * @param category - category of favorite item.
- */
- fun removeFavorite(lat: Double, lon: Double, name: String, category: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val favorite = AFavorite(lat, lon, name, "", category, "", false)
- return mIOsmAndAidlInterface!!.removeFavorite(RemoveFavoriteParams(favorite))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Add map marker at given location.
- *
- * @param lat - latitude.
- * @param lon - longitude.
- * @param name - name.
- */
- fun addMapMarker(lat: Double, lon: Double, name: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val marker = AMapMarker(ALatLon(lat, lon), name)
- return mIOsmAndAidlInterface!!.addMapMarker(AddMapMarkerParams(marker))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Update map marker at given location with name.
- *
- * @param latPrev - latitude (current marker).
- * @param lonPrev - longitude (current marker).
- * @param namePrev - name (current marker).
- * @param latNew - latitude (new marker).
- * @param lonNew - longitude (new marker).
- * @param nameNew - name (new marker).
- */
- fun updateMapMarker(latPrev: Double, lonPrev: Double, namePrev: String,
- latNew: Double, lonNew: Double, nameNew: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val markerPrev = AMapMarker(ALatLon(latPrev, lonPrev), namePrev)
- val markerNew = AMapMarker(ALatLon(latNew, lonNew), nameNew)
- return mIOsmAndAidlInterface!!.updateMapMarker(UpdateMapMarkerParams(markerPrev, markerNew))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Remove map marker at given location with name.
- *
- * @param lat - latitude.
- * @param lon - longitude.
- * @param name - name.
- */
- fun removeMapMarker(lat: Double, lon: Double, name: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val marker = AMapMarker(ALatLon(lat, lon), name)
- return mIOsmAndAidlInterface!!.removeMapMarker(RemoveMapMarkerParams(marker))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Add map widget to the right side of the main screen.
- * Note: any specified icon should exist in OsmAnd app resources.
- *
- * @param id - widget id.
- * @param menuIconName - icon name (configure map menu).
- * @param menuTitle - widget name (configure map menu).
- * @param lightIconName - icon name for the light theme (widget).
- * @param darkIconName - icon name for the dark theme (widget).
- * @param text - main widget text.
- * @param description - sub text, like "km/h".
- * @param order - order position in the widgets list.
- * @param intentOnClick - onClick intent. Called after click on widget as startActivity(Intent intent).
- */
- fun addMapWidget(id: String, menuIconName: String, menuTitle: String,
- lightIconName: String, darkIconName: String, text: String, description: String,
- order: Int, intentOnClick: Intent): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val widget = AMapWidget(id, menuIconName, menuTitle, lightIconName,
- darkIconName, text, description, order, intentOnClick)
- return mIOsmAndAidlInterface!!.addMapWidget(AddMapWidgetParams(widget))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Update map widget.
- * Note: any specified icon should exist in OsmAnd app resources.
- *
- * @param id - widget id.
- * @param menuIconName - icon name (configure map menu).
- * @param menuTitle - widget name (configure map menu).
- * @param lightIconName - icon name for the light theme (widget).
- * @param darkIconName - icon name for the dark theme (widget).
- * @param text - main widget text.
- * @param description - sub text, like "km/h".
- * @param order - order position in the widgets list.
- * @param intentOnClick - onClick intent. Called after click on widget as startActivity(Intent intent).
- */
- fun updateMapWidget(id: String, menuIconName: String, menuTitle: String,
- lightIconName: String, darkIconName: String, text: String, description: String,
- order: Int, intentOnClick: Intent): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val widget = AMapWidget(id, menuIconName, menuTitle, lightIconName,
- darkIconName, text, description, order, intentOnClick)
- return mIOsmAndAidlInterface!!.updateMapWidget(UpdateMapWidgetParams(widget))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Remove map widget.
- *
- * @param id - widget id.
- */
- fun removeMapWidget(id: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.removeMapWidget(RemoveMapWidgetParams(id))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Add user layer on the map.
- *
- * @param id - layer id.
- * @param name - layer name.
- * @param zOrder - z-order position of layer. Default value is 5.5f
- * @param points - initial list of points. Nullable.
- */
- fun addMapLayer(id: String, name: String, zOrder: Float, points: List?): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val layer = AMapLayer(id, name, zOrder, points)
- return mIOsmAndAidlInterface!!.addMapLayer(AddMapLayerParams(layer))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Update user layer.
- *
- * @param id - layer id.
- * @param name - layer name.
- * @param zOrder - z-order position of layer. Default value is 5.5f
- * @param points - list of points. Nullable.
- */
- fun updateMapLayer(id: String, name: String, zOrder: Float, points: List?): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val layer = AMapLayer(id, name, zOrder, points)
- return mIOsmAndAidlInterface!!.updateMapLayer(UpdateMapLayerParams(layer))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Remove user layer.
- *
- * @param id - layer id.
- */
- fun removeMapLayer(id: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.removeMapLayer(RemoveMapLayerParams(id))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Add point to user layer.
- *
- * @param layerId - layer id. Note: layer should be added first.
- * @param pointId - point id.
- * @param shortName - short name (single char). Displayed on the map.
- * @param fullName - full name. Displayed in the context menu on first row.
- * @param typeName - type name. Displayed in context menu on second row.
- * @param color - color of circle's background.
- * @param location - location of the point.
- * @param details - list of details. Displayed under context menu.
- */
- fun addMapPoint(layerId: String, pointId: String, shortName: String, fullName: String,
- typeName: String, color: Int, location: ALatLon, details: List?): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)
- return mIOsmAndAidlInterface!!.addMapPoint(AddMapPointParams(layerId, point))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Update point.
- *
- * @param layerId - layer id.
- * @param pointId - point id.
- * @param shortName - short name (single char). Displayed on the map.
- * @param fullName - full name. Displayed in the context menu on first row.
- * @param typeName - type name. Displayed in context menu on second row.
- * @param color - color of circle's background.
- * @param location - location of the point.
- * @param details - list of details. Displayed under context menu.
- */
- fun updateMapPoint(layerId: String, pointId: String, shortName: String, fullName: String,
- typeName: String, color: Int, location: ALatLon, details: List?): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)
- return mIOsmAndAidlInterface!!.updateMapPoint(UpdateMapPointParams(layerId, point))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Remove point.
- *
- * @param layerId - layer id.
- * @param pointId - point id.
- */
- fun removeMapPoint(layerId: String, pointId: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.removeMapPoint(RemoveMapPointParams(layerId, pointId))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Import GPX file to OsmAnd.
- * OsmAnd must have rights to access location. Not recommended.
- *
- * @param file - File which represents GPX track.
- * @param fileName - Destination file name. May contain dirs.
- * @param color - color of gpx. Can be one of: "red", "orange", "lightblue", "blue", "purple",
- * "translucent_red", "translucent_orange", "translucent_lightblue",
- * "translucent_blue", "translucent_purple"
- * @param show - show track on the map after import
- */
- fun importGpxFromFile(file: File, fileName: String, color: String, show: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.importGpx(ImportGpxParams(file, fileName, color, show))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Import GPX file to OsmAnd.
- *
- * @param gpxUri - URI created by FileProvider.
- * @param fileName - Destination file name. May contain dirs.
- * @param color - color of gpx. Can be one of: "", "red", "orange", "lightblue", "blue", "purple",
- * "translucent_red", "translucent_orange", "translucent_lightblue",
- * "translucent_blue", "translucent_purple"
- * @param show - show track on the map after import
- */
- fun importGpxFromUri(gpxUri: Uri, fileName: String, color: String, show: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- app.grantUriPermission(OSMAND_PACKAGE_NAME, gpxUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
- return mIOsmAndAidlInterface!!.importGpx(ImportGpxParams(gpxUri, fileName, color, show))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun navigateGpxFromUri(gpxUri: Uri, force: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- app.grantUriPermission(OSMAND_PACKAGE_NAME, gpxUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
- return mIOsmAndAidlInterface!!.navigateGpx(NavigateGpxParams(gpxUri, force))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Import GPX file to OsmAnd.
- *
- * @param data - Raw contents of GPX file. Sent as intent's extra string parameter.
- * @param fileName - Destination file name. May contain dirs.
- * @param color - color of gpx. Can be one of: "red", "orange", "lightblue", "blue", "purple",
- * "translucent_red", "translucent_orange", "translucent_lightblue",
- * "translucent_blue", "translucent_purple"
- * @param show - show track on the map after import
- */
- fun importGpxFromData(data: String, fileName: String, color: String, show: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.importGpx(ImportGpxParams(data, fileName, color, show))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun navigateGpxFromData(data: String, force: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.navigateGpx(NavigateGpxParams(data, force))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Show GPX file on map.
- *
- * @param fileName - file name to show. Must be imported first.
- */
- fun showGpx(fileName: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.showGpx(ShowGpxParams(fileName))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Hide GPX file.
- *
- * @param fileName - file name to hide.
- */
- fun hideGpx(fileName: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.hideGpx(HideGpxParams(fileName))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Remove GPX file.
- *
- * @param fileName - file name to remove;
- */
- fun removeGpx(fileName: String): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.removeGpx(RemoveGpxParams(fileName))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- /**
- * Get list of active GPX files.
- *
- * @param latitude - latitude of new map center.
- * @param longitude - longitude of new map center.
- * @param zoom - map zoom level. Set 0 to keep zoom unchanged.
- * @param animated - set true to animate changes.
- */
- fun setMapLocation(latitude: Double, longitude: Double, zoom: Int, animated: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.setMapLocation(
- SetMapLocationParams(latitude, longitude, zoom, animated))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun startGpxRecording(params: StartGpxRecordingParams): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.startGpxRecording(params)
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun stopGpxRecording(params: StopGpxRecordingParams): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.stopGpxRecording(params)
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun takePhotoNote(lat: Double, lon: Double): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.takePhotoNote(TakePhotoNoteParams(lat, lon))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun startVideoRecording(lat: Double, lon: Double): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.startVideoRecording(StartVideoRecordingParams(lat, lon))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun startAudioRecording(lat: Double, lon: Double): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.startAudioRecording(StartAudioRecordingParams(lat, lon))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun stopRecording(): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.stopRecording(StopRecordingParams())
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
-
- fun navigate(startName: String, startLat: Double, startLon: Double, destName: String, destLat: Double, destLon: Double, profile: String, force: Boolean): Boolean {
- if (mIOsmAndAidlInterface != null) {
- try {
- return mIOsmAndAidlInterface!!.navigate(NavigateParams(startName, startLat, startLon, destName, destLat, destLon, profile, force))
- } catch (e: RemoteException) {
- e.printStackTrace()
- }
-
- }
- return false
- }
+ companion object {
+ private const val OSMAND_FREE_PACKAGE_NAME = "net.osmand"
+ private const val OSMAND_PLUS_PACKAGE_NAME = "net.osmand.plus"
+ private var OSMAND_PACKAGE_NAME = OSMAND_PLUS_PACKAGE_NAME
+ }
+
+ private var mIOsmAndAidlInterface: IOsmAndAidlInterface? = null
+
+ var initialized: Boolean = false
+ private set
+
+ var bound: Boolean = false
+ private set
+
+ var listener: OsmandHelperListener? = null
+
+ interface OsmandHelperListener {
+ fun onOsmandConnectionStateChanged(connected: Boolean)
+ }
+
+ /**
+ * Class for interacting with the main interface of the service.
+ */
+ private val mConnection = object : ServiceConnection {
+ override fun onServiceConnected(className: ComponentName,
+ service: IBinder) {
+ // This is called when the connection with the service has been
+ // established, giving us the service object we can use to
+ // interact with the service. We are communicating with our
+ // service through an IDL interface, so get a client-side
+ // representation of that from the raw service object.
+ mIOsmAndAidlInterface = IOsmAndAidlInterface.Stub.asInterface(service)
+ initialized = true
+ Toast.makeText(app, "OsmAnd connected", Toast.LENGTH_SHORT).show()
+ listener?.onOsmandConnectionStateChanged(true)
+ }
+
+ override fun onServiceDisconnected(className: ComponentName) {
+ // This is called when the connection with the service has been
+ // unexpectedly disconnected -- that is, its process crashed.
+ mIOsmAndAidlInterface = null
+ Toast.makeText(app, "OsmAnd disconnected", Toast.LENGTH_SHORT).show()
+ listener?.onOsmandConnectionStateChanged(false)
+ }
+ }
+
+ fun isOsmandBound(): Boolean {
+ return bound
+ }
+
+ fun isOsmandConnected(): Boolean {
+ return mIOsmAndAidlInterface != null
+ }
+
+ /**
+ * Get list of active GPX files.
+ *
+ * @return list of active gpx files.
+ */
+ val activeGpxFiles: List?
+ get() {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val res = ArrayList()
+ if (mIOsmAndAidlInterface!!.getActiveGpx(res)) {
+ return res
+ }
+ } catch (e: Throwable) {
+ e.printStackTrace()
+ }
+
+ }
+ return null
+ }
+
+ init {
+ when {
+ bindService(OSMAND_PLUS_PACKAGE_NAME) -> {
+ OSMAND_PACKAGE_NAME = OSMAND_PLUS_PACKAGE_NAME
+ bound = true
+ }
+ bindService(OSMAND_FREE_PACKAGE_NAME) -> {
+ OSMAND_PACKAGE_NAME = OSMAND_FREE_PACKAGE_NAME
+ bound = true
+ }
+ else -> {
+ bound = false
+ initialized = true
+ }
+ }
+ }
+
+ private fun bindService(packageName: String): Boolean {
+ return if (mIOsmAndAidlInterface == null) {
+ val intent = Intent("net.osmand.aidl.OsmandAidlService")
+ intent.`package` = packageName
+ app.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
+ } else {
+ true
+ }
+ }
+
+ fun cleanupResources() {
+ if (mIOsmAndAidlInterface != null) {
+ app.unbindService(mConnection)
+ }
+ }
+
+ fun refreshMap(): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.refreshMap()
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Add favorite group with given params.
+ *
+ * @param name - group name.
+ * @param color - group color. Can be one of: "red", "orange", "yellow",
+ * "lightgreen", "green", "lightblue", "blue", "purple", "pink", "brown".
+ * @param visible - group visibility.
+ */
+ fun addFavoriteGroup(name: String, color: String, visible: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val favoriteGroup = AFavoriteGroup(name, color, visible)
+ return mIOsmAndAidlInterface!!.addFavoriteGroup(AddFavoriteGroupParams(favoriteGroup))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Update favorite group with given params.
+ *
+ * @param namePrev - group name (current).
+ * @param colorPrev - group color (current).
+ * @param visiblePrev - group visibility (current).
+ * @param nameNew - group name (new).
+ * @param colorNew - group color (new).
+ * @param visibleNew - group visibility (new).
+ */
+ fun updateFavoriteGroup(namePrev: String, colorPrev: String, visiblePrev: Boolean,
+ nameNew: String, colorNew: String, visibleNew: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val favoriteGroupPrev = AFavoriteGroup(namePrev, colorPrev, visiblePrev)
+ val favoriteGroupNew = AFavoriteGroup(nameNew, colorNew, visibleNew)
+ return mIOsmAndAidlInterface!!.updateFavoriteGroup(UpdateFavoriteGroupParams(favoriteGroupPrev, favoriteGroupNew))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Remove favorite group with given name.
+ *
+ * @param name - name of favorite group.
+ */
+ fun removeFavoriteGroup(name: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val favoriteGroup = AFavoriteGroup(name, "", false)
+ return mIOsmAndAidlInterface!!.removeFavoriteGroup(RemoveFavoriteGroupParams(favoriteGroup))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Add favorite at given location with given params.
+ *
+ * @param lat - latitude.
+ * @param lon - longitude.
+ * @param name - name of favorite item.
+ * @param description - description of favorite item.
+ * @param category - category of favorite item.
+ * @param color - color of favorite item. Can be one of: "red", "orange", "yellow",
+ * "lightgreen", "green", "lightblue", "blue", "purple", "pink", "brown".
+ * @param visible - should favorite item be visible after creation.
+ */
+ fun addFavorite(lat: Double, lon: Double, name: String, description: String,
+ category: String, color: String, visible: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val favorite = AFavorite(lat, lon, name, description, category, color, visible)
+ return mIOsmAndAidlInterface!!.addFavorite(AddFavoriteParams(favorite))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Update favorite at given location with given params.
+ *
+ * @param latPrev - latitude (current favorite).
+ * @param lonPrev - longitude (current favorite).
+ * @param namePrev - name of favorite item (current favorite).
+ * @param categoryPrev - category of favorite item (current favorite).
+ * @param latNew - latitude (new favorite).
+ * @param lonNew - longitude (new favorite).
+ * @param nameNew - name of favorite item (new favorite).
+ * @param descriptionNew - description of favorite item (new favorite).
+ * @param categoryNew - category of favorite item (new favorite). Use only to create a new category,
+ * not to update an existing one. If you want to update an existing category,
+ * use the [.updateFavoriteGroup] method.
+ * @param colorNew - color of new category. Can be one of: "red", "orange", "yellow",
+ * "lightgreen", "green", "lightblue", "blue", "purple", "pink", "brown".
+ * @param visibleNew - should new category be visible after creation.
+ */
+ fun updateFavorite(latPrev: Double, lonPrev: Double, namePrev: String, categoryPrev: String,
+ latNew: Double, lonNew: Double, nameNew: String, descriptionNew: String,
+ categoryNew: String, colorNew: String, visibleNew: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val favoritePrev = AFavorite(latPrev, lonPrev, namePrev, "", categoryPrev, "", false)
+ val favoriteNew = AFavorite(latNew, lonNew, nameNew, descriptionNew, categoryNew, colorNew, visibleNew)
+ return mIOsmAndAidlInterface!!.updateFavorite(UpdateFavoriteParams(favoritePrev, favoriteNew))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Remove favorite at given location with given params.
+ *
+ * @param lat - latitude.
+ * @param lon - longitude.
+ * @param name - name of favorite item.
+ * @param category - category of favorite item.
+ */
+ fun removeFavorite(lat: Double, lon: Double, name: String, category: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val favorite = AFavorite(lat, lon, name, "", category, "", false)
+ return mIOsmAndAidlInterface!!.removeFavorite(RemoveFavoriteParams(favorite))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Add map marker at given location.
+ *
+ * @param lat - latitude.
+ * @param lon - longitude.
+ * @param name - name.
+ */
+ fun addMapMarker(lat: Double, lon: Double, name: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val marker = AMapMarker(ALatLon(lat, lon), name)
+ return mIOsmAndAidlInterface!!.addMapMarker(AddMapMarkerParams(marker))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Update map marker at given location with name.
+ *
+ * @param latPrev - latitude (current marker).
+ * @param lonPrev - longitude (current marker).
+ * @param namePrev - name (current marker).
+ * @param latNew - latitude (new marker).
+ * @param lonNew - longitude (new marker).
+ * @param nameNew - name (new marker).
+ */
+ fun updateMapMarker(latPrev: Double, lonPrev: Double, namePrev: String,
+ latNew: Double, lonNew: Double, nameNew: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val markerPrev = AMapMarker(ALatLon(latPrev, lonPrev), namePrev)
+ val markerNew = AMapMarker(ALatLon(latNew, lonNew), nameNew)
+ return mIOsmAndAidlInterface!!.updateMapMarker(UpdateMapMarkerParams(markerPrev, markerNew))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Remove map marker at given location with name.
+ *
+ * @param lat - latitude.
+ * @param lon - longitude.
+ * @param name - name.
+ */
+ fun removeMapMarker(lat: Double, lon: Double, name: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val marker = AMapMarker(ALatLon(lat, lon), name)
+ return mIOsmAndAidlInterface!!.removeMapMarker(RemoveMapMarkerParams(marker))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Add map widget to the right side of the main screen.
+ * Note: any specified icon should exist in OsmAnd app resources.
+ *
+ * @param id - widget id.
+ * @param menuIconName - icon name (configure map menu).
+ * @param menuTitle - widget name (configure map menu).
+ * @param lightIconName - icon name for the light theme (widget).
+ * @param darkIconName - icon name for the dark theme (widget).
+ * @param text - main widget text.
+ * @param description - sub text, like "km/h".
+ * @param order - order position in the widgets list.
+ * @param intentOnClick - onClick intent. Called after click on widget as startActivity(Intent intent).
+ */
+ fun addMapWidget(id: String, menuIconName: String, menuTitle: String,
+ lightIconName: String, darkIconName: String, text: String, description: String,
+ order: Int, intentOnClick: Intent): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val widget = AMapWidget(id, menuIconName, menuTitle, lightIconName,
+ darkIconName, text, description, order, intentOnClick)
+ return mIOsmAndAidlInterface!!.addMapWidget(AddMapWidgetParams(widget))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Update map widget.
+ * Note: any specified icon should exist in OsmAnd app resources.
+ *
+ * @param id - widget id.
+ * @param menuIconName - icon name (configure map menu).
+ * @param menuTitle - widget name (configure map menu).
+ * @param lightIconName - icon name for the light theme (widget).
+ * @param darkIconName - icon name for the dark theme (widget).
+ * @param text - main widget text.
+ * @param description - sub text, like "km/h".
+ * @param order - order position in the widgets list.
+ * @param intentOnClick - onClick intent. Called after click on widget as startActivity(Intent intent).
+ */
+ fun updateMapWidget(id: String, menuIconName: String, menuTitle: String,
+ lightIconName: String, darkIconName: String, text: String, description: String,
+ order: Int, intentOnClick: Intent): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val widget = AMapWidget(id, menuIconName, menuTitle, lightIconName,
+ darkIconName, text, description, order, intentOnClick)
+ return mIOsmAndAidlInterface!!.updateMapWidget(UpdateMapWidgetParams(widget))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Remove map widget.
+ *
+ * @param id - widget id.
+ */
+ fun removeMapWidget(id: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.removeMapWidget(RemoveMapWidgetParams(id))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Add user layer on the map.
+ *
+ * @param id - layer id.
+ * @param name - layer name.
+ * @param zOrder - z-order position of layer. Default value is 5.5f
+ * @param points - initial list of points. Nullable.
+ */
+ fun addMapLayer(id: String, name: String, zOrder: Float, points: List?): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val layer = AMapLayer(id, name, zOrder, points)
+ return mIOsmAndAidlInterface!!.addMapLayer(AddMapLayerParams(layer))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Update user layer.
+ *
+ * @param id - layer id.
+ * @param name - layer name.
+ * @param zOrder - z-order position of layer. Default value is 5.5f
+ * @param points - list of points. Nullable.
+ */
+ fun updateMapLayer(id: String, name: String, zOrder: Float, points: List?): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val layer = AMapLayer(id, name, zOrder, points)
+ return mIOsmAndAidlInterface!!.updateMapLayer(UpdateMapLayerParams(layer))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Remove user layer.
+ *
+ * @param id - layer id.
+ */
+ fun removeMapLayer(id: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.removeMapLayer(RemoveMapLayerParams(id))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Add point to user layer.
+ *
+ * @param layerId - layer id. Note: layer should be added first.
+ * @param pointId - point id.
+ * @param shortName - short name (single char). Displayed on the map.
+ * @param fullName - full name. Displayed in the context menu on first row.
+ * @param typeName - type name. Displayed in context menu on second row.
+ * @param color - color of circle's background.
+ * @param location - location of the point.
+ * @param details - list of details. Displayed under context menu.
+ */
+ fun addMapPoint(layerId: String, pointId: String, shortName: String, fullName: String,
+ typeName: String, color: Int, location: ALatLon, details: List?): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)
+ return mIOsmAndAidlInterface!!.addMapPoint(AddMapPointParams(layerId, point))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Update point.
+ *
+ * @param layerId - layer id.
+ * @param pointId - point id.
+ * @param shortName - short name (single char). Displayed on the map.
+ * @param fullName - full name. Displayed in the context menu on first row.
+ * @param typeName - type name. Displayed in context menu on second row.
+ * @param color - color of circle's background.
+ * @param location - location of the point.
+ * @param details - list of details. Displayed under context menu.
+ */
+ fun updateMapPoint(layerId: String, pointId: String, shortName: String, fullName: String,
+ typeName: String, color: Int, location: ALatLon, details: List?): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)
+ return mIOsmAndAidlInterface!!.updateMapPoint(UpdateMapPointParams(layerId, point))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Remove point.
+ *
+ * @param layerId - layer id.
+ * @param pointId - point id.
+ */
+ fun removeMapPoint(layerId: String, pointId: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.removeMapPoint(RemoveMapPointParams(layerId, pointId))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Import GPX file to OsmAnd.
+ * OsmAnd must have rights to access location. Not recommended.
+ *
+ * @param file - File which represents GPX track.
+ * @param fileName - Destination file name. May contain dirs.
+ * @param color - color of gpx. Can be one of: "red", "orange", "lightblue", "blue", "purple",
+ * "translucent_red", "translucent_orange", "translucent_lightblue",
+ * "translucent_blue", "translucent_purple"
+ * @param show - show track on the map after import
+ */
+ fun importGpxFromFile(file: File, fileName: String, color: String, show: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.importGpx(ImportGpxParams(file, fileName, color, show))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Import GPX file to OsmAnd.
+ *
+ * @param gpxUri - URI created by FileProvider.
+ * @param fileName - Destination file name. May contain dirs.
+ * @param color - color of gpx. Can be one of: "", "red", "orange", "lightblue", "blue", "purple",
+ * "translucent_red", "translucent_orange", "translucent_lightblue",
+ * "translucent_blue", "translucent_purple"
+ * @param show - show track on the map after import
+ */
+ fun importGpxFromUri(gpxUri: Uri, fileName: String, color: String, show: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ app.grantUriPermission(OSMAND_PACKAGE_NAME, gpxUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ return mIOsmAndAidlInterface!!.importGpx(ImportGpxParams(gpxUri, fileName, color, show))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun navigateGpxFromUri(gpxUri: Uri, force: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ app.grantUriPermission(OSMAND_PACKAGE_NAME, gpxUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ return mIOsmAndAidlInterface!!.navigateGpx(NavigateGpxParams(gpxUri, force))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Import GPX file to OsmAnd.
+ *
+ * @param data - Raw contents of GPX file. Sent as intent's extra string parameter.
+ * @param fileName - Destination file name. May contain dirs.
+ * @param color - color of gpx. Can be one of: "red", "orange", "lightblue", "blue", "purple",
+ * "translucent_red", "translucent_orange", "translucent_lightblue",
+ * "translucent_blue", "translucent_purple"
+ * @param show - show track on the map after import
+ */
+ fun importGpxFromData(data: String, fileName: String, color: String, show: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.importGpx(ImportGpxParams(data, fileName, color, show))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun navigateGpxFromData(data: String, force: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.navigateGpx(NavigateGpxParams(data, force))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Show GPX file on map.
+ *
+ * @param fileName - file name to show. Must be imported first.
+ */
+ fun showGpx(fileName: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.showGpx(ShowGpxParams(fileName))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Hide GPX file.
+ *
+ * @param fileName - file name to hide.
+ */
+ fun hideGpx(fileName: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.hideGpx(HideGpxParams(fileName))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Remove GPX file.
+ *
+ * @param fileName - file name to remove;
+ */
+ fun removeGpx(fileName: String): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.removeGpx(RemoveGpxParams(fileName))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ /**
+ * Get list of active GPX files.
+ *
+ * @param latitude - latitude of new map center.
+ * @param longitude - longitude of new map center.
+ * @param zoom - map zoom level. Set 0 to keep zoom unchanged.
+ * @param animated - set true to animate changes.
+ */
+ fun setMapLocation(latitude: Double, longitude: Double, zoom: Int, animated: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.setMapLocation(
+ SetMapLocationParams(latitude, longitude, zoom, animated))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun startGpxRecording(params: StartGpxRecordingParams): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.startGpxRecording(params)
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun stopGpxRecording(params: StopGpxRecordingParams): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.stopGpxRecording(params)
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun takePhotoNote(lat: Double, lon: Double): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.takePhotoNote(TakePhotoNoteParams(lat, lon))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun startVideoRecording(lat: Double, lon: Double): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.startVideoRecording(StartVideoRecordingParams(lat, lon))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun startAudioRecording(lat: Double, lon: Double): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.startAudioRecording(StartAudioRecordingParams(lat, lon))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun stopRecording(): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.stopRecording(StopRecordingParams())
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
+
+ fun navigate(startName: String, startLat: Double, startLon: Double, destName: String, destLat: Double, destLon: Double, profile: String, force: Boolean): Boolean {
+ if (mIOsmAndAidlInterface != null) {
+ try {
+ return mIOsmAndAidlInterface!!.navigate(NavigateParams(startName, startLat, startLon, destName, destLat, destLon, profile, force))
+ } catch (e: RemoteException) {
+ e.printStackTrace()
+ }
+
+ }
+ return false
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt
index f8cbfdc863..09f3bc5499 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt
@@ -6,88 +6,88 @@ import net.osmand.telegram.notifications.TelegramNotification.NotificationType
class ShareLocationHelper(private val app: TelegramApplication) {
- companion object {
- const val MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 60 * 60 * 24 - 1 // day
- }
+ companion object {
+ const val MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 60 * 60 * 24 - 1 // day
+ }
- var sharingLocation: Boolean = false
- private set
+ var sharingLocation: Boolean = false
+ private set
- var duration: Long = 0
- private set
+ var duration: Long = 0
+ private set
- var distance: Int = 0
- private set
+ var distance: Int = 0
+ private set
- var lastLocationMessageSentTime: Long = 0
+ var lastLocationMessageSentTime: Long = 0
- private var lastTimeInMillis: Long = 0L
+ private var lastTimeInMillis: Long = 0L
- private var lastLocation: Location? = null
- set(value) {
- if (lastTimeInMillis == 0L) {
- lastTimeInMillis = System.currentTimeMillis()
- } else {
- val currentTimeInMillis = System.currentTimeMillis()
- duration += currentTimeInMillis - lastTimeInMillis
- lastTimeInMillis = currentTimeInMillis
- }
- if (lastLocation != null && value != null) {
- distance += value.distanceTo(lastLocation).toInt()
- }
- field = value
- }
+ private var lastLocation: Location? = null
+ set(value) {
+ if (lastTimeInMillis == 0L) {
+ lastTimeInMillis = System.currentTimeMillis()
+ } else {
+ val currentTimeInMillis = System.currentTimeMillis()
+ duration += currentTimeInMillis - lastTimeInMillis
+ lastTimeInMillis = currentTimeInMillis
+ }
+ if (lastLocation != null && value != null) {
+ distance += value.distanceTo(lastLocation).toInt()
+ }
+ field = value
+ }
- fun updateLocation(location: Location?) {
- lastLocation = location
+ fun updateLocation(location: Location?) {
+ lastLocation = location
- if (location != null && app.isInternetConnectionAvailable) {
- val shareLocationChats = app.settings.getShareLocationChats()
- if (shareLocationChats.isNotEmpty()) {
- app.telegramHelper.sendLiveLocationMessage(shareLocationChats, MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC, location.latitude, location.longitude)
- }
- lastLocationMessageSentTime = System.currentTimeMillis()
- }
- refreshNotification()
- }
+ if (location != null && app.isInternetConnectionAvailable) {
+ val shareLocationChats = app.settings.getShareLocationChats()
+ if (shareLocationChats.isNotEmpty()) {
+ app.telegramHelper.sendLiveLocationMessage(shareLocationChats, MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC, location.latitude, location.longitude)
+ }
+ lastLocationMessageSentTime = System.currentTimeMillis()
+ }
+ refreshNotification()
+ }
- fun startSharingLocation() {
- if (!sharingLocation) {
- sharingLocation = true
+ fun startSharingLocation() {
+ if (!sharingLocation) {
+ sharingLocation = true
- app.startMyLocationService()
+ app.startMyLocationService()
- refreshNotification()
- }
- }
+ refreshNotification()
+ }
+ }
- fun stopSharingLocation() {
- if (sharingLocation) {
- sharingLocation = false
+ fun stopSharingLocation() {
+ if (sharingLocation) {
+ sharingLocation = false
- app.stopMyLocationService()
- lastLocation = null
- lastTimeInMillis = 0L
- distance = 0
- duration = 0
+ app.stopMyLocationService()
+ lastLocation = null
+ lastTimeInMillis = 0L
+ distance = 0
+ duration = 0
- refreshNotification()
- }
- }
+ refreshNotification()
+ }
+ }
- fun pauseSharingLocation() {
- sharingLocation = false
+ fun pauseSharingLocation() {
+ sharingLocation = false
- app.stopMyLocationService()
- lastLocation = null
- lastTimeInMillis = 0L
+ app.stopMyLocationService()
+ lastLocation = null
+ lastTimeInMillis = 0L
- refreshNotification()
- }
+ refreshNotification()
+ }
- private fun refreshNotification() {
- app.runInUIThread {
- app.notificationHelper.refreshNotification(NotificationType.SHARE_LOCATION)
- }
- }
+ private fun refreshNotification() {
+ app.runInUIThread {
+ app.notificationHelper.refreshNotification(NotificationType.LOCATION)
+ }
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt
index ba6dc98e19..091e31ff4e 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt
@@ -7,77 +7,77 @@ import org.drinkless.td.libcore.telegram.TdApi
class ShowLocationHelper(private val app: TelegramApplication) {
- companion object {
- private const val MAP_LAYER_ID = "telegram_layer"
- }
+ companion object {
+ private const val MAP_LAYER_ID = "telegram_layer"
+ }
- private val telegramHelper = app.telegramHelper
- private val osmandHelper = app.osmandHelper
+ private val telegramHelper = app.telegramHelper
+ private val osmandHelper = app.osmandHelper
- var showingLocation: Boolean = false
- private set
+ var showingLocation: Boolean = false
+ private set
- private fun setMapLayer() {
- osmandHelper.addMapLayer(MAP_LAYER_ID, "Telegram", 5.5f, null)
- }
+ private fun setMapLayer() {
+ osmandHelper.addMapLayer(MAP_LAYER_ID, "Telegram", 5.5f, null)
+ }
- fun showLocationOnMap(chatTitle: String, message: TdApi.Message) {
- if (osmandHelper.isOsmandConnected()) {
- val content = message.content
- if (content is TdApi.MessageLocation) {
- var userName = ""
- val user = telegramHelper.getUser(message.senderUserId)
- if (user != null) {
- userName = "${user.firstName} ${user.lastName}".trim()
- if (userName.isEmpty()) {
- userName = user.username
- }
- if (userName.isEmpty()) {
- userName = user.phoneNumber
- }
- }
- if (userName.isEmpty()) {
- userName = message.senderUserId.toString()
- }
- setMapLayer()
- osmandHelper.addMapPoint(MAP_LAYER_ID, "${chatTitle}_${message.senderUserId}", userName, userName,
- chatTitle, Color.RED, ALatLon(content.location.latitude, content.location.longitude), null)
- }
- }
- }
-
- fun showChatMessages(chatTitle: String) {
- if (osmandHelper.isOsmandConnected()) {
- val messages = telegramHelper.getChatMessages(chatTitle)
- for (message in messages) {
- showLocationOnMap(chatTitle, message)
- }
- }
- }
+ fun showLocationOnMap(chatTitle: String, message: TdApi.Message) {
+ if (osmandHelper.isOsmandConnected()) {
+ val content = message.content
+ if (content is TdApi.MessageLocation) {
+ var userName = ""
+ val user = telegramHelper.getUser(message.senderUserId)
+ if (user != null) {
+ userName = "${user.firstName} ${user.lastName}".trim()
+ if (userName.isEmpty()) {
+ userName = user.username
+ }
+ if (userName.isEmpty()) {
+ userName = user.phoneNumber
+ }
+ }
+ if (userName.isEmpty()) {
+ userName = message.senderUserId.toString()
+ }
+ setMapLayer()
+ osmandHelper.addMapPoint(MAP_LAYER_ID, "${chatTitle}_${message.senderUserId}", userName, userName,
+ chatTitle, Color.RED, ALatLon(content.location.latitude, content.location.longitude), null)
+ }
+ }
+ }
- fun hideChatMessages(chatTitle: String) {
- if (osmandHelper.isOsmandConnected()) {
- val messages = telegramHelper.getChatMessages(chatTitle)
- for (message in messages) {
- val user = telegramHelper.getUser(message.senderUserId)
- if (user != null) {
- osmandHelper.removeMapPoint(MAP_LAYER_ID, "${chatTitle}_${message.senderUserId}")
- }
- }
- }
- }
+ fun showChatMessages(chatTitle: String) {
+ if (osmandHelper.isOsmandConnected()) {
+ val messages = telegramHelper.getChatMessages(chatTitle)
+ for (message in messages) {
+ showLocationOnMap(chatTitle, message)
+ }
+ }
+ }
- fun startShowingLocation() {
- if (!showingLocation) {
- showingLocation = true
- app.startUserLocationService()
- }
- }
+ fun hideChatMessages(chatTitle: String) {
+ if (osmandHelper.isOsmandConnected()) {
+ val messages = telegramHelper.getChatMessages(chatTitle)
+ for (message in messages) {
+ val user = telegramHelper.getUser(message.senderUserId)
+ if (user != null) {
+ osmandHelper.removeMapPoint(MAP_LAYER_ID, "${chatTitle}_${message.senderUserId}")
+ }
+ }
+ }
+ }
- fun stopShowingLocation() {
- if (showingLocation) {
- showingLocation = false
- app.stopUserLocationService()
- }
- }
+ fun startShowingLocation() {
+ if (!showingLocation) {
+ showingLocation = true
+ app.startUserLocationService()
+ }
+ }
+
+ fun stopShowingLocation() {
+ if (showingLocation) {
+ showingLocation = false
+ app.stopUserLocationService()
+ }
+ }
}
\ No newline at end of file
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt
index 3933f23dff..3c68ba23c5 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt
@@ -14,716 +14,716 @@ import java.util.concurrent.ConcurrentHashMap
class TelegramHelper private constructor() {
- companion object {
- private val log = PlatformUtil.getLog(TelegramHelper::class.java)
- private const val CHATS_LIMIT = 100
- private const val CHAT_LIVE_USERS_LIMIT = 100
- private const val IGNORED_ERROR_CODE = 406
+ companion object {
+ private val log = PlatformUtil.getLog(TelegramHelper::class.java)
+ private const val CHATS_LIMIT = 100
+ private const val CHAT_LIVE_USERS_LIMIT = 100
+ private const val IGNORED_ERROR_CODE = 406
- private var helper: TelegramHelper? = null
+ private var helper: TelegramHelper? = null
- val instance: TelegramHelper
- get() {
- if (helper == null) {
- helper = TelegramHelper()
- }
- return helper!!
- }
- }
+ val instance: TelegramHelper
+ get() {
+ if (helper == null) {
+ helper = TelegramHelper()
+ }
+ return helper!!
+ }
+ }
- private val users = ConcurrentHashMap()
- private val basicGroups = ConcurrentHashMap()
- private val supergroups = ConcurrentHashMap()
- private val secretChats = ConcurrentHashMap()
+ private val users = ConcurrentHashMap()
+ private val basicGroups = ConcurrentHashMap()
+ private val supergroups = ConcurrentHashMap()
+ private val secretChats = ConcurrentHashMap()
- private val chats = ConcurrentHashMap()
- private val chatTitles = ConcurrentHashMap()
- private val chatList = TreeSet()
- private val chatLiveMessages = ConcurrentHashMap()
+ private val chats = ConcurrentHashMap()
+ private val chatTitles = ConcurrentHashMap()
+ private val chatList = TreeSet()
+ private val chatLiveMessages = ConcurrentHashMap()
- private val usersLiveMessages = ConcurrentHashMap()
+ private val usersLiveMessages = ConcurrentHashMap()
- private val usersFullInfo = ConcurrentHashMap()
- private val basicGroupsFullInfo = ConcurrentHashMap()
- private val supergroupsFullInfo = ConcurrentHashMap()
+ private val usersFullInfo = ConcurrentHashMap()
+ private val basicGroupsFullInfo = ConcurrentHashMap()
+ private val supergroupsFullInfo = ConcurrentHashMap()
- var appDir: String? = null
- private var libraryLoaded = false
- private var telegramAuthorizationRequestHandler: TelegramAuthorizationRequestHandler? = null
+ var appDir: String? = null
+ private var libraryLoaded = false
+ private var telegramAuthorizationRequestHandler: TelegramAuthorizationRequestHandler? = null
- private var client: Client? = null
+ private var client: Client? = null
- private var haveFullChatList: Boolean = false
- private var needRefreshActiveLiveLocationMessages: Boolean = true
- private var requestingActiveLiveLocationMessages: Boolean = false
+ private var haveFullChatList: Boolean = false
+ private var needRefreshActiveLiveLocationMessages: Boolean = true
+ private var requestingActiveLiveLocationMessages: Boolean = false
- private var authorizationState: AuthorizationState? = null
- private var haveAuthorization = false
+ private var authorizationState: AuthorizationState? = null
+ private var haveAuthorization = false
- private val defaultHandler = DefaultHandler()
- private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler()
+ private val defaultHandler = DefaultHandler()
+ private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler()
- var listener: TelegramListener? = null
- var incomingMessagesListener: TelegramIncomingMessagesListener? = null
+ var listener: TelegramListener? = null
+ var incomingMessagesListener: TelegramIncomingMessagesListener? = null
- fun getChatList(): TreeSet {
- synchronized(chatList) {
- return TreeSet(chatList)
- }
- }
+ fun getChatList(): TreeSet {
+ synchronized(chatList) {
+ return TreeSet(chatList)
+ }
+ }
- fun getChatTitles(): List {
- return chatTitles.keys().toList()
- }
+ fun getChatTitles(): List {
+ return chatTitles.keys().toList()
+ }
- fun getChat(id: Long): TdApi.Chat? {
- return chats[id]
- }
+ fun getChat(id: Long): TdApi.Chat? {
+ return chats[id]
+ }
- fun getUser(id: Int): TdApi.User? {
- return users[id]
- }
+ fun getUser(id: Int): TdApi.User? {
+ return users[id]
+ }
- fun getChatMessages(chatTitle: String): List {
- val res = mutableListOf()
- for (message in usersLiveMessages.values) {
- val title = chats[message.chatId]?.title
- if (title == chatTitle) {
- res.add(message)
- }
- }
- return res
- }
+ fun getChatMessages(chatTitle: String): List {
+ val res = mutableListOf()
+ for (message in usersLiveMessages.values) {
+ val title = chats[message.chatId]?.title
+ if (title == chatTitle) {
+ res.add(message)
+ }
+ }
+ return res
+ }
- private fun updateChatTitles() {
- chatTitles.clear()
- for (chatEntry in chats.entries) {
- chatTitles[chatEntry.value.title] = chatEntry.key
- }
- }
+ private fun updateChatTitles() {
+ chatTitles.clear()
+ for (chatEntry in chats.entries) {
+ chatTitles[chatEntry.value.title] = chatEntry.key
+ }
+ }
- enum class TelegramAuthenticationParameterType {
- PHONE_NUMBER,
- CODE,
- PASSWORD
- }
+ enum class TelegramAuthenticationParameterType {
+ PHONE_NUMBER,
+ CODE,
+ PASSWORD
+ }
- enum class TelegramAuthorizationState {
- UNKNOWN,
- WAIT_PARAMETERS,
- WAIT_PHONE_NUMBER,
- WAIT_CODE,
- WAIT_PASSWORD,
- READY,
- LOGGING_OUT,
- CLOSING,
- CLOSED
- }
+ enum class TelegramAuthorizationState {
+ UNKNOWN,
+ WAIT_PARAMETERS,
+ WAIT_PHONE_NUMBER,
+ WAIT_CODE,
+ WAIT_PASSWORD,
+ READY,
+ LOGGING_OUT,
+ CLOSING,
+ CLOSED
+ }
- interface TelegramListener {
- fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState,
- newTelegramAuthorizationState: TelegramAuthorizationState)
+ interface TelegramListener {
+ fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState,
+ newTelegramAuthorizationState: TelegramAuthorizationState)
- fun onTelegramChatsRead()
- fun onTelegramChatsChanged()
- fun onTelegramError(code: Int, message: String)
- fun onSendLiveLicationError(code: Int, message: String)
- }
+ fun onTelegramChatsRead()
+ fun onTelegramChatsChanged()
+ fun onTelegramError(code: Int, message: String)
+ fun onSendLiveLicationError(code: Int, message: String)
+ }
- interface TelegramIncomingMessagesListener {
- fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message)
- }
+ interface TelegramIncomingMessagesListener {
+ fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message)
+ }
- interface TelegramAuthorizationRequestListener {
- fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType)
- fun onTelegramAuthorizationRequestError(code: Int, message: String)
- }
+ interface TelegramAuthorizationRequestListener {
+ fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType)
+ fun onTelegramAuthorizationRequestError(code: Int, message: String)
+ }
- inner class TelegramAuthorizationRequestHandler(val telegramAuthorizationRequestListener: TelegramAuthorizationRequestListener) {
+ inner class TelegramAuthorizationRequestHandler(val telegramAuthorizationRequestListener: TelegramAuthorizationRequestListener) {
- fun applyAuthenticationParameter(parameterType: TelegramAuthenticationParameterType, parameterValue: String) {
- if (!TextUtils.isEmpty(parameterValue)) {
- when (parameterType) {
- PHONE_NUMBER -> client!!.send(TdApi.SetAuthenticationPhoneNumber(parameterValue, false, false), AuthorizationRequestHandler())
- CODE -> client!!.send(TdApi.CheckAuthenticationCode(parameterValue, "", ""), AuthorizationRequestHandler())
- PASSWORD -> client!!.send(TdApi.CheckAuthenticationPassword(parameterValue), AuthorizationRequestHandler())
- }
- }
- }
- }
+ fun applyAuthenticationParameter(parameterType: TelegramAuthenticationParameterType, parameterValue: String) {
+ if (!TextUtils.isEmpty(parameterValue)) {
+ when (parameterType) {
+ PHONE_NUMBER -> client!!.send(TdApi.SetAuthenticationPhoneNumber(parameterValue, false, false), AuthorizationRequestHandler())
+ CODE -> client!!.send(TdApi.CheckAuthenticationCode(parameterValue, "", ""), AuthorizationRequestHandler())
+ PASSWORD -> client!!.send(TdApi.CheckAuthenticationPassword(parameterValue), AuthorizationRequestHandler())
+ }
+ }
+ }
+ }
- fun getTelegramAuthorizationState(): TelegramAuthorizationState {
- val authorizationState = this.authorizationState
- ?: return TelegramAuthorizationState.UNKNOWN
- return when (authorizationState.constructor) {
- TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PARAMETERS
- TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PHONE_NUMBER
- TdApi.AuthorizationStateWaitCode.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_CODE
- TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PASSWORD
- TdApi.AuthorizationStateReady.CONSTRUCTOR -> TelegramAuthorizationState.READY
- TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR -> TelegramAuthorizationState.LOGGING_OUT
- TdApi.AuthorizationStateClosing.CONSTRUCTOR -> TelegramAuthorizationState.CLOSING
- TdApi.AuthorizationStateClosed.CONSTRUCTOR -> TelegramAuthorizationState.CLOSED
- else -> TelegramAuthorizationState.UNKNOWN
- }
- }
+ fun getTelegramAuthorizationState(): TelegramAuthorizationState {
+ val authorizationState = this.authorizationState
+ ?: return TelegramAuthorizationState.UNKNOWN
+ return when (authorizationState.constructor) {
+ TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PARAMETERS
+ TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PHONE_NUMBER
+ TdApi.AuthorizationStateWaitCode.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_CODE
+ TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PASSWORD
+ TdApi.AuthorizationStateReady.CONSTRUCTOR -> TelegramAuthorizationState.READY
+ TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR -> TelegramAuthorizationState.LOGGING_OUT
+ TdApi.AuthorizationStateClosing.CONSTRUCTOR -> TelegramAuthorizationState.CLOSING
+ TdApi.AuthorizationStateClosed.CONSTRUCTOR -> TelegramAuthorizationState.CLOSED
+ else -> TelegramAuthorizationState.UNKNOWN
+ }
+ }
- fun setTelegramAuthorizationRequestHandler(telegramAuthorizationRequestListener: TelegramAuthorizationRequestListener): TelegramAuthorizationRequestHandler {
- val handler = TelegramAuthorizationRequestHandler(telegramAuthorizationRequestListener)
- this.telegramAuthorizationRequestHandler = handler
- return handler
- }
+ fun setTelegramAuthorizationRequestHandler(telegramAuthorizationRequestListener: TelegramAuthorizationRequestListener): TelegramAuthorizationRequestHandler {
+ val handler = TelegramAuthorizationRequestHandler(telegramAuthorizationRequestListener)
+ this.telegramAuthorizationRequestHandler = handler
+ return handler
+ }
- init {
- try {
- log.debug("Loading native tdlib...")
- System.loadLibrary("tdjni")
- Client.setLogVerbosityLevel(0)
- libraryLoaded = true
- } catch (e: Throwable) {
- log.error("Failed to load tdlib", e)
- }
+ init {
+ try {
+ log.debug("Loading native tdlib...")
+ System.loadLibrary("tdjni")
+ Client.setLogVerbosityLevel(0)
+ libraryLoaded = true
+ } catch (e: Throwable) {
+ log.error("Failed to load tdlib", e)
+ }
- }
+ }
- fun init(): Boolean {
- return if (libraryLoaded) {
- // create client
- client = Client.create(UpdatesHandler(), null, null)
- client!!.send(TdApi.GetAuthorizationState(), defaultHandler)
- true
- } else {
- false
- }
- }
+ fun init(): Boolean {
+ return if (libraryLoaded) {
+ // create client
+ client = Client.create(UpdatesHandler(), null, null)
+ client!!.send(TdApi.GetAuthorizationState(), defaultHandler)
+ true
+ } else {
+ false
+ }
+ }
- private fun requestChats(reload: Boolean = false) {
- synchronized(chatList) {
- if (reload) {
- chatList.clear()
- haveFullChatList = false
- }
- if (!haveFullChatList && CHATS_LIMIT > chatList.size) {
- // have enough chats in the chat list or chat list is too small
- var offsetOrder = java.lang.Long.MAX_VALUE
- var offsetChatId: Long = 0
- if (!chatList.isEmpty()) {
- val last = chatList.last()
- offsetOrder = last.order
- offsetChatId = last.chatId
- }
- client?.send(TdApi.GetChats(offsetOrder, offsetChatId, CHATS_LIMIT - chatList.size), { obj ->
- when (obj.constructor) {
- TdApi.Error.CONSTRUCTOR -> {
- val error = obj as TdApi.Error
- if (error.code != IGNORED_ERROR_CODE) {
- listener?.onTelegramError(error.code, error.message)
- }
- }
- TdApi.Chats.CONSTRUCTOR -> {
- val chatIds = (obj as TdApi.Chats).chatIds
- if (chatIds.isEmpty()) {
- synchronized(chatList) {
- haveFullChatList = true
- }
- }
- // chats had already been received through updates, let's retry request
- requestChats()
- }
- else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
- }
- })
- return
- }
- }
- updateChatTitles()
- getChatRecentLocationMessages(chatTitles.keys)
- listener?.onTelegramChatsRead()
- }
+ private fun requestChats(reload: Boolean = false) {
+ synchronized(chatList) {
+ if (reload) {
+ chatList.clear()
+ haveFullChatList = false
+ }
+ if (!haveFullChatList && CHATS_LIMIT > chatList.size) {
+ // have enough chats in the chat list or chat list is too small
+ var offsetOrder = java.lang.Long.MAX_VALUE
+ var offsetChatId: Long = 0
+ if (!chatList.isEmpty()) {
+ val last = chatList.last()
+ offsetOrder = last.order
+ offsetChatId = last.chatId
+ }
+ client?.send(TdApi.GetChats(offsetOrder, offsetChatId, CHATS_LIMIT - chatList.size), { obj ->
+ when (obj.constructor) {
+ TdApi.Error.CONSTRUCTOR -> {
+ val error = obj as TdApi.Error
+ if (error.code != IGNORED_ERROR_CODE) {
+ listener?.onTelegramError(error.code, error.message)
+ }
+ }
+ TdApi.Chats.CONSTRUCTOR -> {
+ val chatIds = (obj as TdApi.Chats).chatIds
+ if (chatIds.isEmpty()) {
+ synchronized(chatList) {
+ haveFullChatList = true
+ }
+ }
+ // chats had already been received through updates, let's retry request
+ requestChats()
+ }
+ else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
+ }
+ })
+ return
+ }
+ }
+ updateChatTitles()
+ getChatRecentLocationMessages(chatTitles.keys)
+ listener?.onTelegramChatsRead()
+ }
- private fun getChatRecentLocationMessages(chatTitles: Set) {
- if (haveAuthorization) {
- for (chatTitle in chatTitles) {
- val chatId = this.chatTitles[chatTitle]
- if (chatId != null) {
- client?.send(TdApi.SearchChatRecentLocationMessages(chatId, CHAT_LIVE_USERS_LIMIT), { obj ->
- when (obj.constructor) {
- TdApi.Error.CONSTRUCTOR -> {
- val error = obj as TdApi.Error
- val code = error.code
- if (code != IGNORED_ERROR_CODE && code != 400) {
- listener?.onTelegramError(code, error.message)
- }
- }
- TdApi.Messages.CONSTRUCTOR -> {
- val messages = (obj as TdApi.Messages).messages
- for (message in messages) {
- if (!message.isOutgoing) {
- usersLiveMessages[message.id] = message
- }
- }
- incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, *messages)
- }
- else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
- }
- })
- }
- }
- }
- }
+ private fun getChatRecentLocationMessages(chatTitles: Set) {
+ if (haveAuthorization) {
+ for (chatTitle in chatTitles) {
+ val chatId = this.chatTitles[chatTitle]
+ if (chatId != null) {
+ client?.send(TdApi.SearchChatRecentLocationMessages(chatId, CHAT_LIVE_USERS_LIMIT), { obj ->
+ when (obj.constructor) {
+ TdApi.Error.CONSTRUCTOR -> {
+ val error = obj as TdApi.Error
+ val code = error.code
+ if (code != IGNORED_ERROR_CODE && code != 400) {
+ listener?.onTelegramError(code, error.message)
+ }
+ }
+ TdApi.Messages.CONSTRUCTOR -> {
+ val messages = (obj as TdApi.Messages).messages
+ for (message in messages) {
+ if (!message.isOutgoing) {
+ usersLiveMessages[message.id] = message
+ }
+ }
+ incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, *messages)
+ }
+ else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
+ }
+ })
+ }
+ }
+ }
+ }
- /**
- * @chatId Id of the chat
- * @livePeriod Period for which the location can be updated, in seconds; should be between 60 and 86400 for a live location and 0 otherwise.
- * @latitude Latitude of the location
- * @longitude Longitude of the location
- */
- fun sendLiveLocationMessage(chatTitles: List, livePeriod: Int = 61, latitude: Double, longitude: Double): Boolean {
- if (!requestingActiveLiveLocationMessages && haveAuthorization) {
- if (needRefreshActiveLiveLocationMessages) {
- getActiveLiveLocationMessages {
- sendLiveLocationImpl(chatTitles, livePeriod, latitude, longitude)
- }
- needRefreshActiveLiveLocationMessages = false
- } else {
- sendLiveLocationImpl(chatTitles, livePeriod, latitude, longitude)
- }
- return true
- }
- return false
- }
+ /**
+ * @chatId Id of the chat
+ * @livePeriod Period for which the location can be updated, in seconds; should be between 60 and 86400 for a live location and 0 otherwise.
+ * @latitude Latitude of the location
+ * @longitude Longitude of the location
+ */
+ fun sendLiveLocationMessage(chatTitles: List, livePeriod: Int = 61, latitude: Double, longitude: Double): Boolean {
+ if (!requestingActiveLiveLocationMessages && haveAuthorization) {
+ if (needRefreshActiveLiveLocationMessages) {
+ getActiveLiveLocationMessages {
+ sendLiveLocationImpl(chatTitles, livePeriod, latitude, longitude)
+ }
+ needRefreshActiveLiveLocationMessages = false
+ } else {
+ sendLiveLocationImpl(chatTitles, livePeriod, latitude, longitude)
+ }
+ return true
+ }
+ return false
+ }
- private fun getActiveLiveLocationMessages(onComplete: (() -> Unit)?) {
- requestingActiveLiveLocationMessages = true
- client?.send(TdApi.GetActiveLiveLocationMessages(), { obj ->
- when (obj.constructor) {
- TdApi.Error.CONSTRUCTOR -> {
- val error = obj as TdApi.Error
- if (error.code != IGNORED_ERROR_CODE) {
- needRefreshActiveLiveLocationMessages = true
- listener?.onSendLiveLicationError(error.code, error.message)
- }
- }
- TdApi.Messages.CONSTRUCTOR -> {
- val messages = (obj as TdApi.Messages).messages
- chatLiveMessages.clear()
- if (messages.isNotEmpty()) {
- for (msg in messages) {
- val chatId = msg.chatId
- chatLiveMessages[chatId] = msg.id
- }
- }
- onComplete?.invoke()
- }
- else -> listener?.onSendLiveLicationError(-1, "Receive wrong response from TDLib: $obj")
- }
- requestingActiveLiveLocationMessages = false
- })
- }
+ private fun getActiveLiveLocationMessages(onComplete: (() -> Unit)?) {
+ requestingActiveLiveLocationMessages = true
+ client?.send(TdApi.GetActiveLiveLocationMessages(), { obj ->
+ when (obj.constructor) {
+ TdApi.Error.CONSTRUCTOR -> {
+ val error = obj as TdApi.Error
+ if (error.code != IGNORED_ERROR_CODE) {
+ needRefreshActiveLiveLocationMessages = true
+ listener?.onSendLiveLicationError(error.code, error.message)
+ }
+ }
+ TdApi.Messages.CONSTRUCTOR -> {
+ val messages = (obj as TdApi.Messages).messages
+ chatLiveMessages.clear()
+ if (messages.isNotEmpty()) {
+ for (msg in messages) {
+ val chatId = msg.chatId
+ chatLiveMessages[chatId] = msg.id
+ }
+ }
+ onComplete?.invoke()
+ }
+ else -> listener?.onSendLiveLicationError(-1, "Receive wrong response from TDLib: $obj")
+ }
+ requestingActiveLiveLocationMessages = false
+ })
+ }
- private fun sendLiveLocationImpl(chatTitles: List, livePeriod: Int = 61, latitude: Double, longitude: Double) {
- val lp = livePeriod.coerceAtLeast(61)
- val location = TdApi.Location(latitude, longitude)
- val content = TdApi.InputMessageLocation(location, lp)
+ private fun sendLiveLocationImpl(chatTitles: List, livePeriod: Int = 61, latitude: Double, longitude: Double) {
+ val lp = livePeriod.coerceAtLeast(61)
+ val location = TdApi.Location(latitude, longitude)
+ val content = TdApi.InputMessageLocation(location, lp)
- for (chatTitle in chatTitles) {
- val chatId = this.chatTitles[chatTitle]
- if (chatId != null) {
- val msgId = chatLiveMessages[chatId]
- if (msgId != null) {
- if (msgId != 0L) {
- client?.send(TdApi.EditMessageLiveLocation(chatId, msgId, null, location), liveLocationMessageUpdatesHandler)
- }
- } else {
- chatLiveMessages[chatId] = 0L
- client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), liveLocationMessageUpdatesHandler)
- }
- }
- }
- }
+ for (chatTitle in chatTitles) {
+ val chatId = this.chatTitles[chatTitle]
+ if (chatId != null) {
+ val msgId = chatLiveMessages[chatId]
+ if (msgId != null) {
+ if (msgId != 0L) {
+ client?.send(TdApi.EditMessageLiveLocation(chatId, msgId, null, location), liveLocationMessageUpdatesHandler)
+ }
+ } else {
+ chatLiveMessages[chatId] = 0L
+ client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), liveLocationMessageUpdatesHandler)
+ }
+ }
+ }
+ }
- /**
- * @chatId Id of the chat
- * @message Text of the message
- */
- fun sendTextMessage(chatId: Long, message: String): Boolean {
- // initialize reply markup just for testing
- //val row = arrayOf(TdApi.InlineKeyboardButton("https://telegram.org?1", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?2", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?3", TdApi.InlineKeyboardButtonTypeUrl()))
- //val replyMarkup = TdApi.ReplyMarkupInlineKeyboard(arrayOf(row, row, row))
+ /**
+ * @chatId Id of the chat
+ * @message Text of the message
+ */
+ fun sendTextMessage(chatId: Long, message: String): Boolean {
+ // initialize reply markup just for testing
+ //val row = arrayOf(TdApi.InlineKeyboardButton("https://telegram.org?1", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?2", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?3", TdApi.InlineKeyboardButtonTypeUrl()))
+ //val replyMarkup = TdApi.ReplyMarkupInlineKeyboard(arrayOf(row, row, row))
- if (haveAuthorization) {
- val content = TdApi.InputMessageText(TdApi.FormattedText(message, null), false, true)
- client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), defaultHandler)
- return true
- }
- return false
- }
+ if (haveAuthorization) {
+ val content = TdApi.InputMessageText(TdApi.FormattedText(message, null), false, true)
+ client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), defaultHandler)
+ return true
+ }
+ return false
+ }
- fun logout(): Boolean {
- return if (libraryLoaded) {
- haveAuthorization = false
- client!!.send(TdApi.LogOut(), defaultHandler)
- true
- } else {
- false
- }
- }
+ fun logout(): Boolean {
+ return if (libraryLoaded) {
+ haveAuthorization = false
+ client!!.send(TdApi.LogOut(), defaultHandler)
+ true
+ } else {
+ false
+ }
+ }
- fun close(): Boolean {
- return if (libraryLoaded) {
- haveAuthorization = false
- client!!.send(TdApi.Close(), defaultHandler)
- true
- } else {
- false
- }
- }
+ fun close(): Boolean {
+ return if (libraryLoaded) {
+ haveAuthorization = false
+ client!!.send(TdApi.Close(), defaultHandler)
+ true
+ } else {
+ false
+ }
+ }
- private fun setChatOrder(chat: TdApi.Chat, order: Long) {
- synchronized(chatList) {
- if (chat.order != 0L) {
- chatList.remove(OrderedChat(chat.order, chat.id))
- }
+ private fun setChatOrder(chat: TdApi.Chat, order: Long) {
+ synchronized(chatList) {
+ if (chat.order != 0L) {
+ chatList.remove(OrderedChat(chat.order, chat.id))
+ }
- chat.order = order
+ chat.order = order
- if (chat.order != 0L) {
- chatList.add(OrderedChat(chat.order, chat.id))
- }
- }
- }
+ if (chat.order != 0L) {
+ chatList.add(OrderedChat(chat.order, chat.id))
+ }
+ }
+ }
- private inner class LiveLocationMessageUpdatesHandler : ResultHandler {
- override fun onResult(obj: TdApi.Object) {
- when (obj.constructor) {
- TdApi.Error.CONSTRUCTOR -> {
- val error = obj as TdApi.Error
- if (error.code != IGNORED_ERROR_CODE) {
- needRefreshActiveLiveLocationMessages = true
- listener?.onSendLiveLicationError(error.code, error.message)
- }
- }
- else -> {
- if (obj is TdApi.Message) {
- when (obj.sendingState?.constructor) {
- TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
- needRefreshActiveLiveLocationMessages = true
- listener?.onSendLiveLicationError(-1, "Live location message ${obj.id} failed to send")
- }
- }
- }
- }
- }
- }
- }
+ private inner class LiveLocationMessageUpdatesHandler : ResultHandler {
+ override fun onResult(obj: TdApi.Object) {
+ when (obj.constructor) {
+ TdApi.Error.CONSTRUCTOR -> {
+ val error = obj as TdApi.Error
+ if (error.code != IGNORED_ERROR_CODE) {
+ needRefreshActiveLiveLocationMessages = true
+ listener?.onSendLiveLicationError(error.code, error.message)
+ }
+ }
+ else -> {
+ if (obj is TdApi.Message) {
+ when (obj.sendingState?.constructor) {
+ TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
+ needRefreshActiveLiveLocationMessages = true
+ listener?.onSendLiveLicationError(-1, "Live location message ${obj.id} failed to send")
+ }
+ }
+ }
+ }
+ }
+ }
+ }
- private fun onAuthorizationStateUpdated(authorizationState: AuthorizationState?) {
- val prevAuthState = getTelegramAuthorizationState()
- if (authorizationState != null) {
- this.authorizationState = authorizationState
- }
- when (this.authorizationState?.constructor) {
- TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR -> {
- log.info("Init tdlib parameters")
+ private fun onAuthorizationStateUpdated(authorizationState: AuthorizationState?) {
+ val prevAuthState = getTelegramAuthorizationState()
+ if (authorizationState != null) {
+ this.authorizationState = authorizationState
+ }
+ when (this.authorizationState?.constructor) {
+ TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR -> {
+ log.info("Init tdlib parameters")
- val parameters = TdApi.TdlibParameters()
- parameters.databaseDirectory = File(appDir, "tdlib").absolutePath
- parameters.useMessageDatabase = true
- parameters.useSecretChats = true
- parameters.apiId = 94575
- parameters.apiHash = "a3406de8d171bb422bb6ddf3bbd800e2"
- parameters.systemLanguageCode = "en"
- parameters.deviceModel = "Android"
- parameters.systemVersion = "OsmAnd Telegram"
- parameters.applicationVersion = "1.0"
- parameters.enableStorageOptimizer = true
+ val parameters = TdApi.TdlibParameters()
+ parameters.databaseDirectory = File(appDir, "tdlib").absolutePath
+ parameters.useMessageDatabase = true
+ parameters.useSecretChats = true
+ parameters.apiId = 94575
+ parameters.apiHash = "a3406de8d171bb422bb6ddf3bbd800e2"
+ parameters.systemLanguageCode = "en"
+ parameters.deviceModel = "Android"
+ parameters.systemVersion = "OsmAnd Telegram"
+ parameters.applicationVersion = "1.0"
+ parameters.enableStorageOptimizer = true
- client!!.send(TdApi.SetTdlibParameters(parameters), AuthorizationRequestHandler())
- }
- TdApi.AuthorizationStateWaitEncryptionKey.CONSTRUCTOR -> {
- client!!.send(TdApi.CheckDatabaseEncryptionKey(), AuthorizationRequestHandler())
- }
- TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR -> {
- log.info("Request phone number")
- telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(PHONE_NUMBER)
- }
- TdApi.AuthorizationStateWaitCode.CONSTRUCTOR -> {
- log.info("Request code")
- telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(CODE)
- }
- TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR -> {
- log.info("Request password")
- telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(PASSWORD)
- }
- TdApi.AuthorizationStateReady.CONSTRUCTOR -> {
- log.info("Ready")
- }
- TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR -> {
- log.info("Logging out")
- }
- TdApi.AuthorizationStateClosing.CONSTRUCTOR -> {
- log.info("Closing")
- }
- TdApi.AuthorizationStateClosed.CONSTRUCTOR -> {
- log.info("Closed")
- }
- else -> log.error("Unsupported authorization state: " + this.authorizationState!!)
- }
- val wasAuthorized = haveAuthorization
- haveAuthorization = this.authorizationState?.constructor == TdApi.AuthorizationStateReady.CONSTRUCTOR
- if (wasAuthorized != haveAuthorization) {
- needRefreshActiveLiveLocationMessages = true
- if (haveAuthorization) {
- requestChats(true)
- }
- }
- val newAuthState = getTelegramAuthorizationState()
- listener?.onTelegramStatusChanged(prevAuthState, newAuthState)
- }
+ client!!.send(TdApi.SetTdlibParameters(parameters), AuthorizationRequestHandler())
+ }
+ TdApi.AuthorizationStateWaitEncryptionKey.CONSTRUCTOR -> {
+ client!!.send(TdApi.CheckDatabaseEncryptionKey(), AuthorizationRequestHandler())
+ }
+ TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR -> {
+ log.info("Request phone number")
+ telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(PHONE_NUMBER)
+ }
+ TdApi.AuthorizationStateWaitCode.CONSTRUCTOR -> {
+ log.info("Request code")
+ telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(CODE)
+ }
+ TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR -> {
+ log.info("Request password")
+ telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(PASSWORD)
+ }
+ TdApi.AuthorizationStateReady.CONSTRUCTOR -> {
+ log.info("Ready")
+ }
+ TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR -> {
+ log.info("Logging out")
+ }
+ TdApi.AuthorizationStateClosing.CONSTRUCTOR -> {
+ log.info("Closing")
+ }
+ TdApi.AuthorizationStateClosed.CONSTRUCTOR -> {
+ log.info("Closed")
+ }
+ else -> log.error("Unsupported authorization state: " + this.authorizationState!!)
+ }
+ val wasAuthorized = haveAuthorization
+ haveAuthorization = this.authorizationState?.constructor == TdApi.AuthorizationStateReady.CONSTRUCTOR
+ if (wasAuthorized != haveAuthorization) {
+ needRefreshActiveLiveLocationMessages = true
+ if (haveAuthorization) {
+ requestChats(true)
+ }
+ }
+ val newAuthState = getTelegramAuthorizationState()
+ listener?.onTelegramStatusChanged(prevAuthState, newAuthState)
+ }
- class OrderedChat internal constructor(internal val order: Long, internal val chatId: Long) : Comparable {
+ class OrderedChat internal constructor(internal val order: Long, internal val chatId: Long) : Comparable {
- override fun compareTo(other: OrderedChat): Int {
- if (this.order != other.order) {
- return if (other.order < this.order) -1 else 1
- }
- return if (this.chatId != other.chatId) {
- if (other.chatId < this.chatId) -1 else 1
- } else 0
- }
+ override fun compareTo(other: OrderedChat): Int {
+ if (this.order != other.order) {
+ return if (other.order < this.order) -1 else 1
+ }
+ return if (this.chatId != other.chatId) {
+ if (other.chatId < this.chatId) -1 else 1
+ } else 0
+ }
- override fun equals(other: Any?): Boolean {
- if (other == null) {
- return false
- }
- if (other !is OrderedChat) {
- return false
- }
- val o = other as OrderedChat?
- return this.order == o!!.order && this.chatId == o.chatId
- }
+ override fun equals(other: Any?): Boolean {
+ if (other == null) {
+ return false
+ }
+ if (other !is OrderedChat) {
+ return false
+ }
+ val o = other as OrderedChat?
+ return this.order == o!!.order && this.chatId == o.chatId
+ }
- override fun hashCode(): Int {
- return (order + chatId).hashCode()
- }
- }
+ override fun hashCode(): Int {
+ return (order + chatId).hashCode()
+ }
+ }
- private class DefaultHandler : ResultHandler {
- override fun onResult(obj: TdApi.Object) {}
- }
+ private class DefaultHandler : ResultHandler {
+ override fun onResult(obj: TdApi.Object) {}
+ }
- private inner class UpdatesHandler : ResultHandler {
- override fun onResult(obj: TdApi.Object) {
- when (obj.constructor) {
- TdApi.UpdateAuthorizationState.CONSTRUCTOR -> onAuthorizationStateUpdated((obj as TdApi.UpdateAuthorizationState).authorizationState)
+ private inner class UpdatesHandler : ResultHandler {
+ override fun onResult(obj: TdApi.Object) {
+ when (obj.constructor) {
+ TdApi.UpdateAuthorizationState.CONSTRUCTOR -> onAuthorizationStateUpdated((obj as TdApi.UpdateAuthorizationState).authorizationState)
- TdApi.UpdateUser.CONSTRUCTOR -> {
- val updateUser = obj as TdApi.UpdateUser
- users[updateUser.user.id] = updateUser.user
- }
- TdApi.UpdateUserStatus.CONSTRUCTOR -> {
- val updateUserStatus = obj as TdApi.UpdateUserStatus
- val user = users[updateUserStatus.userId]
- synchronized(user!!) {
- user.status = updateUserStatus.status
- }
- }
- TdApi.UpdateBasicGroup.CONSTRUCTOR -> {
- val updateBasicGroup = obj as TdApi.UpdateBasicGroup
- basicGroups[updateBasicGroup.basicGroup.id] = updateBasicGroup.basicGroup
- }
- TdApi.UpdateSupergroup.CONSTRUCTOR -> {
- val updateSupergroup = obj as TdApi.UpdateSupergroup
- supergroups[updateSupergroup.supergroup.id] = updateSupergroup.supergroup
- }
- TdApi.UpdateSecretChat.CONSTRUCTOR -> {
- val updateSecretChat = obj as TdApi.UpdateSecretChat
- secretChats[updateSecretChat.secretChat.id] = updateSecretChat.secretChat
- }
+ TdApi.UpdateUser.CONSTRUCTOR -> {
+ val updateUser = obj as TdApi.UpdateUser
+ users[updateUser.user.id] = updateUser.user
+ }
+ TdApi.UpdateUserStatus.CONSTRUCTOR -> {
+ val updateUserStatus = obj as TdApi.UpdateUserStatus
+ val user = users[updateUserStatus.userId]
+ synchronized(user!!) {
+ user.status = updateUserStatus.status
+ }
+ }
+ TdApi.UpdateBasicGroup.CONSTRUCTOR -> {
+ val updateBasicGroup = obj as TdApi.UpdateBasicGroup
+ basicGroups[updateBasicGroup.basicGroup.id] = updateBasicGroup.basicGroup
+ }
+ TdApi.UpdateSupergroup.CONSTRUCTOR -> {
+ val updateSupergroup = obj as TdApi.UpdateSupergroup
+ supergroups[updateSupergroup.supergroup.id] = updateSupergroup.supergroup
+ }
+ TdApi.UpdateSecretChat.CONSTRUCTOR -> {
+ val updateSecretChat = obj as TdApi.UpdateSecretChat
+ secretChats[updateSecretChat.secretChat.id] = updateSecretChat.secretChat
+ }
- TdApi.UpdateNewChat.CONSTRUCTOR -> {
- val updateNewChat = obj as TdApi.UpdateNewChat
- val chat = updateNewChat.chat
- synchronized(chat!!) {
- if (chat.type !is TdApi.ChatTypeSupergroup || !(chat.type as TdApi.ChatTypeSupergroup).isChannel) {
- chats[chat.id] = chat
+ TdApi.UpdateNewChat.CONSTRUCTOR -> {
+ val updateNewChat = obj as TdApi.UpdateNewChat
+ val chat = updateNewChat.chat
+ synchronized(chat!!) {
+ if (chat.type !is TdApi.ChatTypeSupergroup || !(chat.type as TdApi.ChatTypeSupergroup).isChannel) {
+ chats[chat.id] = chat
- val order = chat.order
- chat.order = 0
- setChatOrder(chat, order)
- }
- }
- updateChatTitles()
- listener?.onTelegramChatsChanged()
- }
- TdApi.UpdateChatTitle.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatTitle
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.title = updateChat.title
- }
- updateChatTitles()
- listener?.onTelegramChatsChanged()
- }
- TdApi.UpdateChatPhoto.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatPhoto
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.photo = updateChat.photo
- }
- listener?.onTelegramChatsChanged()
- }
- TdApi.UpdateChatLastMessage.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatLastMessage
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.lastMessage = updateChat.lastMessage
- setChatOrder(chat, updateChat.order)
- }
- }
- TdApi.UpdateChatOrder.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatOrder
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- setChatOrder(chat, updateChat.order)
- }
- listener?.onTelegramChatsChanged()
- }
- TdApi.UpdateChatIsPinned.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatIsPinned
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.isPinned = updateChat.isPinned
- setChatOrder(chat, updateChat.order)
- }
- }
- TdApi.UpdateChatReadInbox.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatReadInbox
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.lastReadInboxMessageId = updateChat.lastReadInboxMessageId
- chat.unreadCount = updateChat.unreadCount
- }
- }
- TdApi.UpdateChatReadOutbox.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatReadOutbox
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.lastReadOutboxMessageId = updateChat.lastReadOutboxMessageId
- }
- }
- TdApi.UpdateChatUnreadMentionCount.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatUnreadMentionCount
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.unreadMentionCount = updateChat.unreadMentionCount
- }
- }
- TdApi.UpdateMessageContent.CONSTRUCTOR -> {
- val updateMessageContent = obj as TdApi.UpdateMessageContent
- val message = usersLiveMessages[updateMessageContent.messageId]
- if (message != null && !message.isOutgoing) {
- message.content = updateMessageContent.newContent
- val chatTitle = chats[message.chatId]?.title
- if (chatTitle != null) {
- incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, message)
- }
- }
- }
- TdApi.UpdateNewMessage.CONSTRUCTOR -> {
- val updateNewMessage = obj as TdApi.UpdateNewMessage
- val message = updateNewMessage.message
- if (!message.isOutgoing && message.content is TdApi.MessageLocation) {
- usersLiveMessages[message.id] = message
- val chatTitle = chats[message.chatId]?.title
- if (chatTitle != null) {
- incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, message)
- }
- }
- }
- TdApi.UpdateMessageMentionRead.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateMessageMentionRead
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.unreadMentionCount = updateChat.unreadMentionCount
- }
- }
- TdApi.UpdateMessageSendFailed.CONSTRUCTOR -> {
- needRefreshActiveLiveLocationMessages = true
- }
- TdApi.UpdateMessageSendSucceeded.CONSTRUCTOR -> {
- val updateMessageSendSucceeded = obj as TdApi.UpdateMessageSendSucceeded
- val message = updateMessageSendSucceeded.message
- chatLiveMessages[message.chatId] = message.id
- }
- TdApi.UpdateDeleteMessages.CONSTRUCTOR -> {
- val updateDeleteMessages = obj as TdApi.UpdateDeleteMessages
- if (updateDeleteMessages.isPermanent) {
- val chatId = updateDeleteMessages.chatId
- for (messageId in updateDeleteMessages.messageIds) {
- if (chatLiveMessages[chatId] == messageId) {
- chatLiveMessages.remove(chatId)
- break
- }
- }
- }
- }
- TdApi.UpdateChatReplyMarkup.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatReplyMarkup
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.replyMarkupMessageId = updateChat.replyMarkupMessageId
- }
- }
- TdApi.UpdateChatDraftMessage.CONSTRUCTOR -> {
- val updateChat = obj as TdApi.UpdateChatDraftMessage
- val chat = chats[updateChat.chatId]
- synchronized(chat!!) {
- chat.draftMessage = updateChat.draftMessage
- setChatOrder(chat, updateChat.order)
- }
- }
- TdApi.UpdateNotificationSettings.CONSTRUCTOR -> {
- val update = obj as TdApi.UpdateNotificationSettings
- if (update.scope is TdApi.NotificationSettingsScopeChat) {
- val chat = chats[(update.scope as TdApi.NotificationSettingsScopeChat).chatId]
- synchronized(chat!!) {
- chat.notificationSettings = update.notificationSettings
- }
- }
- }
+ val order = chat.order
+ chat.order = 0
+ setChatOrder(chat, order)
+ }
+ }
+ updateChatTitles()
+ listener?.onTelegramChatsChanged()
+ }
+ TdApi.UpdateChatTitle.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatTitle
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.title = updateChat.title
+ }
+ updateChatTitles()
+ listener?.onTelegramChatsChanged()
+ }
+ TdApi.UpdateChatPhoto.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatPhoto
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.photo = updateChat.photo
+ }
+ listener?.onTelegramChatsChanged()
+ }
+ TdApi.UpdateChatLastMessage.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatLastMessage
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.lastMessage = updateChat.lastMessage
+ setChatOrder(chat, updateChat.order)
+ }
+ }
+ TdApi.UpdateChatOrder.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatOrder
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ setChatOrder(chat, updateChat.order)
+ }
+ listener?.onTelegramChatsChanged()
+ }
+ TdApi.UpdateChatIsPinned.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatIsPinned
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.isPinned = updateChat.isPinned
+ setChatOrder(chat, updateChat.order)
+ }
+ }
+ TdApi.UpdateChatReadInbox.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatReadInbox
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.lastReadInboxMessageId = updateChat.lastReadInboxMessageId
+ chat.unreadCount = updateChat.unreadCount
+ }
+ }
+ TdApi.UpdateChatReadOutbox.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatReadOutbox
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.lastReadOutboxMessageId = updateChat.lastReadOutboxMessageId
+ }
+ }
+ TdApi.UpdateChatUnreadMentionCount.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatUnreadMentionCount
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.unreadMentionCount = updateChat.unreadMentionCount
+ }
+ }
+ TdApi.UpdateMessageContent.CONSTRUCTOR -> {
+ val updateMessageContent = obj as TdApi.UpdateMessageContent
+ val message = usersLiveMessages[updateMessageContent.messageId]
+ if (message != null && !message.isOutgoing) {
+ message.content = updateMessageContent.newContent
+ val chatTitle = chats[message.chatId]?.title
+ if (chatTitle != null) {
+ incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, message)
+ }
+ }
+ }
+ TdApi.UpdateNewMessage.CONSTRUCTOR -> {
+ val updateNewMessage = obj as TdApi.UpdateNewMessage
+ val message = updateNewMessage.message
+ if (!message.isOutgoing && message.content is TdApi.MessageLocation) {
+ usersLiveMessages[message.id] = message
+ val chatTitle = chats[message.chatId]?.title
+ if (chatTitle != null) {
+ incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, message)
+ }
+ }
+ }
+ TdApi.UpdateMessageMentionRead.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateMessageMentionRead
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.unreadMentionCount = updateChat.unreadMentionCount
+ }
+ }
+ TdApi.UpdateMessageSendFailed.CONSTRUCTOR -> {
+ needRefreshActiveLiveLocationMessages = true
+ }
+ TdApi.UpdateMessageSendSucceeded.CONSTRUCTOR -> {
+ val updateMessageSendSucceeded = obj as TdApi.UpdateMessageSendSucceeded
+ val message = updateMessageSendSucceeded.message
+ chatLiveMessages[message.chatId] = message.id
+ }
+ TdApi.UpdateDeleteMessages.CONSTRUCTOR -> {
+ val updateDeleteMessages = obj as TdApi.UpdateDeleteMessages
+ if (updateDeleteMessages.isPermanent) {
+ val chatId = updateDeleteMessages.chatId
+ for (messageId in updateDeleteMessages.messageIds) {
+ if (chatLiveMessages[chatId] == messageId) {
+ chatLiveMessages.remove(chatId)
+ break
+ }
+ }
+ }
+ }
+ TdApi.UpdateChatReplyMarkup.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatReplyMarkup
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.replyMarkupMessageId = updateChat.replyMarkupMessageId
+ }
+ }
+ TdApi.UpdateChatDraftMessage.CONSTRUCTOR -> {
+ val updateChat = obj as TdApi.UpdateChatDraftMessage
+ val chat = chats[updateChat.chatId]
+ synchronized(chat!!) {
+ chat.draftMessage = updateChat.draftMessage
+ setChatOrder(chat, updateChat.order)
+ }
+ }
+ TdApi.UpdateNotificationSettings.CONSTRUCTOR -> {
+ val update = obj as TdApi.UpdateNotificationSettings
+ if (update.scope is TdApi.NotificationSettingsScopeChat) {
+ val chat = chats[(update.scope as TdApi.NotificationSettingsScopeChat).chatId]
+ synchronized(chat!!) {
+ chat.notificationSettings = update.notificationSettings
+ }
+ }
+ }
- TdApi.UpdateUserFullInfo.CONSTRUCTOR -> {
- val updateUserFullInfo = obj as TdApi.UpdateUserFullInfo
- usersFullInfo[updateUserFullInfo.userId] = updateUserFullInfo.userFullInfo
- }
- TdApi.UpdateBasicGroupFullInfo.CONSTRUCTOR -> {
- val updateBasicGroupFullInfo = obj as TdApi.UpdateBasicGroupFullInfo
- basicGroupsFullInfo[updateBasicGroupFullInfo.basicGroupId] = updateBasicGroupFullInfo.basicGroupFullInfo
- }
- TdApi.UpdateSupergroupFullInfo.CONSTRUCTOR -> {
- val updateSupergroupFullInfo = obj as TdApi.UpdateSupergroupFullInfo
- supergroupsFullInfo[updateSupergroupFullInfo.supergroupId] = updateSupergroupFullInfo.supergroupFullInfo
- }
- }
- }
- }
+ TdApi.UpdateUserFullInfo.CONSTRUCTOR -> {
+ val updateUserFullInfo = obj as TdApi.UpdateUserFullInfo
+ usersFullInfo[updateUserFullInfo.userId] = updateUserFullInfo.userFullInfo
+ }
+ TdApi.UpdateBasicGroupFullInfo.CONSTRUCTOR -> {
+ val updateBasicGroupFullInfo = obj as TdApi.UpdateBasicGroupFullInfo
+ basicGroupsFullInfo[updateBasicGroupFullInfo.basicGroupId] = updateBasicGroupFullInfo.basicGroupFullInfo
+ }
+ TdApi.UpdateSupergroupFullInfo.CONSTRUCTOR -> {
+ val updateSupergroupFullInfo = obj as TdApi.UpdateSupergroupFullInfo
+ supergroupsFullInfo[updateSupergroupFullInfo.supergroupId] = updateSupergroupFullInfo.supergroupFullInfo
+ }
+ }
+ }
+ }
- private inner class AuthorizationRequestHandler : ResultHandler {
- override fun onResult(obj: TdApi.Object) {
- when (obj.constructor) {
- TdApi.Error.CONSTRUCTOR -> {
- log.error("Receive an error: $obj")
- val errorObj = obj as TdApi.Error
- if (errorObj.code != IGNORED_ERROR_CODE) {
- telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onTelegramAuthorizationRequestError(errorObj.code, errorObj.message)
- onAuthorizationStateUpdated(null) // repeat last action
- }
- }
- TdApi.Ok.CONSTRUCTOR -> {
- }
- else -> log.error("Receive wrong response from TDLib: $obj")
- }// result is already received through UpdateAuthorizationState, nothing to do
- }
- }
+ private inner class AuthorizationRequestHandler : ResultHandler {
+ override fun onResult(obj: TdApi.Object) {
+ when (obj.constructor) {
+ TdApi.Error.CONSTRUCTOR -> {
+ log.error("Receive an error: $obj")
+ val errorObj = obj as TdApi.Error
+ if (errorObj.code != IGNORED_ERROR_CODE) {
+ telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onTelegramAuthorizationRequestError(errorObj.code, errorObj.message)
+ onAuthorizationStateUpdated(null) // repeat last action
+ }
+ }
+ TdApi.Ok.CONSTRUCTOR -> {
+ }
+ else -> log.error("Receive wrong response from TDLib: $obj")
+ }// result is already received through UpdateAuthorizationState, nothing to do
+ }
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/notifications/LocationNotification.kt b/OsmAnd-telegram/src/net/osmand/telegram/notifications/LocationNotification.kt
new file mode 100644
index 0000000000..9d2a656b86
--- /dev/null
+++ b/OsmAnd-telegram/src/net/osmand/telegram/notifications/LocationNotification.kt
@@ -0,0 +1,60 @@
+package net.osmand.telegram.notifications
+
+import android.support.v4.app.NotificationCompat
+import android.support.v4.content.ContextCompat
+import net.osmand.telegram.R
+import net.osmand.telegram.TelegramApplication
+import net.osmand.telegram.utils.OsmandFormatter
+import net.osmand.util.Algorithms
+
+class LocationNotification(app: TelegramApplication) : TelegramNotification(app, GROUP_NAME) {
+
+ companion object {
+ const val GROUP_NAME = "share_location"
+ }
+
+ override val type: TelegramNotification.NotificationType
+ get() = TelegramNotification.NotificationType.LOCATION
+
+ override val priority: Int
+ get() = NotificationCompat.PRIORITY_DEFAULT
+
+ override val isActive: Boolean
+ get() {
+ val service = app.telegramService
+ return isEnabled && service != null
+ }
+
+ override val isEnabled: Boolean
+ get() = app.settings.hasAnyChatToShareLocation()
+
+ override val telegramNotificationId: Int
+ get() = TelegramNotification.LOCATION_NOTIFICATION_SERVICE_ID
+
+ override val telegramWearableNotificationId: Int
+ get() = TelegramNotification.WEAR_LOCATION_NOTIFICATION_SERVICE_ID
+
+ override fun buildNotification(wearable: Boolean): NotificationCompat.Builder {
+ val notificationTitle: String
+ val notificationText: String
+ val shareLocationHelper = app.shareLocationHelper
+ if (shareLocationHelper.sharingLocation) {
+ val sharedDistance = shareLocationHelper.distance.toFloat()
+ color = ContextCompat.getColor(app, R.color.osmand_orange)
+ icon = R.drawable.ic_action_polygom_dark
+ notificationTitle = (app.getString(R.string.sharing_location) + " • "
+ + Algorithms.formatDuration((shareLocationHelper.duration / 1000).toInt(), true))
+ notificationText = (app.getString(R.string.shared_string_distance)
+ + ": " + OsmandFormatter.getFormattedDistance(sharedDistance, app))
+ } else {
+ notificationTitle = app.getString(R.string.show_users_on_map)
+ notificationText = app.getString(R.string.active_chats) + ": " + app.settings.getShowOnMapChatsCount()
+ color = 0
+ icon = R.drawable.ic_action_view
+ }
+
+ return createBuilder(wearable)
+ .setContentTitle(notificationTitle)
+ .setStyle(NotificationCompat.BigTextStyle().bigText(notificationText))
+ }
+}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/notifications/NotificationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/notifications/NotificationHelper.kt
index 5f87676f29..78c576e888 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/notifications/NotificationHelper.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/notifications/NotificationHelper.kt
@@ -5,46 +5,43 @@ import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
-import android.support.v4.app.NotificationManagerCompat
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
-import java.util.*
class NotificationHelper(private val app: TelegramApplication) {
- val shareLocationNotification = ShareLocationNotification(app)
- val showLocationNotification = ShowLocationNotification(app)
+ val locationNotification = LocationNotification(app)
- private val all = listOf(shareLocationNotification, showLocationNotification)
+ private val all = listOf(locationNotification)
- fun buildNotification(telegramNotification: TelegramNotification): Notification {
- return telegramNotification.buildNotification(false).build()
- }
+ fun buildNotification(telegramNotification: TelegramNotification): Notification {
+ return telegramNotification.buildNotification(false).build()
+ }
- fun refreshNotification(notificationType: NotificationType) {
- for (notification in all) {
- if (notification.type == notificationType) {
- notification.refreshNotification()
- break
- }
- }
- }
+ fun refreshNotification(notificationType: NotificationType) {
+ for (notification in all) {
+ if (notification.type == notificationType) {
+ notification.refreshNotification()
+ break
+ }
+ }
+ }
- @TargetApi(26)
- fun createNotificationChannel() {
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
- val channel = NotificationChannel(NOTIFICATION_CHANEL_ID,
- app.getString(R.string.osmand_service), NotificationManager.IMPORTANCE_LOW)
- channel.enableVibration(false)
- channel.description = app.getString(R.string.osmand_service_descr)
- val mNotificationManager = app
- .getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
- mNotificationManager.createNotificationChannel(channel)
- }
- }
+ @TargetApi(26)
+ fun createNotificationChannel() {
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+ val channel = NotificationChannel(NOTIFICATION_CHANEL_ID,
+ app.getString(R.string.osmand_service), NotificationManager.IMPORTANCE_LOW)
+ channel.enableVibration(false)
+ channel.description = app.getString(R.string.osmand_service_descr)
+ val mNotificationManager = app
+ .getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ mNotificationManager.createNotificationChannel(channel)
+ }
+ }
- companion object {
- const val NOTIFICATION_CHANEL_ID = "osmand_telegram_background_service"
- }
+ companion object {
+ const val NOTIFICATION_CHANEL_ID = "osmand_telegram_background_service"
+ }
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShareLocationNotification.kt b/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShareLocationNotification.kt
deleted file mode 100644
index e52c82386d..0000000000
--- a/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShareLocationNotification.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package net.osmand.telegram.notifications
-
-import android.support.v4.app.NotificationCompat
-import android.support.v4.content.ContextCompat
-import net.osmand.telegram.R
-import net.osmand.telegram.TelegramApplication
-import net.osmand.telegram.utils.OsmandFormatter
-import net.osmand.util.Algorithms
-
-class ShareLocationNotification(app: TelegramApplication) : TelegramNotification(app, GROUP_NAME) {
-
- companion object {
- const val GROUP_NAME = "share_location"
- }
-
- override val type: TelegramNotification.NotificationType
- get() = TelegramNotification.NotificationType.SHARE_LOCATION
-
- override val priority: Int
- get() = NotificationCompat.PRIORITY_DEFAULT
-
- override val isActive: Boolean
- get() {
- val service = app.myLocationService
- return isEnabled && service != null
- }
-
- override val isEnabled: Boolean
- get() = app.settings.hasAnyChatToShareLocation()
-
- override val telegramNotificationId: Int
- get() = TelegramNotification.SHARE_LOCATION_NOTIFICATION_SERVICE_ID
-
- override val telegramWearableNotificationId: Int
- get() = TelegramNotification.WEAR_SHARE_LOCATION_NOTIFICATION_SERVICE_ID
-
- override fun buildNotification(wearable: Boolean): NotificationCompat.Builder {
- icon = R.drawable.ic_action_polygom_dark
- val shareLocationHelper = app.shareLocationHelper
- val sharedDistance = shareLocationHelper.distance.toFloat()
- color = ContextCompat.getColor(app, R.color.osmand_orange)
- val notificationTitle = (app.getString(R.string.sharing_location) + " • "
- + Algorithms.formatDuration((shareLocationHelper.duration / 1000).toInt(), true))
- val notificationText = (app.getString(R.string.shared_string_distance)
- + ": " + OsmandFormatter.getFormattedDistance(sharedDistance, app))
-
- return createBuilder(wearable)
- .setContentTitle(notificationTitle)
- .setStyle(NotificationCompat.BigTextStyle().bigText(notificationText))
- }
-}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShowLocationNotification.kt b/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShowLocationNotification.kt
deleted file mode 100644
index f1e38eb02d..0000000000
--- a/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShowLocationNotification.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package net.osmand.telegram.notifications
-
-import android.support.v4.app.NotificationCompat
-import net.osmand.telegram.R
-import net.osmand.telegram.TelegramApplication
-
-class ShowLocationNotification(app: TelegramApplication) : TelegramNotification(app, GROUP_NAME) {
-
- companion object {
-
- const val GROUP_NAME = "show_location"
- }
-
- override val type: TelegramNotification.NotificationType
- get() = NotificationType.SHOW_LOCATION
-
- override val priority: Int
- get() = NotificationCompat.PRIORITY_DEFAULT
-
- override val isActive: Boolean
- get() {
- val service = app.userLocationService
- return isEnabled && service != null
- }
-
- override val isEnabled: Boolean
- get() = app.settings.hasAnyChatToShowOnMap()
-
- override val telegramNotificationId: Int
- get() = TelegramNotification.SHOW_LOCATION_NOTIFICATION_SERVICE_ID
-
- override val telegramWearableNotificationId: Int
- get() = TelegramNotification.WEAR_SHOW_LOCATION_NOTIFICATION_SERVICE_ID
-
- override fun buildNotification(wearable: Boolean): NotificationCompat.Builder {
- val notificationTitle: String = app.getString(R.string.show_users_on_map)
- val notificationText: String = app.getString(R.string.active_chats) + ": " + app.settings.getShowOnMapChatsCount()
- color = 0
- icon = R.drawable.ic_action_view
-
- return createBuilder(wearable)
- .setContentTitle(notificationTitle)
- .setStyle(NotificationCompat.BigTextStyle().bigText(notificationText))
- }
-}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/notifications/TelegramNotification.kt b/OsmAnd-telegram/src/net/osmand/telegram/notifications/TelegramNotification.kt
index 135d671c8d..521a047744 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/notifications/TelegramNotification.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/notifications/TelegramNotification.kt
@@ -13,11 +13,9 @@ abstract class TelegramNotification(protected var app: TelegramApplication, val
companion object {
- const val SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 6
- const val SHOW_LOCATION_NOTIFICATION_SERVICE_ID = 7
+ const val LOCATION_NOTIFICATION_SERVICE_ID = 6
- const val WEAR_SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 1006
- const val WEAR_SHOW_LOCATION_NOTIFICATION_SERVICE_ID = 1006
+ const val WEAR_LOCATION_NOTIFICATION_SERVICE_ID = 1006
}
protected var ongoing = true
@@ -37,8 +35,7 @@ abstract class TelegramNotification(protected var app: TelegramApplication, val
abstract val isEnabled: Boolean
enum class NotificationType {
- SHARE_LOCATION,
- SHOW_LOCATION
+ LOCATION,
}
@SuppressLint("InlinedApi")
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/services/MyLocationService.kt b/OsmAnd-telegram/src/net/osmand/telegram/services/MyLocationService.kt
deleted file mode 100644
index 5390ee6cb2..0000000000
--- a/OsmAnd-telegram/src/net/osmand/telegram/services/MyLocationService.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-package net.osmand.telegram.services
-
-import android.app.Service
-import android.content.Context
-import android.content.Intent
-import android.location.Location
-import android.location.LocationListener
-import android.location.LocationManager
-import android.os.Binder
-import android.os.Bundle
-import android.os.Handler
-import android.os.IBinder
-import android.util.Log
-import android.widget.Toast
-import net.osmand.PlatformUtil
-import net.osmand.telegram.R
-import net.osmand.telegram.TelegramApplication
-
-class MyLocationService : Service(), LocationListener {
-
- private val binder = LocationServiceBinder()
- private fun app() = application as TelegramApplication
-
- var handler: Handler? = null
-
- class LocationServiceBinder : Binder()
-
- override fun onBind(intent: Intent): IBinder? {
- return binder
- }
-
- fun stopIfNeeded(ctx: Context) {
- val serviceIntent = Intent(ctx, MyLocationService::class.java)
- ctx.stopService(serviceIntent)
- }
-
- override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
- handler = Handler()
- val app = app()
-
- app.myLocationService = this
-
- // requesting
- // request location updates
- val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
- try {
- locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this@MyLocationService)
- } catch (e: SecurityException) {
- Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
- Log.d(PlatformUtil.TAG, "Location service permission not granted")
- } catch (e: IllegalArgumentException) {
- Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show()
- Log.d(PlatformUtil.TAG, "GPS location provider not available")
- }
-
- val shareLocationNotification = app.notificationHelper.shareLocationNotification
- val notification = app.notificationHelper.buildNotification(shareLocationNotification)
- startForeground(shareLocationNotification.telegramNotificationId, notification)
- app.notificationHelper.refreshNotification(shareLocationNotification.type)
- return Service.START_REDELIVER_INTENT
- }
-
- override fun onDestroy() {
- super.onDestroy()
- val app = app()
- app.myLocationService = null
-
- // remove updates
- val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
- try {
- locationManager.removeUpdates(this)
- } catch (e: SecurityException) {
- Log.d(PlatformUtil.TAG, "Location service permission not granted")
- }
-
- // remove notification
- stopForeground(java.lang.Boolean.TRUE)
- }
-
- override fun onLocationChanged(l: Location?) {
- if (l != null) {
- val location = convertLocation(l)
- app().shareLocationHelper.updateLocation(location)
- }
- }
-
- override fun onProviderDisabled(provider: String) {
- Toast.makeText(this, getString(R.string.location_service_no_gps_available), Toast.LENGTH_LONG).show()
- }
-
-
- override fun onProviderEnabled(provider: String) {}
-
-
- override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
-
- override fun onTaskRemoved(rootIntent: Intent) {
- val app = app()
- if (app.myLocationService != null) {
- // Do not stop service after UI task was dismissed
- //this@MyLocationService.stopSelf()
- }
- }
-
- companion object {
-
- fun convertLocation(l: Location?): net.osmand.Location? {
- if (l == null) {
- return null
- }
- val r = net.osmand.Location(l.provider)
- r.latitude = l.latitude
- r.longitude = l.longitude
- r.time = l.time
- if (l.hasAccuracy()) {
- r.accuracy = l.accuracy
- }
- if (l.hasSpeed()) {
- r.speed = l.speed
- }
- if (l.hasAltitude()) {
- r.altitude = l.altitude
- }
- if (l.hasBearing()) {
- r.bearing = l.bearing
- }
- if (l.hasAltitude()) {
- r.altitude = l.altitude
- }
- return r
- }
- }
-}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/services/UserLocationService.kt b/OsmAnd-telegram/src/net/osmand/telegram/services/UserLocationService.kt
deleted file mode 100644
index a7afdece16..0000000000
--- a/OsmAnd-telegram/src/net/osmand/telegram/services/UserLocationService.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-package net.osmand.telegram.services
-
-import android.app.Service
-import android.content.Context
-import android.content.Intent
-import android.os.AsyncTask
-import android.os.Binder
-import android.os.Handler
-import android.os.IBinder
-import net.osmand.telegram.TelegramApplication
-import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener
-import org.drinkless.td.libcore.telegram.TdApi
-import java.util.concurrent.Executors
-
-class UserLocationService : Service(), TelegramIncomingMessagesListener {
-
- private val binder = LocationServiceBinder()
- private fun app() = application as TelegramApplication
- private val executor = Executors.newSingleThreadExecutor()
-
- var handler: Handler? = null
-
- class LocationServiceBinder : Binder()
-
- override fun onBind(intent: Intent): IBinder? {
- return binder
- }
-
- override fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message) {
- val app = app()
- if (app.settings.isShowingChatOnMap(chatTitle)) {
- ShowMessagesTask(app, chatTitle).executeOnExecutor(executor, *messages)
- }
- }
-
- fun stopIfNeeded(ctx: Context) {
- val serviceIntent = Intent(ctx, UserLocationService::class.java)
- ctx.stopService(serviceIntent)
- }
-
- override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
- handler = Handler()
- val app = app()
-
- app.userLocationService = this
- app.telegramHelper.incomingMessagesListener = this
-
- val showLocationNotification = app.notificationHelper.showLocationNotification
- val notification = app.notificationHelper.buildNotification(showLocationNotification)
- startForeground(showLocationNotification.telegramNotificationId, notification)
- app.notificationHelper.refreshNotification(showLocationNotification.type)
- return Service.START_REDELIVER_INTENT
- }
-
- override fun onDestroy() {
- super.onDestroy()
- val app = app()
- app.telegramHelper.incomingMessagesListener = null
- app.userLocationService = null
-
- stopForeground(java.lang.Boolean.TRUE)
- }
-
- override fun onTaskRemoved(rootIntent: Intent) {
- val app = app()
- if (app.userLocationService != null) {
- // Do not stop service after UI task was dismissed
- //this@MyLocationService.stopSelf()
- }
- }
-
- class ShowMessagesTask(private val app: TelegramApplication, private val chatTitle: String) : AsyncTask() {
-
- override fun doInBackground(vararg messages: TdApi.Message): Void? {
- for (message in messages) {
- app.showLocationHelper.showLocationOnMap(chatTitle, message)
- }
- return null
- }
- }
-}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java
index 78211827ef..9f472eaa1f 100644
--- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java
+++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java
@@ -819,7 +819,10 @@ public class OsmandAidlApi {
boolean updateMapLayer(AMapLayer layer) {
if (layer != null && layers.containsKey(layer.getId())) {
- layers.put(layer.getId(), layer);
+ AMapLayer existingLayer = layers.get(layer.getId());
+ for (AMapPoint point : layer.getPoints()) {
+ existingLayer.putPoint(point);
+ }
refreshMap();
return true;
} else {