Telegram - cleanup code
This commit is contained in:
parent
824d608c86
commit
911126e3f9
20 changed files with 2611 additions and 2711 deletions
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
169
OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt
Normal file
169
OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
|
|
@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue