Merge pull request #2891 from nextcloud/refactoring/noid/locationRemoveConductor

Replace Controllers with Activities for location+geocoding
This commit is contained in:
Marcel Hibbe 2023-03-30 10:23:54 +02:00 committed by GitHub
commit 9e68be74d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 382 additions and 219 deletions

View File

@ -194,6 +194,14 @@
android:name=".messagesearch.MessageSearchActivity"
android:theme="@style/AppTheme" />
<activity
android:name=".location.LocationPickerActivity"
android:theme="@style/AppTheme" />
<activity
android:name=".location.GeocodingActivity"
android:theme="@style/AppTheme" />
<receiver android:name=".receivers.PackageReplacedReceiver"
android:exported="false">
<intent-filter>

View File

@ -134,6 +134,7 @@ import com.nextcloud.talk.extensions.loadAvatarOrImagePreview
import com.nextcloud.talk.jobs.DownloadFileToCacheWorker
import com.nextcloud.talk.jobs.ShareOperationWorker
import com.nextcloud.talk.jobs.UploadAndShareFilesWorker
import com.nextcloud.talk.location.LocationPickerActivity
import com.nextcloud.talk.messagesearch.MessageSearchActivity
import com.nextcloud.talk.models.domain.ReactionAddedModel
import com.nextcloud.talk.models.domain.ReactionDeletedModel
@ -1767,13 +1768,9 @@ class ChatController(args: Bundle) :
fun showShareLocationScreen() {
Log.d(TAG, "showShareLocationScreen")
val bundle = Bundle()
bundle.putString(KEY_ROOM_TOKEN, roomToken)
router.pushController(
RouterTransaction.with(LocationPickerController(bundle))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
val intent = Intent(activity, LocationPickerActivity::class.java)
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
activity!!.startActivity(intent)
}
private fun showConversationInfoScreen() {

View File

@ -18,32 +18,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.controllers
package com.nextcloud.talk.location
import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.text.InputType
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.AdapterView
import android.widget.Toast
import androidx.appcompat.widget.SearchView
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.MenuItemCompat
import androidx.preference.PreferenceManager
import autodagger.AutoInjector
import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.adapters.GeocodingAdapter
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.controllers.base.BaseController
import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.databinding.ControllerGeocodingBinding
import com.nextcloud.talk.databinding.ActivityGeocodingBinding
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import fr.dudie.nominatim.client.TalkJsonNominatimClient
import fr.dudie.nominatim.model.Address
@ -57,13 +58,11 @@ import org.osmdroid.config.Configuration
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class GeocodingController(args: Bundle) :
BaseController(
R.layout.controller_geocoding,
args
),
class GeocodingActivity :
BaseActivity(),
SearchView.OnQueryTextListener {
private val binding: ControllerGeocodingBinding? by viewBinding(ControllerGeocodingBinding::bind)
private lateinit var binding: ActivityGeocodingBinding
@Inject
lateinit var ncApi: NcApi
@ -71,7 +70,7 @@ class GeocodingController(args: Bundle) :
@Inject
lateinit var okHttpClient: OkHttpClient
var roomToken: String?
lateinit var roomToken: String
var nominatimClient: TalkJsonNominatimClient? = null
var searchItem: MenuItem? = null
@ -81,52 +80,89 @@ class GeocodingController(args: Bundle) :
lateinit var adapter: GeocodingAdapter
private var geocodingResults: List<Address> = ArrayList()
constructor(args: Bundle, listener: LocationPickerController) : this(args) {
targetController = listener
}
init {
setHasOptionsMenu(true)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
binding = ActivityGeocodingBinding.inflate(layoutInflater)
setupActionBar()
setupSystemColors()
setContentView(binding.root)
Configuration.getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context))
query = args.getString(BundleKeys.KEY_GEOCODING_QUERY)
roomToken = args.getString(BundleKeys.KEY_ROOM_TOKEN)
roomToken = intent.getStringExtra(BundleKeys.KEY_ROOM_TOKEN)!!
query = intent.getStringExtra(BundleKeys.KEY_GEOCODING_QUERY)
}
private fun initAdapter(addresses: List<Address>) {
adapter = GeocodingAdapter(binding?.geocodingResults?.context!!, addresses)
binding?.geocodingResults?.adapter = adapter
}
override fun onAttach(view: View) {
super.onAttach(view)
override fun onStart() {
super.onStart()
initAdapter(geocodingResults)
initGeocoder()
}
override fun onResume() {
super.onResume()
if (!query.isNullOrEmpty()) {
searchLocation()
} else {
Log.e(TAG, "search string that was passed to GeocodingController was null or empty")
}
binding?.geocodingResults?.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
binding.geocodingResults.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
val address: Address = adapter.getItem(position) as Address
val listener: GeocodingResultListener? = targetController as GeocodingResultListener?
listener?.receiveChosenGeocodingResult(address.latitude, address.longitude, address.displayName)
router.popCurrentController()
val geocodingResult = GeocodingResult(address.latitude, address.longitude, address.displayName)
val intent = Intent(this, LocationPickerActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken)
intent.putExtra(BundleKeys.KEY_GEOCODING_RESULT, geocodingResult)
startActivity(intent)
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_geocoding, menu)
private fun setupActionBar() {
setSupportActionBar(binding.geocodingToolbar)
binding.geocodingToolbar.setNavigationOnClickListener {
onBackPressed()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent)))
supportActionBar?.title = ""
}
private fun setupSystemColors() {
DisplayUtils.applyColorToStatusBar(
this,
ResourcesCompat.getColor(
resources,
R.color.appbar,
null
)
)
DisplayUtils.applyColorToNavigationBar(
this.window,
ResourcesCompat.getColor(resources, R.color.bg_default, null)
)
}
private fun initAdapter(addresses: List<Address>) {
adapter = GeocodingAdapter(binding.geocodingResults.context!!, addresses)
binding.geocodingResults.adapter = adapter
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.menu_geocoding, menu)
searchItem = menu.findItem(R.id.geocoding_action_search)
initSearchView()
searchItem?.expandActionView()
searchView?.setQuery(query, false)
searchView?.clearFocus()
return true
}
override fun onQueryTextSubmit(query: String?): Boolean {
@ -141,38 +177,39 @@ class GeocodingController(args: Bundle) :
}
private fun initSearchView() {
if (activity != null) {
val searchManager = activity!!.getSystemService(Context.SEARCH_SERVICE) as SearchManager
if (searchItem != null) {
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
searchView?.maxWidth = Int.MAX_VALUE
searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) {
imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
}
searchView?.imeOptions = imeOptions
searchView?.queryHint = resources!!.getString(R.string.nc_search)
searchView?.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName))
searchView?.setOnQueryTextListener(this)
searchItem?.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(menuItem: MenuItem): Boolean {
return true
}
override fun onMenuItemActionCollapse(menuItem: MenuItem): Boolean {
router.popCurrentController()
return true
}
})
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
if (searchItem != null) {
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
searchView?.maxWidth = Int.MAX_VALUE
searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) {
imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
}
searchView?.imeOptions = imeOptions
searchView?.queryHint = resources!!.getString(R.string.nc_search)
searchView?.setSearchableInfo(searchManager.getSearchableInfo(componentName))
searchView?.setOnQueryTextListener(this)
searchItem?.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(menuItem: MenuItem): Boolean {
return true
}
override fun onMenuItemActionCollapse(menuItem: MenuItem): Boolean {
val intent = Intent(context, LocationPickerActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtra(BundleKeys.KEY_ROOM_TOKEN, roomToken)
startActivity(intent)
return true
}
})
}
}
private fun initGeocoder() {
val baseUrl = context!!.getString(R.string.osm_geocoder_url)
val email = context!!.getString(R.string.osm_geocoder_contact)
val baseUrl = getString(R.string.osm_geocoder_url)
val email = context.getString(R.string.osm_geocoder_contact)
nominatimClient = TalkJsonNominatimClient(baseUrl, okHttpClient, email)
}
@ -206,11 +243,7 @@ class GeocodingController(args: Bundle) :
}
}
interface GeocodingResultListener {
fun receiveChosenGeocodingResult(lat: Double, lon: Double, name: String)
}
companion object {
private const val TAG = "GeocodingController"
private val TAG = GeocodingActivity::class.java.simpleName
}
}

View File

@ -0,0 +1,31 @@
/*
* Nextcloud Talk application
*
* @author Marcel Hibbe
* Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.location
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class GeocodingResult(
val lat: Double,
val lon: Double,
var displayName: String
) : Parcelable

View File

@ -18,11 +18,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.controllers
package com.nextcloud.talk.location
import android.Manifest
import android.app.Activity
import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.ColorDrawable
import android.location.Location
@ -33,7 +35,6 @@ import android.os.Bundle
import android.text.InputType
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.EditorInfo
@ -44,19 +45,17 @@ import androidx.core.content.res.ResourcesCompat
import androidx.core.view.MenuItemCompat
import androidx.preference.PreferenceManager
import autodagger.AutoInjector
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.controllers.base.BaseController
import com.nextcloud.talk.controllers.util.viewBinding
import com.nextcloud.talk.databinding.ControllerLocationBinding
import com.nextcloud.talk.databinding.ActivityLocationBinding
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_GEOCODING_RESULT
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import fr.dudie.nominatim.client.TalkJsonNominatimClient
import fr.dudie.nominatim.model.Address
@ -82,15 +81,12 @@ import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class LocationPickerController(args: Bundle) :
BaseController(
R.layout.controller_location,
args
),
class LocationPickerActivity :
BaseActivity(),
SearchView.OnQueryTextListener,
LocationListener,
GeocodingController.GeocodingResultListener {
private val binding: ControllerLocationBinding? by viewBinding(ControllerLocationBinding::bind)
LocationListener {
private lateinit var binding: ActivityLocationBinding
@Inject
lateinit var ncApi: NcApi
@ -103,38 +99,121 @@ class LocationPickerController(args: Bundle) :
var nominatimClient: TalkJsonNominatimClient? = null
var roomToken: String?
lateinit var roomToken: String
var geocodingResult: GeocodingResult? = null
var myLocation: GeoPoint = GeoPoint(COORDINATE_ZERO, COORDINATE_ZERO)
private var locationManager: LocationManager? = null
private lateinit var locationOverlay: MyLocationNewOverlay
var moveToCurrentLocationWasClicked: Boolean = true
var moveToCurrentLocation: Boolean = true
var readyToShareLocation: Boolean = false
private var mapCenterLat: Double = 0.0
private var mapCenterLon: Double = 0.0
var searchItem: MenuItem? = null
var searchView: SearchView? = null
var receivedChosenGeocodingResult: Boolean = false
var geocodedLat: Double = 0.0
var geocodedLon: Double = 0.0
var geocodedName: String = ""
init {
setHasOptionsMenu(true)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context))
roomToken = args.getString(KEY_ROOM_TOKEN)
roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!!
geocodingResult = intent.getParcelableExtra(KEY_GEOCODING_RESULT)
if (savedInstanceState != null) {
moveToCurrentLocation = savedInstanceState.getBoolean("moveToCurrentLocation") == true
mapCenterLat = savedInstanceState.getDouble("mapCenterLat")
mapCenterLon = savedInstanceState.getDouble("mapCenterLon")
geocodingResult = savedInstanceState.getParcelable("geocodingResult")
}
binding = ActivityLocationBinding.inflate(layoutInflater)
setupActionBar()
setupSystemColors()
setContentView(binding.root)
getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(context))
}
override fun onAttach(view: View) {
super.onAttach(view)
override fun onStart() {
super.onStart()
initMap()
}
override fun onResume() {
super.onResume()
if (geocodingResult != null) {
moveToCurrentLocation = false
}
setLocationDescription(false, geocodingResult != null)
binding.shareLocation.isClickable = false
binding.shareLocation.setOnClickListener {
if (readyToShareLocation) {
shareLocation(
binding.map.mapCenter?.latitude,
binding.map.mapCenter?.longitude,
binding.placeName.text.toString()
)
} else {
Log.w(TAG, "readyToShareLocation was false while user tried to share location.")
}
}
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
bundle.putBoolean("moveToCurrentLocation", moveToCurrentLocation)
bundle.putDouble("mapCenterLat", binding.map.mapCenter.latitude)
bundle.putDouble("mapCenterLon", binding.map.mapCenter.longitude)
bundle.putParcelable("geocodingResult", geocodingResult)
}
private fun setupActionBar() {
setSupportActionBar(binding.locationPickerToolbar)
binding.locationPickerToolbar.setNavigationOnClickListener {
onBackPressed()
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent)))
supportActionBar?.title = context.getString(R.string.nc_share_location)
}
private fun setupSystemColors() {
DisplayUtils.applyColorToStatusBar(
this,
ResourcesCompat.getColor(
resources,
R.color.appbar,
null
)
)
DisplayUtils.applyColorToNavigationBar(
this.window,
ResourcesCompat.getColor(resources, R.color.bg_default, null)
)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.menu_locationpicker, menu)
return true
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
super.onPrepareOptionsMenu(menu)
searchItem = menu.findItem(R.id.location_action_search)
initSearchView()
return true
}
@Suppress("Detekt.TooGenericExceptionCaught")
override fun onDetach(view: View) {
super.onDetach(view)
override fun onStop() {
super.onStop()
try {
locationManager!!.removeUpdates(this)
@ -145,68 +224,29 @@ class LocationPickerController(args: Bundle) :
locationOverlay.disableMyLocation()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_locationpicker, menu)
searchItem = menu.findItem(R.id.location_action_search)
initSearchView()
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
actionBar?.setIcon(ColorDrawable(resources!!.getColor(android.R.color.transparent)))
actionBar?.title = context!!.getString(R.string.nc_share_location)
}
override val title: String
get() =
resources!!.getString(R.string.nc_share_location)
override fun onViewBound(view: View) {
setLocationDescription(false, receivedChosenGeocodingResult)
binding?.shareLocation?.isClickable = false
binding?.shareLocation?.setOnClickListener {
if (readyToShareLocation) {
shareLocation(
binding?.map?.mapCenter?.latitude,
binding?.map?.mapCenter?.longitude,
binding?.placeName?.text.toString()
)
} else {
Log.w(TAG, "readyToShareLocation was false while user tried to share location.")
}
}
}
private fun initSearchView() {
if (activity != null) {
val searchManager = activity!!.getSystemService(Context.SEARCH_SERVICE) as SearchManager
if (searchItem != null) {
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
searchView?.maxWidth = Int.MAX_VALUE
searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) {
imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
}
searchView?.imeOptions = imeOptions
searchView?.queryHint = resources!!.getString(R.string.nc_search)
searchView?.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName))
searchView?.setOnQueryTextListener(this)
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
if (searchItem != null) {
searchView = MenuItemCompat.getActionView(searchItem) as SearchView
searchView?.maxWidth = Int.MAX_VALUE
searchView?.inputType = InputType.TYPE_TEXT_VARIATION_FILTER
var imeOptions = EditorInfo.IME_ACTION_DONE or EditorInfo.IME_FLAG_NO_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appPreferences!!.isKeyboardIncognito) {
imeOptions = imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
}
searchView?.imeOptions = imeOptions
searchView?.queryHint = resources!!.getString(R.string.nc_search)
searchView?.setSearchableInfo(searchManager.getSearchableInfo(componentName))
searchView?.setOnQueryTextListener(this)
}
}
override fun onQueryTextSubmit(query: String?): Boolean {
if (!query.isNullOrEmpty()) {
val bundle = Bundle()
bundle.putString(BundleKeys.KEY_GEOCODING_QUERY, query)
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken)
router.pushController(
RouterTransaction.with(GeocodingController(bundle, this))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
val intent = Intent(this, GeocodingActivity::class.java)
intent.putExtra(BundleKeys.KEY_GEOCODING_QUERY, query)
intent.putExtra(KEY_ROOM_TOKEN, roomToken)
startActivity(intent)
}
return true
}
@ -217,10 +257,10 @@ class LocationPickerController(args: Bundle) :
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.ComplexMethod")
private fun initMap() {
binding?.map?.setTileSource(TileSourceFactory.MAPNIK)
binding?.map?.onResume()
binding.map.setTileSource(TileSourceFactory.MAPNIK)
binding.map.onResume()
locationManager = activity!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (!isLocationPermissionsGranted()) {
requestLocationPermissions()
@ -229,12 +269,12 @@ class LocationPickerController(args: Bundle) :
}
val copyrightOverlay = CopyrightOverlay(context)
binding?.map?.overlays?.add(copyrightOverlay)
binding.map.overlays.add(copyrightOverlay)
binding?.map?.setMultiTouchControls(true)
binding?.map?.isTilesScaledToDpi = true
binding.map.setMultiTouchControls(true)
binding.map.isTilesScaledToDpi = true
locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(context), binding?.map)
locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(context), binding.map)
locationOverlay.enableMyLocation()
locationOverlay.setPersonHotspot(PERSON_HOT_SPOT_X, PERSON_HOT_SPOT_Y)
locationOverlay.setPersonIcon(
@ -242,24 +282,28 @@ class LocationPickerController(args: Bundle) :
ResourcesCompat.getDrawable(resources!!, R.drawable.current_location_circle, null)
)
)
binding?.map?.overlays?.add(locationOverlay)
binding.map.overlays.add(locationOverlay)
val mapController = binding?.map?.controller
val mapController = binding.map.controller
if (receivedChosenGeocodingResult) {
mapController?.setZoom(ZOOM_LEVEL_RECEIVED_RESULT)
if (geocodingResult != null) {
mapController.setZoom(ZOOM_LEVEL_RECEIVED_RESULT)
} else {
mapController?.setZoom(ZOOM_LEVEL_DEFAULT)
mapController.setZoom(ZOOM_LEVEL_DEFAULT)
}
val zoomToCurrentPositionOnFirstFix = !receivedChosenGeocodingResult
if (mapCenterLat != 0.0 && mapCenterLon != 0.0) {
mapController.setCenter(GeoPoint(mapCenterLat, mapCenterLon))
}
val zoomToCurrentPositionOnFirstFix = geocodingResult == null && moveToCurrentLocation
locationOverlay.runOnFirstFix {
if (locationOverlay.myLocation != null) {
myLocation = locationOverlay.myLocation
if (zoomToCurrentPositionOnFirstFix) {
activity!!.runOnUiThread {
mapController?.setZoom(ZOOM_LEVEL_DEFAULT)
mapController?.setCenter(myLocation)
runOnUiThread {
mapController.setZoom(ZOOM_LEVEL_DEFAULT)
mapController.setCenter(myLocation)
}
}
} else {
@ -269,20 +313,22 @@ class LocationPickerController(args: Bundle) :
}
}
if (receivedChosenGeocodingResult && geocodedLat != COORDINATE_ZERO && geocodedLon != COORDINATE_ZERO) {
mapController?.setCenter(GeoPoint(geocodedLat, geocodedLon))
}
binding?.centerMapButton?.setOnClickListener {
if (myLocation.latitude == COORDINATE_ZERO && myLocation.longitude == COORDINATE_ZERO) {
Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show()
} else {
mapController?.animateTo(myLocation)
moveToCurrentLocationWasClicked = true
geocodingResult?.let {
if (it.lat != COORDINATE_ZERO && it.lon != COORDINATE_ZERO) {
mapController.setCenter(GeoPoint(it.lat, it.lon))
}
}
binding?.map?.addMapListener(
binding.centerMapButton.setOnClickListener {
if (myLocation.latitude == COORDINATE_ZERO && myLocation.longitude == COORDINATE_ZERO) {
Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show()
} else {
mapController.animateTo(myLocation)
moveToCurrentLocation = true
}
}
binding.map.addMapListener(
delayedMapListener()
)
}
@ -293,17 +339,17 @@ class LocationPickerController(args: Bundle) :
override fun onScroll(paramScrollEvent: ScrollEvent): Boolean {
try {
when {
moveToCurrentLocationWasClicked -> {
moveToCurrentLocation -> {
setLocationDescription(isGpsLocation = true, isGeocodedResult = false)
moveToCurrentLocationWasClicked = false
moveToCurrentLocation = false
}
receivedChosenGeocodingResult -> {
binding?.shareLocation?.isClickable = true
geocodingResult != null -> {
binding.shareLocation.isClickable = true
setLocationDescription(isGpsLocation = false, isGeocodedResult = true)
receivedChosenGeocodingResult = false
geocodingResult = null
}
else -> {
binding?.shareLocation?.isClickable = true
binding.shareLocation.isClickable = true
setLocationDescription(isGpsLocation = false, isGeocodedResult = false)
}
}
@ -349,35 +395,35 @@ class LocationPickerController(args: Bundle) :
" and there is no alternative like UnifiedNlp installed. Furthermore no GPS is " +
"supported."
)
Toast.makeText(context, context?.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG)
Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG)
.show()
}
}
} catch (e: SecurityException) {
Log.e(TAG, "Error when requesting location updates. Permissions may be missing.", e)
Toast.makeText(context, context?.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show()
Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Log.e(TAG, "Error when requesting location updates.", e)
Toast.makeText(context, context?.getString(R.string.nc_common_error_sorry), Toast.LENGTH_LONG).show()
Toast.makeText(context, context.getString(R.string.nc_common_error_sorry), Toast.LENGTH_LONG).show()
}
}
private fun setLocationDescription(isGpsLocation: Boolean, isGeocodedResult: Boolean) {
when {
isGpsLocation -> {
binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_current_location)
binding?.placeName?.visibility = View.GONE
binding?.placeName?.text = ""
binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_current_location)
binding.placeName.visibility = View.GONE
binding.placeName.text = ""
}
isGeocodedResult -> {
binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_this_location)
binding?.placeName?.visibility = View.VISIBLE
binding?.placeName?.text = geocodedName
binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location)
binding.placeName.visibility = View.VISIBLE
binding.placeName.text = geocodingResult?.displayName
}
else -> {
binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_this_location)
binding?.placeName?.visibility = View.GONE
binding?.placeName?.text = ""
binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location)
binding.placeName.visibility = View.GONE
binding.placeName.text = ""
}
}
}
@ -395,11 +441,14 @@ class LocationPickerController(args: Bundle) :
}
private fun executeShareLocation(selectedLat: Double?, selectedLon: Double?, locationName: String?) {
binding.roundedImageView.visibility = View.GONE
binding.sendingLocationProgressbar.visibility = View.VISIBLE
val objectId = "geo:$selectedLat,$selectedLon"
var locationNameToShare = locationName
if (locationNameToShare.isNullOrBlank()) {
locationNameToShare = resources?.getString(R.string.nc_shared_location)
locationNameToShare = resources.getString(R.string.nc_shared_location)
}
val metaData: String =
@ -410,8 +459,8 @@ class LocationPickerController(args: Bundle) :
val apiVersion = ApiUtils.getChatApiVersion(currentUser, intArrayOf(1))
ncApi.sendLocation(
ApiUtils.getCredentials(currentUser?.username, currentUser?.token),
ApiUtils.getUrlToSendLocation(apiVersion, currentUser?.baseUrl, roomToken),
ApiUtils.getCredentials(currentUser.username, currentUser.token),
ApiUtils.getUrlToSendLocation(apiVersion, currentUser.baseUrl, roomToken),
"geo-location",
objectId,
metaData
@ -424,13 +473,13 @@ class LocationPickerController(args: Bundle) :
}
override fun onNext(t: GenericOverall) {
router.popCurrentController()
finish()
}
override fun onError(e: Throwable) {
Log.e(TAG, "error when trying to share location", e)
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
router.popCurrentController()
finish()
}
override fun onComplete() {
@ -472,6 +521,8 @@ class LocationPickerController(args: Bundle) :
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
fun areAllGranted(grantResults: IntArray): Boolean {
grantResults.forEach {
if (it == PackageManager.PERMISSION_DENIED) return false
@ -487,13 +538,6 @@ class LocationPickerController(args: Bundle) :
}
}
override fun receiveChosenGeocodingResult(lat: Double, lon: Double, name: String) {
receivedChosenGeocodingResult = true
geocodedLat = lat
geocodedLon = lon
geocodedName = name
}
private fun initGeocoder() {
val baseUrl = context!!.getString(R.string.osm_geocoder_url)
val email = context!!.getString(R.string.osm_geocoder_contact)
@ -542,8 +586,13 @@ class LocationPickerController(args: Bundle) :
// empty
}
override fun onBackPressed() {
setResult(Activity.RESULT_CANCELED)
finish()
}
companion object {
private const val TAG = "LocPicker"
private val TAG = LocationPickerActivity::class.java.simpleName
private const val REQUEST_PERMISSIONS_REQUEST_CODE = 1
private const val PERSON_HOT_SPOT_X: Float = 20.0F
private const val PERSON_HOT_SPOT_Y: Float = 20.0F

View File

@ -85,4 +85,5 @@ object BundleKeys {
const val KEY_NOTIFICATION_RESTRICT_DELETION = "KEY_NOTIFICATION_RESTRICT_DELETION"
const val KEY_DISMISS_RECORDING_URL = "KEY_DISMISS_RECORDING_URL"
const val KEY_SHARE_RECORDING_TO_CHAT_URL = "KEY_SHARE_RECORDING_TO_CHAT_URL"
const val KEY_GEOCODING_RESULT = "KEY_GEOCODING_RESULT"
}

View File

@ -20,11 +20,30 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/geocoding_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/geocoding_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/appbar"
android:theme="?attr/actionBarPopupTheme"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIconTint="@color/fontAppbar"
app:popupTheme="@style/appActionBarPopupMenu"
app:titleTextColor="@color/fontAppbar"
tools:title="@string/nc_app_product_name" />
</com.google.android.material.appbar.AppBarLayout>
<ListView
android:id="@+id/geocoding_results"
android:layout_width="match_parent"

View File

@ -29,6 +29,23 @@
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/location_picker_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/location_picker_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/appbar"
android:theme="?attr/actionBarPopupTheme"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIconTint="@color/fontAppbar"
app:popupTheme="@style/appActionBarPopupMenu"
app:titleTextColor="@color/fontAppbar"
tools:title="@string/nc_app_product_name" />
</com.google.android.material.appbar.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
@ -92,6 +109,14 @@
android:contentDescription="@null"
android:src="@drawable/ic_circular_location" />
<ProgressBar
android:id="@+id/sending_location_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone">
</ProgressBar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"