I am getting a NullPointerException when I try to access an element in the layout from a DialogFragment. I have checked that, if I call getView() inside the same DialogFragment the result is 'null'.
Thank you in advance!
This is the Activity that calls commits the FragmentDialog "NewPOIDialog"
class MainActivity : AppCompatActivity() {
//Variables for Location service
private var hasGps: Boolean = false
private var hasNetwork: Boolean = false
private var locationGps: Location? = null
private var locationNetwork: Location? = null
private companion object {
private const val TAG = "MainActivity"
}
private lateinit var auth: FirebaseAuth
private lateinit var permissionsRequestor: PermissionsRequestor
private lateinit var mapView: MapView
private lateinit var mapActivity: MapActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
//Get the authorisation from Firebase
auth = Firebase.auth
Log.d("", "HERE SDK version: " + SDKBuildInformation.sdkVersion().versionName)
// Get a MapView instance from layout.
mapView = findViewById(R.id.map_view)
mapView.onCreate(savedInstanceState)
location()
handleAndroidPermissions()
}
fun searchInMap(view: View?) {
NewPOIDialog().show(supportFragmentManager, "test")
}
fun clearRouteButtonClicked(view: View?) {
mapActivity.clearMap()
}
fun clearWaypoints(view: View?) {
mapActivity.clearWaypoints()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true //we provided the menu that needs to be inflated
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.miLogout) {
Log.i(TAG, "Logout")
//Logout the user
auth.signOut()
LoginManager.getInstance().logOut()
val logoutIntent = Intent(this, LoginActivity::class.java)
logoutIntent.flags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK //Clear the backstack
startActivity(logoutIntent)
}
return super.onOptionsItemSelected(item)
}
private fun handleAndroidPermissions() {
permissionsRequestor = PermissionsRequestor(this)
permissionsRequestor.request(object : PermissionsRequestor.ResultListener {
override fun permissionsGranted() {
loadMapScene()
}
override fun permissionsDenied() {
Log.e(TAG, "Permissions denied by user.")
}
})
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
permissionsRequestor.onRequestPermissionsResult(requestCode, grantResults)
}
private fun loadMapScene() {
mapView.mapScene.loadScene(MapScheme.NORMAL_DAY, object : MapScene.LoadSceneCallback {
override fun onLoadScene(p0: MapError?) {
if (p0 == null) {
mapActivity = MapActivity(this#MainActivity, mapView, supportFragmentManager)
mapView.camera.lookAt(
GeoCoordinates(53.57407651646072, -1.525012498490556),
100000.0
)
} else {
Log.d("TAG", "onLoadScene failed: $p0")
}
}
})
}
fun location() {
var locationManager: LocationManager = getSystemService(LOCATION_SERVICE) as LocationManager
hasGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
hasNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
if (hasGps || hasNetwork) {
if (hasGps) {
Log.d(TAG, "hasGPS")
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
//return
handleAndroidPermissions()
}
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
1000,
0f,
object :
LocationListener {
override fun onLocationChanged(p0: Location?) {
if (p0 != null) {
locationNetwork = p0
}
}
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {
}
override fun onProviderEnabled(p0: String?) {
}
override fun onProviderDisabled(p0: String?) {
}
})
val localGpsLocation =
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
if (localGpsLocation != null) {
locationGps = localGpsLocation
}
}
///////////////////////////////////////////////////////////////////////////
if (hasNetwork) {
Log.d(TAG, "hasGPS")
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
1000,
0f,
object :
LocationListener {
override fun onLocationChanged(p0: Location?) {
if (p0 != null) {
locationNetwork = p0
}
}
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {
}
override fun onProviderEnabled(p0: String?) {
}
override fun onProviderDisabled(p0: String?) {
}
})
val localGpsLocation =
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
if (localGpsLocation != null) {
locationGps = localGpsLocation
}
val localNetworkLocation =
locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
if (localNetworkLocation != null) {
locationNetwork = localNetworkLocation
}
if (locationGps != null && locationNetwork != null) {
if (locationGps!!.accuracy!! > locationNetwork!!.accuracy!!) { //The lower number is the accurate location
Log.d(TAG, "Network Latitude : ${locationNetwork!!.latitude}")
Log.d(TAG, "Network Longitude : ${locationNetwork!!.longitude}")
latitude_txt.text = "Latitude : ${locationNetwork!!.latitude} - Network"
longitude_txt.text = "Longitude : ${locationNetwork!!.longitude} - Network"
latitude_txt.text = "Latitude : ${locationGps!!.latitude} - Gps"
longitude_txt.text = "Longitude : ${locationGps!!.longitude} - Gps"
} else {
Log.d(TAG, "Gps Latitude : ${locationGps!!.latitude}")
Log.d(TAG, "Gps Longitude : ${locationGps!!.longitude}")
latitude_txt.text = "Latitude : ${locationGps!!.latitude} - Gps"
longitude_txt.text = "Longitude : ${locationGps!!.longitude} - Gps"
}
}
}
// if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) &&
// this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)
// ) {
// locationManager.requestLocationUpdates(
// LocationManager.GPS_PROVIDER,
// LOCATION_UPDATE_INTERVAL_IN_MS,
// 1,
// this
// );
// } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
// locationManager.requestLocationUpdates(
// LocationManager.NETWORK_PROVIDER,
// LOCATION_UPDATE_INTERVAL_IN_MS,
// 1,
// this
// );
// } else {
// Log.d(TAG, "Positioning not possible.");
// // ...
// }
}
}
}
NewPOIDialog
The view was initially called as below, I changed it as I was receiving a StackOverFlowError:
var view = layoutInflater.inflate(R.layout.activity_new_poi_dialog,null)
class NewPOIDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
var view = LayoutInflater.from(context).inflate(R.layout.activity_new_poi_dialog, null)
var dialog = AlertDialog.Builder(requireContext())
.setMessage("TITLE")
.setView(view)
.setPositiveButton("ok") { _, _ -> }
.setNegativeButton("Cancel") { _, _ -> }
.create()
//THIS LINE WORKS FINE
var coordinatesvalue = view.findViewById<TextView>(R.id.coordinates_value)
coordinatesvalue.text =
"${arguments?.getDouble("latitude")}\n, ${arguments?.getDouble("longitude")}"
//THIS CAUSES A NULL POINTER EXCEPTION
coordinates_value.text = "TEST"
return dialog
}
}
The exception I am getting:
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.robin.socialparking, PID: 19187
java.lang.NullPointerException: coordinates_value must not be null
at com.robin.socialparking.dialog.NewPOIDialog.onCreateDialog(NewPOIDialog.kt:54)
at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:380)
at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1412)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
I/Process: Sending signal. PID: 19187 SIG: 9
Related
In my app my geofence does not update my firebase database when I enter the area. I made sure my code for updating the database works so that is not the problem. Also, when I enter the geofence my activity crashes. I’m going to add all my code for getting my location, the geofence and my broadcast.
Maps activity
class PricklyMapsActivity : AppCompatActivity(), OnMapReadyCallback {
lateinit var toggle: ActionBarDrawerToggle
//location
private lateinit var fusedLocatonClient: FusedLocationProviderClient
private lateinit var myLatlng: LatLng
private lateinit var currentLocation: Location
private val permissionId = 5
//Map
private lateinit var map: GoogleMap
private lateinit var binding: ActivityPricklyMapsBinding
//Goefence
private var gadgetQ = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q
private lateinit var geoClient: GeofencingClient
var geofenceList: MutableList<Geofence> = mutableListOf()
//firebase
private lateinit var database: DatabaseReference
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityPricklyMapsBinding.inflate(layoutInflater)
setContentView(binding.root)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
fusedLocatonClient = LocationServices.getFusedLocationProviderClient(this)
//drawer create and in actions
val drawerLayout: DrawerLayout = findViewById(R.id.draweLayout)
val navWiew: NavigationView = findViewById(R.id.nav_view)
toggle = ActionBarDrawerToggle(this#PricklyMapsActivity, drawerLayout, R.string.open, R.string.close)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
navWiew.setNavigationItemSelectedListener {
when (it.itemId){
R.id.Home -> showActivityHome()
R.id.Map -> Toast.makeText(applicationContext, "Alredy at the Map", Toast.LENGTH_SHORT).show()
}
true
}
//drawer create end
//Geofence
geoClient = LocationServices.getGeofencingClient(this)
//add geofences here
val latatude = -26.694340
val longatude = 27.083960
val radius = 10f
geofenceList.add(Geofence.Builder()
.setRequestId("Toets")
.setCircularRegion(latatude,longatude,radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.build())
}
override fun onDestroy() {
super.onDestroy()
removeGeofence()
}
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
getCurrentLocation()
val placeName = arrayOf<String>("Texas")
val lataltude = arrayOf<Double>(-26.694340)
val longatude = arrayOf<Double>(27.083960)
for (i in 0..placeName.size-1){
val x = placeName[i]
val y = lataltude[i]
val z = longatude[i]
addCircle(x, y, z)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(toggle.onOptionsItemSelected(item)){
return true
}
return super.onOptionsItemSelected(item)
}
//go to the home activity
private fun showActivityHome(){
val intent1 = Intent(this#PricklyMapsActivity, MainActivity::class.java)
startActivity(intent1)
}
private fun addCircle(Name: String, latatude: Double, longatude: Double){
val radius = 10.00
val latLng = LatLng(latatude,longatude)
map.addCircle(
CircleOptions()
.radius(radius)
.center(latLng)
.strokeColor(Color.argb(150,173,216,230))
.fillColor(Color.argb(100, 173, 216, 230))
)
}
//Geofence pending intent
private val geofenceIntent: PendingIntent by lazy {
val intent = Intent(this, GeofenceBrodcastReceiver::class.java)
intent.action = ACTION_GEOFENCE_EVENT
PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
}
companion object{
internal const val ACTION_GEOFENCE_EVENT =
"PricklyMapsActivity.pricklypear.action.ACTION_GEOFENCE_EVENT"
}
//Specifies the geofence
private fun seekGeofencing(): GeofencingRequest {
return GeofencingRequest.Builder().apply {
setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
addGeofences(geofenceList)
}.build()
}
//adds the geofence or geofences
#SuppressLint("MissingPermission")
private fun addGeofence(){
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION
) != PERMISSION_GRANTED){
return
}
geoClient?.addGeofences(seekGeofencing(), geofenceIntent)?.run {
addOnSuccessListener {
Toast.makeText(this#PricklyMapsActivity, "Geofence(s) added", Toast.LENGTH_LONG).show()
}
addOnFailureListener {
Toast.makeText(this#PricklyMapsActivity, "Failed to add geofence(s)", Toast.LENGTH_LONG).show()
}
}
}
//Removing geofences
private fun removeGeofence(){
geoClient?.removeGeofences(geofenceIntent)?.run {
addOnSuccessListener {
Toast.makeText(this#PricklyMapsActivity, "Geofences removed", Toast.LENGTH_SHORT).show()
}
addOnFailureListener {
Toast.makeText(this#PricklyMapsActivity, "Failed to remove geofences", Toast.LENGTH_SHORT).show()
}
}
}
//From here and down it is getting location and permition
#SuppressLint("MissingPermission", "NewApi")
private fun getCurrentLocation(){
if (checkPermission()){
if (isLocationEnabled()){
map.isMyLocationEnabled = true
fusedLocatonClient.lastLocation.addOnCompleteListener(this){ task ->
val location: Location?=task.result
if (location==null){
Toast.makeText(this,
"Location may still be turning on pleas wate a while",
Toast.LENGTH_SHORT).show()
}else {
currentLocation = location
myLatlng = LatLng(location.latitude, location.longitude)
map.animateCamera(CameraUpdateFactory.newLatLngZoom(myLatlng, 18f))
addGeofence()
}
Looper.myLooper()
}
}else{
//open settings if location is not enabled
Toast.makeText(this, "Pleas turn on location", Toast.LENGTH_SHORT).show()
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
}
}else{
//requests permition if permition is not granted
requestPermissions()
}
}
//Checker for if the laocation is enabled return boolean
private fun isLocationEnabled(): Boolean{
val locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
//Checker for if the location permission is enabled return boolean
#TargetApi(29)
private fun checkPermission(): Boolean{
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PERMISSION_GRANTED){
if (gadgetQ){
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_BACKGROUND_LOCATION) ==
PERMISSION_GRANTED) {
return true
}
}else {
return true
}
}
return false
}
private fun requestPermissions(){
ActivityCompat.requestPermissions(this,
arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION), permissionId
//android.Manifest.permission.ACCESS_BACKGROUND_LOCATION), permissionId
)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == permissionId){
if (grantResults.isNotEmpty() && grantResults[0] == PERMISSION_GRANTED){
getCurrentLocation()
}else{
Toast.makeText(this, "location is not granted", Toast.LENGTH_SHORT).show()
}
}
}
}
Brodcast receiver Class
class GeofenceBrodcastReceiver: BroadcastReceiver() {
private lateinit var database: DatabaseReference
override fun onReceive(context: Context?, intent: Intent?) {
val geofencingEvent = GeofencingEvent.fromIntent(intent!!)
val geofencingTransition = geofencingEvent!!.geofenceTransition
if (geofencingTransition == Geofence.GEOFENCE_TRANSITION_ENTER) {
database = FirebaseDatabase.getInstance().getReference("Texas")
database.child("Count").get().addOnSuccessListener {
if (it.exists()) {
var number = it.getValue(Long::class.java)
if (number is Long){
number += 1
val post =mapOf<String, Long>("Count" to number)
database.updateChildren(post)
}
} else {
Log.e(TAG, "Invalid type transition")
}
}.addOnFailureListener {
Log.e(TAG, "Invalid type transition")
}
}
}
}
At the pending intent I tried changing the type, but it did not work. I have looked every ware and as far as I can tell there is no problem with my code, and it should work so if someone can help me it would be much appreciated.
Hello I have a fragment with a MapView inside and I need to update the position of his markers every X seconds.
Actually I re-download the data every X seconds then I call "updateAdams" function to relocate all the markers. The problem is that I see the marker move only if I zoom in/zoom out the map, if I don't zoom I don't see the markers move.
How can I solve this?
I tryed to add mGoogleMap.clear() but doing this the markers just disappear and re-appear only if I zoom in/zoom out again.
This is my code (an Adam is a Vehicle):
class GestioneAdamMapFragment : Fragment(),
OnMapReadyCallback,
GetLocationManager.OnLocationUpdateCallback {
private var mGoogleMap: GoogleMap? = null
private lateinit var mGetLocationManager: GetLocationManager
private var mMyLocation: LatLng? = null
private var mAdams: ArrayList<Adam> = ArrayList()
private var mIsFirstInit = true
private var mIdAdamMarkerClicked: Int? = null
private lateinit var mClusterManager: ClusterManager<MarkerClusterItem>
private val mClusterItems = ArrayList<MarkerClusterItem>()
companion object {
fun newInstance(adams: ArrayList<Adam>): GestioneAdamMapFragment {
val mInstance = GestioneAdamMapFragment()
val args = Bundle()
args.putSerializable(KEY_ADAMS, adams)
mInstance.arguments = args
return mInstance
}
fun newInstance() = GestioneAdamMapFragment()
}
//region [#] Override Lifecycle Methods
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_gestione_adam_map, container, false)
initOnCreateView()
MapsInitializer.initialize(requireContext())
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initOnViewCreated(savedInstanceState)
}
override fun onResume() {
mMapView.onResume()
super.onResume()
}
override fun onPause() {
super.onPause()
mMapView.onPause()
}
override fun onDestroy() {
mMapView?.onDestroy()
super.onDestroy()
}
override fun onLowMemory() {
super.onLowMemory()
mMapView.onLowMemory()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if(requestCode == REQ_CODE_PERMISSION_LOCATION){
if(grantResults.size > 0x0){
for(res in grantResults){
if(res == PackageManager.PERMISSION_GRANTED){
mMapView.getMapAsync(this)
break
}
}
}
}
}
//endregion
//region [#] Override OnMapReadyCallback Methods
override fun onMapReady(p0: GoogleMap) {
mGoogleMap = p0
initGoogleMap()
if(mAdams.isNotEmpty()){
initListenersAndCluster()
}
if(mMyLocation != null){
var included = false
if(mAdams.isNotEmpty()){
for(adam in mAdams){
if(adam?.getPosizione() != null && adam!!.getPosizione()!!.getLatitude() != null && adam!!.getPosizione()!!.getLongitude() != null){
included = true
}
}
}
if(!included){
mGoogleMap!!.animateCamera(CameraUpdateFactory.newLatLngZoom(mMyLocation!!, 5.0f))
}
}
}
//region [#] Override GetLocationManager.OnLocationUpdateCallback Methods
override fun onLocationUpdated(location: Location?) {
mMyLocation = if(location != null)
LatLng(location.latitude, location.longitude)
else
null
}
//endregion
//region [#] Public Methods
fun setAdams(adams: List<Adam>){
mAdams.clear()
mAdams.addAll(adams)
if(mGoogleMap != null){
initListenersAndCluster()
}
}
fun updateAdams(adams: List<Adam>){
mClusterManager.removeItems(mClusterItems)
mAdams.clear()
mAdams.addAll(adams)
addClusterItems()
}
//endregion
//region [#] Private Methods
private fun initOnCreateView(){
mGetLocationManager = GetLocationManager.initInstance(requireActivity()).setCallback(this)
mGetLocationManager.startLocationUpdates()
}
private fun initOnViewCreated(savedInstanceState: Bundle?){
mMapView.onCreate(savedInstanceState)
try {
MapsInitializer.initialize(requireActivity().applicationContext)
} catch (e: Exception){
BaseEnvironment.onExceptionLevelLow(TAG, e)
}
mMapView.getMapAsync(this)
mibMapType.setOnClickListener{
when (mGoogleMap!!.mapType) {
GoogleMap.MAP_TYPE_NONE, GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_SATELLITE -> mGoogleMap!!.mapType = GoogleMap.MAP_TYPE_NORMAL
GoogleMap.MAP_TYPE_NORMAL, GoogleMap.MAP_TYPE_TERRAIN -> mGoogleMap!!.mapType = GoogleMap.MAP_TYPE_HYBRID
}
}
}
private fun initGoogleMap(){
if(ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), REQ_CODE_PERMISSION_LOCATION)
} else {
mGoogleMap?.isMyLocationEnabled = true
}
}
private fun initListenersAndCluster(){
mGoogleMap?.clear()
if(mIsFirstInit){
initClusterManager()
zoomToCenterOfAdams()
initOnClickMarker()
initOnClickMap()
mIsFirstInit = false
initOnClickMarkerLabel()
}
addClusterItems()
}
//endregion
private fun zoomToCenterOfAdams(){
val builder: LatLngBounds.Builder = LatLngBounds.Builder()
var included = false
for(adam in mAdams){
if(adam?.getPosizione() != null && adam!!.getPosizione()!!.getLatitude() != null && adam!!.getPosizione()!!.getLongitude() != null){
builder.include(LatLng(adam!!.getPosizione()!!.getLatitude()!!.toDouble(), adam!!.getPosizione()!!.getLongitude()!!.toDouble()))
included = true
}
}
if(included){
val cu: CameraUpdate = CameraUpdateFactory.newLatLngBounds(builder.build(), resources.getDimensionPixelSize(R.dimen.padding_100dp))
mGoogleMap?.animateCamera(cu)
}
}
private fun initOnClickMarkerLabel(){
mClusterManager.setOnClusterItemInfoWindowClickListener {
var adam: Adam? = null
for(a in mAdams){
if(a.getId() == it.title!!.toInt()){
adam = a
break
}
}
if(adam != null){
startActivity(DettagliAdamActivity.getIntent(requireContext(), adam))
}
}
}
private fun initOnClickMarker(){
mClusterManager.setOnClusterItemClickListener {
mIdAdamMarkerClicked = it.title!!.toInt()
false
}
}
private fun initOnClickMap(){
mGoogleMap?.setOnMapClickListener {
mIdAdamMarkerClicked = null
}
}
private fun initClusterManager(){
mClusterManager = ClusterManager(requireContext(), mGoogleMap)
mClusterManager.markerCollection.setInfoWindowAdapter(InfoWindowAdapter(mAdams, requireContext()))
mClusterManager.renderer = ClusterItemRenderer(requireContext(), mGoogleMap!!, mClusterManager)
mGoogleMap!!.setOnCameraIdleListener(mClusterManager)
}
private fun addClusterItems(){
for(adam in mAdams){
var lat = adam.getPosizione()?.getLatitude()?.toDouble()
var lng = adam.getPosizione()?.getLongitude()?.toDouble()
if(lat != null && lng != null){
val marker = MarkerClusterItem(adam, lat, lng, adam.getId().toString(), "Snippet")
mClusterItems.add(marker)
mClusterManager.addItem(marker)
}
}
}
//endregion
}
Actually I'm solving this problem by zooming in of 0.001, is there a better way to solve this problem?
I'm doing as last line of "updateAdams":
mGoogleMap?.animateCamera(CameraUpdateFactory.newLatLngZoom(mGoogleMap?.cameraPosition?.target!!, mGoogleMap!!.cameraPosition!!.zoom + 0.001f))
I put a Map Fragment inside dashboard fragment shown in image below:
To view the image clearly https://i.stack.imgur.com/NcxLB.jpg
whenever i am on home fragment and click on dashboard fragment it takes 3-4 sec (at the first time) and 1-2 sec
here is the code of dashboard fragment
class DashboardFragment :
BaseFragment<DashboardViewModel, FragmentDashboardBinding, WeatherRepository>(),
GoogleMap.OnMapClickListener,
GoogleMap.OnMapLongClickListener,
GoogleMap.OnCameraIdleListener,
OnMapReadyCallback {
private var map: GoogleMap? = null
private var cameraPosition: CameraPosition? = null
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private val defaultLocation = LatLng(-33.8523341, 151.2106085)
private var locationPermissionGranted = false
private var lastKnownLocation: Location? = null
private var weatherData: WeatherData? = null
private lateinit var bottomSheetBehavior: BottomSheetBehavior<NestedScrollView>
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
lastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION)
cameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION)
weatherData = savedInstanceState.getParcelable(KEY_WEATHER_DATA)
}
Log.e("Weather Data", weatherData.toString())
fusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(requireActivity())
val mapFragment =
childFragmentManager.findFragmentById(R.id.myMap) as SupportMapFragment?
mapFragment?.getMapAsync(this#DashboardFragment)
bottomSheetBehavior = BottomSheetBehavior.from(binding.root.bottomSheet)
bottomSheetBehavior.addBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) { /*handle onSlide*/ }
override fun onStateChanged(bottomSheet: View, newState: Int) {
when (newState) {
BottomSheetBehavior.STATE_COLLAPSED -> {
binding.root.bottomSheet.background =
(ContextCompat.getDrawable(requireContext(), R.drawable.round))
}
BottomSheetBehavior.STATE_EXPANDED -> {
binding.root.bottomSheet.background =
(ContextCompat.getDrawable(requireContext(), R.drawable.edge))
}
BottomSheetBehavior.STATE_DRAGGING -> {
}
BottomSheetBehavior.STATE_SETTLING -> {
}
BottomSheetBehavior.STATE_HIDDEN -> {
}
else -> {
}
}
}
})
viewModel.weatherResponse.observe(viewLifecycleOwner, {
when (it) {
is Resource.Success -> {
updateUi(binding.root, it.value)
weatherData = it.value
}
is Resource.Failure -> {
Toast.makeText(
requireContext(),
"Damn, Failed To Load Data",
Toast.LENGTH_SHORT
).show()
}
}
})
}
override fun onSaveInstanceState(outState: Bundle) {
map?.let { map ->
outState.putParcelable(KEY_CAMERA_POSITION, map.cameraPosition)
outState.putParcelable(KEY_LOCATION, lastKnownLocation)
}
super.onSaveInstanceState(outState)
}
override fun onMapReady(map: GoogleMap) {
this.map = map
map.setOnMapClickListener(this)
map.setOnMapLongClickListener(this)
map.setOnCameraIdleListener(this)
getLocationPermission()
updateLocationUI()
getDeviceLocation()
}
var marker: Marker? = null
override fun onMapClick(point: LatLng) {
if (marker == null){
marker = map?.addMarker(
MarkerOptions()
.position(point)
.title("${point.latitude.toString()},${point.longitude.toString()} is the location")
)
} else {
marker!!.position = point
marker!!.title = "${point.latitude.toString()},${point.longitude.toString()} is the location"
}
viewModel.getWeather(
point.latitude.toString(),
point.longitude.toString(),
app_id
)
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED)
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
else
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
Toast.makeText(this.context, "click $point", Toast.LENGTH_SHORT).show()
}
override fun onMapLongClick(point: LatLng) {
try {
val manager: FragmentManager =
(this.context as AppCompatActivity).supportFragmentManager
CustomBottomSheetDialogFragment().show(manager, CustomBottomSheetDialogFragment.TAG)
} catch (e: Exception) {
Log.e("❤", e.printStackTrace().toString())
}
Toast.makeText(this.context, "long click", Toast.LENGTH_SHORT).show()
}
override fun onCameraIdle() {
//if(!::map.isInitialized) return
//cameraTextView.text = map.cameraPosition.toString()
//Toast.makeText(this.context, "camera idle", Toast.LENGTH_SHORT).show()
}
private fun updateLocationUI() {
if (map == null) {
return
}
try {
if (locationPermissionGranted) {
map?.isMyLocationEnabled = true
map?.uiSettings?.isMyLocationButtonEnabled = true
} else {
map?.isMyLocationEnabled = false
map?.uiSettings?.isMyLocationButtonEnabled = false
lastKnownLocation = null
getLocationPermission()
}
} catch (e: SecurityException) {
Log.e("Exception: %s", e.message, e)
}
}
private fun getDeviceLocation() {
try {
if (locationPermissionGranted) {
val locationResult = fusedLocationProviderClient.lastLocation
locationResult.addOnCompleteListener { task ->
if (task.isSuccessful) {
lastKnownLocation = task.result
if (lastKnownLocation != null) {
map?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(
lastKnownLocation!!.latitude,
lastKnownLocation!!.longitude
), DEFAULT_ZOOM.toFloat()
)
)
viewModel.getWeather(
lastKnownLocation!!.latitude.toString(),
lastKnownLocation!!.longitude.toString(),
app_id
)
}
} else {
Log.d(TAG, "Current location is null. Using defaults.")
Log.e(TAG, "Exception: %s", task.exception)
map?.moveCamera(
CameraUpdateFactory
.newLatLngZoom(defaultLocation, DEFAULT_ZOOM.toFloat())
)
map?.uiSettings?.isMyLocationButtonEnabled = false
}
}
}
} catch (e: SecurityException) {
Log.e("Exception: %s", e.message, e)
Toast.makeText(this.context, "Some exception occurred", Toast.LENGTH_SHORT).show()
}
}
private fun getLocationPermission() {
if (ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.ACCESS_FINE_LOCATION
)
== PackageManager.PERMISSION_GRANTED
) {
locationPermissionGranted = true
} else {
requestPermissions(
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
locationPermissionGranted = false
when (requestCode) {
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION -> {
if (grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
locationPermissionGranted = true
}
}
}
updateLocationUI()
}
override fun getViewModal() = DashboardViewModel::class.java
override fun getFragmentBinding(
inflater: LayoutInflater,
container: ViewGroup?
) = FragmentDashboardBinding.inflate(inflater, container, false)
override fun getFragmentRepository() =
WeatherRepository(remoteDataSource.buildApi(WeatherApi::class.java))
companion object {
private val TAG = DashboardFragment::class.java.simpleName
private const val DEFAULT_ZOOM = 15
private const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1
private const val KEY_CAMERA_POSITION = "camera_position"
private const val KEY_LOCATION = "location"
private const val KEY_WEATHER_DATA = "weather_data"
const val app_id = "*******api********"
}
}
even if i comment the whole code it the onActivityCreated() method still the lag occurs.
I used the code from the official Google Maps Platform Documentation, still the example app they use don't lags like my app.
Any help will be appreciated.
I am working on app which require speech to text. I have integrated SpeechRecognizer service. Please check below demo project code for same. Here I have tested that SpeechRecognizer stop listening automatically after 10 to 15 seconds. So I looked for following solution to increase the listening time but did not worked.
Solution 1: SpeechRecognizer - time limit
For the above link i found the problem is text getting cut like Said "Hello , what is the serial number of your currency, It is ABC5654548585" so in first result i got Hello, What is the serial number of your currency and in second i got it is ABC5654548585".So I am unable to parse response properly.
Solution 2: I set the following parameters but did not worked.
EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS
EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS
EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS.
Solution 3: I also integrated mozilla speech to text but it is not accurate as google.
Please help me I am stucked here.Not able to proceed any more.
class MainActivity : AppCompatActivity() {
lateinit var speechRecognize: SpeechRecognizer
var editText: EditText? = null
var micButton: ImageView? = null
var speechRecognizerIntent: Intent? = null
var audioManager: AudioManager? = null
var textRecorded = ""
var isActive = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
speechRecognize = SpeechRecognizer.createSpeechRecognizer(this)
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager?
muteRecognition(true)
editText = findViewById(R.id.text);
micButton = findViewById(R.id.button);
micButton?.setOnClickListener {
if (it.tag == null) {
isActive = true
launchSpeechIntent()
speechRecognize.startListening(speechRecognizerIntent)
it.tag = 1
} else if (it.tag == 1) {
isActive = false
parseText()
speechRecognize.stopListening()
speechRecognize.destroy()
it.tag = null
}
}
val permissions = ArrayList<String>()
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.RECORD_AUDIO
)
!= PackageManager.PERMISSION_GRANTED
) {
permissions.add(Manifest.permission.RECORD_AUDIO)
}
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
!= PackageManager.PERMISSION_GRANTED
) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
if (permissions.isNotEmpty()) {
ActivityCompat.requestPermissions(
this,
permissions.toArray(arrayOf<String>()),
10
)
} else
launchSpeechIntent()
//else
// startRequest()
}
#Suppress("DEPRECATION")
private fun muteRecognition(mute: Boolean) {
audioManager?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val flag = if (mute) AudioManager.ADJUST_MUTE else AudioManager.ADJUST_UNMUTE
it.adjustStreamVolume(AudioManager.STREAM_NOTIFICATION, flag, 0)
it.adjustStreamVolume(AudioManager.STREAM_ALARM, flag, 0)
it.adjustStreamVolume(AudioManager.STREAM_MUSIC, flag, 0)
it.adjustStreamVolume(AudioManager.STREAM_RING, flag, 0)
it.adjustStreamVolume(AudioManager.STREAM_SYSTEM, flag, 0)
} else {
it.setStreamMute(AudioManager.STREAM_NOTIFICATION, mute)
it.setStreamMute(AudioManager.STREAM_ALARM, mute)
it.setStreamMute(AudioManager.STREAM_MUSIC, mute)
it.setStreamMute(AudioManager.STREAM_RING, mute)
it.setStreamMute(AudioManager.STREAM_SYSTEM, mute)
}
}
}
fun launchSpeechIntent() {
speechRecognizerIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechRecognizerIntent?.putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
);
speechRecognizerIntent?.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.packageName)
speechRecognizerIntent?.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
speechRecognizerIntent?.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1)
speechRecognizerIntent?.putExtra(
RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS,
30000
)
speechRecognize.setRecognitionListener(object : RecognitionListener {
override fun onReadyForSpeech(params: Bundle?) {
Log.e("ready for speeach", "true")
}
override fun onRmsChanged(rmsdB: Float) {
Log.e("RMS changed", rmsdB.toString())
}
override fun onBufferReceived(buffer: ByteArray?) {
Log.e("buffer", buffer.toString())
}
override fun onPartialResults(partialResults: Bundle?) {
Log.e("ready for speeach", "true" + partialResults.toString())
}
override fun onEvent(eventType: Int, params: Bundle?) {
Log.e("event", eventType.toString())
Log.e("params", params.toString())
}
override fun onBeginningOfSpeech() {
editText!!.setHint("Listening...........")
editText!!.setText("")
}
override fun onEndOfSpeech() {
}
override fun onError(error: Int) {
Log.e("Error", error.toString())
speechRecognize.startListening(speechRecognizerIntent)
//editText?.setText("Error:"+error.toString())
}
override fun onResults(results: Bundle?) {
val data: ArrayList<String>? =
results!!.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
var flot = results!!.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES)
textRecorded += "#${data!!.first()}"
// restart()
}
})
}
fun restart() {
if (isActive) {
speechRecognize.destroy()
launchSpeechIntent()
speechRecognize.startListening(speechRecognizerIntent)
} else {
speechRecognize.stopListening()
speechRecognize.destroy()
}
}
override fun onResume() {
super.onResume()
}
fun parseText() {
try {
editText?.setText(textRecorded)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.RECORD_AUDIO),
10
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
10 ->
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
launchSpeechIntent()
}
}
}
override fun onDestroy() {
super.onDestroy()
speechRecognize.stopListening()
speechRecognize.destroy()
}
}
can anyone tell me why when I call the function initPetrolStationList() in first if condition currentLocation is allways null but when I call te function addPetrolStation(v: View) is initilized? I would like that when the function initPetrolStationList()is called currentLocation will be not null.
class PetrolStationListActivity : AppCompatActivity() {
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private lateinit var listView: RecyclerView
private var currentLocation: Location? = null
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
//some code
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.petrol_station_list_view)
requestLocationPermission()
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
getLastLocation()
initPetrolStationList()
}
fun addPetrolStation(v: View) {
if (currentLocation != null) {
val googleMapController = GoogleMapsController()
googleMapController.getPetrolStationFromGoogle(object : GoogleResponse {
override fun getLocation(): Location = currentLocation!!
override fun getResponse(body: GoogleMapResponse) {
if (body.status == "OK") {
val intent = Intent(applicationContext, PetrolStationActivity::class.java)
v.context.startActivity(intent)
} else {
Toast.makeText(applicationContext, "Petrol station not found", Toast.LENGTH_LONG).show()
}
}
})
}
}
#SuppressLint("MissingPermission")
private fun getLastLocation() {
fusedLocationProviderClient.lastLocation.addOnCompleteListener {
if (it.isSuccessful) {
currentLocation = it.result!!
Log.d("Current location: ", "Lat:${currentLocation!!.latitude}, Lng:${currentLocation!!.longitude}")
} else {
Log.d("Location exception: ", it.exception?.message)
Toast.makeText(this, "Location not found :( ", Toast.LENGTH_LONG).show()
}
}
}
private fun initPetrolStationList() {
if (currentLocation != null) {
val petrolStationController = PetrolStationController()
//some code
} else Toast.makeText(this, "Location not found", Toast.LENGTH_LONG).show()
}
}
If you call initPetrolStationList from inside getLastLocation after currentLocation = it.result!! then currentLocation will not be null.
Try to initialize petrolStationController immediately
Add fusedLocationProviderClient.lastLocation.addOnCompleteListener in onCreate
And update data of petrolStationController in this listener