Telegram - cleanup code

This commit is contained in:
crimean 2018-06-11 19:57:33 +03:00
parent 824d608c86
commit 911126e3f9
20 changed files with 2611 additions and 2711 deletions

View file

@ -33,25 +33,14 @@
</activity> </activity>
<service <service
android:name=".services.MyLocationService" android:name=".TelegramService"
android:label="@string/process_location_service" android:label="@string/process_service"
android:stopWithTask="false"> android:stopWithTask="false">
<intent-filter> <intent-filter>
<action android:name="net.osmand.telegram.services.MyLocationService" /> <action android:name="net.osmand.telegram.TelegramService" />
</intent-filter> </intent-filter>
</service> </service>
<service
android:name=".services.UserLocationService"
android:label="@string/process_location_service"
android:stopWithTask="false">
<intent-filter>
<action android:name="net.osmand.telegram.services.UserLocationService" />
</intent-filter>
</service>
<receiver android:name=".notifications.NotificationDismissReceiver" />
</application> </application>
</manifest> </manifest>

View file

@ -27,7 +27,7 @@
<string name="shared_string_pause">Pause</string> <string name="shared_string_pause">Pause</string>
<string name="shared_string_start">Start</string> <string name="shared_string_start">Start</string>
<string name="shared_string_stop">Stop</string> <string name="shared_string_stop">Stop</string>
<string name="process_location_service">OsmAnd Telegram location service</string> <string name="process_service">OsmAnd Telegram service</string>
<string name="osmand_logo">OsmAnd logo</string> <string name="osmand_logo">OsmAnd logo</string>
<string name="install_osmand_dialog_message">You need to install free or paid version of OsmAnd first</string> <string name="install_osmand_dialog_message">You need to install free or paid version of OsmAnd first</string>
<string name="install_osmand">Install OsmAnd</string> <string name="install_osmand">Install OsmAnd</string>

View file

@ -5,61 +5,62 @@ import org.apache.commons.logging.Log;
public class PlatformUtil { public class PlatformUtil {
public static String TAG = "net.osmand"; public static String TAG = "net.osmand";
private static class OsmandLogImplementation implements Log { private static class OsmandLogImplementation implements Log {
private final String fullName; private final String fullName;
private final String name; private final String name;
public OsmandLogImplementation(String name){ public OsmandLogImplementation(String name) {
this.fullName = name; this.fullName = name;
this.name = fullName.substring(fullName.lastIndexOf('.') + 1); this.name = fullName.substring(fullName.lastIndexOf('.') + 1);
} }
@Override @Override
public void trace(Object message) { public void trace(Object message) {
if(isTraceEnabled()){ if (isTraceEnabled()) {
android.util.Log.d(TAG, name + " " + message); android.util.Log.d(TAG, name + " " + message);
} }
} }
@Override @Override
public void trace(Object message, Throwable t) { public void trace(Object message, Throwable t) {
if(isTraceEnabled()){ if (isTraceEnabled()) {
android.util.Log.d(TAG, name + " " + message, t); android.util.Log.d(TAG, name + " " + message, t);
} }
} }
@Override @Override
public void debug(Object message) { public void debug(Object message) {
if(isDebugEnabled()){ if (isDebugEnabled()) {
android.util.Log.d(TAG, name + " " + message); android.util.Log.d(TAG, name + " " + message);
} }
} }
@Override @Override
public void debug(Object message, Throwable t) { public void debug(Object message, Throwable t) {
if(isDebugEnabled()){ if (isDebugEnabled()) {
android.util.Log.d(TAG, name + " " + message, t); android.util.Log.d(TAG, name + " " + message, t);
} }
} }
@Override @Override
public void error(Object message) { public void error(Object message) {
if(isErrorEnabled()){ if (isErrorEnabled()) {
android.util.Log.e(TAG, name + " " + message); android.util.Log.e(TAG, name + " " + message);
} }
} }
@Override @Override
public void error(Object message, Throwable t) { public void error(Object message, Throwable t) {
if(isErrorEnabled()){ if (isErrorEnabled()) {
android.util.Log.e(TAG, name + " " + message, t); android.util.Log.e(TAG, name + " " + message, t);
} }
} }
@Override @Override
public void fatal(Object message) { public void fatal(Object message) {
if(isFatalEnabled()){ if (isFatalEnabled()) {
android.util.Log.e(TAG, name + " " + message); android.util.Log.e(TAG, name + " " + message);
} }
@ -67,21 +68,21 @@ public class PlatformUtil {
@Override @Override
public void fatal(Object message, Throwable t) { public void fatal(Object message, Throwable t) {
if(isFatalEnabled()){ if (isFatalEnabled()) {
android.util.Log.e(TAG, name + " " + message, t); android.util.Log.e(TAG, name + " " + message, t);
} }
} }
@Override @Override
public void info(Object message) { public void info(Object message) {
if(isInfoEnabled()){ if (isInfoEnabled()) {
android.util.Log.i(TAG, name + " " + message); android.util.Log.i(TAG, name + " " + message);
} }
} }
@Override @Override
public void info(Object message, Throwable t) { public void info(Object message, Throwable t) {
if(isInfoEnabled()){ if (isInfoEnabled()) {
android.util.Log.i(TAG, name + " " + message, t); android.util.Log.i(TAG, name + " " + message, t);
} }
} }
@ -92,7 +93,6 @@ public class PlatformUtil {
} }
@Override @Override
public boolean isDebugEnabled() { public boolean isDebugEnabled() {
// For debug purposes always true // For debug purposes always true
@ -122,24 +122,24 @@ public class PlatformUtil {
@Override @Override
public void warn(Object message) { public void warn(Object message) {
if(isWarnEnabled()){ if (isWarnEnabled()) {
android.util.Log.w(TAG, name + " " + message); android.util.Log.w(TAG, name + " " + message);
} }
} }
@Override @Override
public void warn(Object message, Throwable t) { public void warn(Object message, Throwable t) {
if(isWarnEnabled()){ if (isWarnEnabled()) {
android.util.Log.w(TAG, name + " " + message, t); android.util.Log.w(TAG, name + " " + message, t);
} }
} }
} }
public static Log getLog(String name){ public static Log getLog(String name) {
return new OsmandLogImplementation(name); return new OsmandLogImplementation(name);
} }
public static Log getLog(Class<?> cl){ public static Log getLog(Class<?> cl) {
return getLog(cl.getName()); return getLog(cl.getName());
} }

View file

@ -108,6 +108,12 @@ class MainActivity : AppCompatActivity(), TelegramListener {
settings.save() settings.save()
} }
override fun onDestroy() {
super.onDestroy()
app.cleanupResources()
}
override fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState, override fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState,
newTelegramAuthorizationState: TelegramAuthorizationState) { newTelegramAuthorizationState: TelegramAuthorizationState) {
runOnUi { runOnUi {

View file

@ -12,8 +12,6 @@ import net.osmand.telegram.helpers.ShareLocationHelper
import net.osmand.telegram.helpers.ShowLocationHelper import net.osmand.telegram.helpers.ShowLocationHelper
import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.notifications.NotificationHelper import net.osmand.telegram.notifications.NotificationHelper
import net.osmand.telegram.services.MyLocationService
import net.osmand.telegram.services.UserLocationService
import net.osmand.telegram.utils.AndroidUtils import net.osmand.telegram.utils.AndroidUtils
class TelegramApplication : Application() { class TelegramApplication : Application() {
@ -25,8 +23,7 @@ class TelegramApplication : Application() {
lateinit var notificationHelper: NotificationHelper private set lateinit var notificationHelper: NotificationHelper private set
lateinit var osmandHelper: OsmandAidlHelper private set lateinit var osmandHelper: OsmandAidlHelper private set
var myLocationService: MyLocationService? = null var telegramService: TelegramService? = null
var userLocationService: UserLocationService? = null
private val uiHandler = Handler() private val uiHandler = Handler()
@ -51,9 +48,7 @@ class TelegramApplication : Application() {
} }
} }
override fun onTerminate() { fun cleanupResources() {
super.onTerminate()
// TODO close telegram api in appropriate place
osmandHelper.cleanupResources() osmandHelper.cleanupResources()
telegramHelper.close() telegramHelper.close()
} }
@ -89,44 +84,38 @@ class TelegramApplication : Application() {
return internetConnectionAvailable return internetConnectionAvailable
} }
fun startMyLocationService(restart: Boolean = false) { private fun startTelegramService(intent: Int) {
val serviceIntent = Intent(this, MyLocationService::class.java) var i = intent
val serviceIntent = Intent(this, TelegramService::class.java)
val myLocationService = myLocationService val telegramService = telegramService
if (myLocationService != null && restart) { if (telegramService != null) {
myLocationService.stopSelf() i = intent or telegramService.usedBy
telegramService.stopSelf()
} }
if (myLocationService == null || restart) {
serviceIntent.putExtra(TelegramService.USAGE_INTENT, i)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent) startForegroundService(serviceIntent)
} else { } else {
startService(serviceIntent) startService(serviceIntent)
} }
} }
fun startMyLocationService() {
startTelegramService(TelegramService.USED_BY_MY_LOCATION)
} }
fun stopMyLocationService() { fun stopMyLocationService() {
myLocationService?.stopIfNeeded(this) telegramService?.stopIfNeeded(this, TelegramService.USED_BY_MY_LOCATION)
} }
fun startUserLocationService(restart: Boolean = false) { fun startUserLocationService() {
val serviceIntent = Intent(this, UserLocationService::class.java) startTelegramService(TelegramService.USED_BY_USERS_LOCATIONS)
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 stopUserLocationService() { fun stopUserLocationService() {
userLocationService?.stopIfNeeded(this) telegramService?.stopIfNeeded(this, TelegramService.USED_BY_USERS_LOCATIONS)
} }
fun runInUIThread(action: (() -> Unit)) { fun runInUIThread(action: (() -> Unit)) {

View file

@ -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<TdApi.Message, Void, Void?>() {
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
}
}
}

View file

@ -87,7 +87,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
private fun refreshNotification() { private fun refreshNotification() {
app.runInUIThread { app.runInUIThread {
app.notificationHelper.refreshNotification(NotificationType.SHARE_LOCATION) app.notificationHelper.refreshNotification(NotificationType.LOCATION)
} }
} }
} }

View file

@ -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))
}
}

View file

@ -5,18 +5,15 @@ import android.app.Notification
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.support.v4.app.NotificationManagerCompat
import net.osmand.telegram.R import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.notifications.TelegramNotification.NotificationType import net.osmand.telegram.notifications.TelegramNotification.NotificationType
import java.util.*
class NotificationHelper(private val app: TelegramApplication) { class NotificationHelper(private val app: TelegramApplication) {
val shareLocationNotification = ShareLocationNotification(app) val locationNotification = LocationNotification(app)
val showLocationNotification = ShowLocationNotification(app)
private val all = listOf(shareLocationNotification, showLocationNotification) private val all = listOf(locationNotification)
fun buildNotification(telegramNotification: TelegramNotification): Notification { fun buildNotification(telegramNotification: TelegramNotification): Notification {
return telegramNotification.buildNotification(false).build() return telegramNotification.buildNotification(false).build()

View file

@ -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))
}
}

View file

@ -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))
}
}

View file

@ -13,11 +13,9 @@ abstract class TelegramNotification(protected var app: TelegramApplication, val
companion object { companion object {
const val SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 6 const val LOCATION_NOTIFICATION_SERVICE_ID = 6
const val SHOW_LOCATION_NOTIFICATION_SERVICE_ID = 7
const val WEAR_SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 1006 const val WEAR_LOCATION_NOTIFICATION_SERVICE_ID = 1006
const val WEAR_SHOW_LOCATION_NOTIFICATION_SERVICE_ID = 1006
} }
protected var ongoing = true protected var ongoing = true
@ -37,8 +35,7 @@ abstract class TelegramNotification(protected var app: TelegramApplication, val
abstract val isEnabled: Boolean abstract val isEnabled: Boolean
enum class NotificationType { enum class NotificationType {
SHARE_LOCATION, LOCATION,
SHOW_LOCATION
} }
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")

View file

@ -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
}
}
}

View file

@ -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<TdApi.Message, Void, Void?>() {
override fun doInBackground(vararg messages: TdApi.Message): Void? {
for (message in messages) {
app.showLocationHelper.showLocationOnMap(chatTitle, message)
}
return null
}
}
}

View file

@ -819,7 +819,10 @@ public class OsmandAidlApi {
boolean updateMapLayer(AMapLayer layer) { boolean updateMapLayer(AMapLayer layer) {
if (layer != null && layers.containsKey(layer.getId())) { 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(); refreshMap();
return true; return true;
} else { } else {