Я работаю в kotlin, и мой фрагмент находится внутри действия. Поэтому, когда я запускаю свое приложение и как только открывается фрагмент местоположения, оно запрашивает у меня разрешение, но сразу падает, поэтому я не могу разрешить или отклонить разрешение.
Вот мой код для фрагмент местоположения:
package com.example.atry.MakeComplaint
import android.app.Activity
import android.app.Activity.RESULT_OK
import com.example.atry.Retrofit.INodeJS
import com.example.atry.Retrofit.Observables
import com.example.atry.Retrofit.RetrofitClient
import android.content.Context
import android.content.IntentSender
import android.content.pm.PackageManager
import android.location.*
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Switch
import android.widget.Toast
import com.google.android.gms.maps.MapView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.atry.R
import com.google.android.gms.common.api.ResolvableApiException
import com.google.android.gms.location.*
import com.google.android.gms.maps.*
import com.google.android.gms.maps.model.*
import kotlinx.android.synthetic.main.fragment_location.view.*
import retrofit2.Call
import retrofit2.Response
class LocationFragment : Fragment(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener {
override fun onMarkerClick(p0: Marker?)= false
private lateinit var map: GoogleMap
private lateinit var mapView : MapView
private lateinit var restrict:LatLngBounds
lateinit var myAPI: INodeJS
var MyCategory: Observables.Complainttype?=null
private var listener: OnLocationFragmentInteractionListener? = null
var makeComplaintobject1:Observables.final?=null
lateinit var typename:String
var objectComplaint =
Observables.Complaint(
1 , "dummy problem" ,
"url" ,
Observables.Location("78.4","17.4"),
Observables.ComplaintTypes("Smell" ),
Observables.Status( "Unresolved")
)
//for updating user's location/ for current location
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationRequest: LocationRequest
private lateinit var locationCallback: LocationCallback
// private lateinit var lastLocation: Location
var lastLocation:Location?=null
private var locationUpdateState = false
companion object {
private const val LOCATION_PERMISSION_REQUEST_CODE = 1
private const val REQUEST_CHECK_SETTINGS = 2 //For updating user's location as they move
}
fun sendCategoryItem(category: Observables.Complainttype) {
//receiving the category selected from Category Fragment
this.MyCategory = category
Log.d("here", "i am here 1")
Log.d("here", MyCategory.toString())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
if (locationResult.locations.isNotEmpty()) {
// get latest location and sets it on the map
lastLocation = locationResult.lastLocation
Log.d("lastlocation", lastLocation.toString())
placeMarkerOnMap(LatLng(lastLocation!!.latitude, lastLocation!!.longitude))
} } }
getLocationUpdates()
//INIT API
val retrofit = RetrofitClient.instanc
myAPI = retrofit.create(INodeJS::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val v = inflater.inflate(R.layout.fragment_location, container, false)
mapView = v.findViewById(R.id.maps)
mapView.onCreate(savedInstanceState)
mapView.onResume()
try {
MapsInitializer.initialize(getActivity()!!.getApplicationContext())
} catch (sendEx: IntentSender.SendIntentException) {
sendEx.printStackTrace()
}
mapView.getMapAsync(this)
v.backToList.setOnClickListener {
backFragment()
}
v.forwardToDescription.setOnClickListener{
//will proceed to the Category Description fragment only if the lastLocation isn't null
getAllData()
}
return v
}
private fun setUpMap() {
if (activity!!.checkSelfPermission(
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
return
}
}
private fun checkForPermissions(){
if(activity!!.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
requestPermissions( arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
}
startLocationUpdates()
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(grantResults.size >0){
if(requestCode== LOCATION_PERMISSION_REQUEST_CODE && grantResults[0] == PackageManager.PERMISSION_GRANTED){
locationUpdateState=true
checkForPermissions()
}
}
}
/**
* call this method in onCreate
* onLocationResult call when location is changed
*/
private fun getLocationUpdates() {
//with fusedLocationClient
// fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
locationRequest = LocationRequest()
locationRequest.interval = 1000
locationRequest.fastestInterval = 5000
locationRequest.smallestDisplacement = 170f // 170 m = 0.1 mile
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //set according to your app function
val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
val client = LocationServices.getSettingsClient(context!!)
val task = client.checkLocationSettings(builder.build())
//can update the map if location services on
task.addOnSuccessListener {
locationUpdateState=true
checkForPermissions()
}
task.addOnFailureListener { e ->
//check if the location settings is on yet
if(e is ResolvableApiException){
try{
e.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS)
}catch (sendEx : IntentSender.SendIntentException){
}
}
}
}
//Places the marker on the map and changes its style.
private fun placeMarkerOnMap(location: LatLng) {
// 1
val markerOptions = MarkerOptions().position(location)
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
// 2
map.addMarker(markerOptions)
}
//start location updates
private fun startLocationUpdates() {
fusedLocationClient.requestLocationUpdates(
locationRequest,
locationCallback,
null /* Looper */
)
}
// stop location updates
private fun stopLocationUpdates() {
fusedLocationClient.removeLocationUpdates(locationCallback)
}
// start receiving location update when activity visible/foreground
override fun onResume() {
super.onResume()
mapView.onResume()
checkForPermissions()
// startLocationUpdates()
}
// stop receiving location update when activity not visible/foreground
override fun onPause() {
super.onPause()
mapView.onPause()
stopLocationUpdates()
}
override fun onDestroy() {
super.onDestroy()
mapView.onDestroy()
}
override public fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}
override fun onMapReady(googleMap: GoogleMap?) {
map = googleMap!!
map.uiSettings?.isZoomControlsEnabled = true
setUpMap()
map.isMyLocationEnabled = true
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
//updating the map with user's current location
if (location !=null){
lastLocation = location
val currentLatLng = LatLng(location.latitude,location.longitude)
placeMarkerOnMap(currentLatLng)
map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng,12f))
}
}
}
private fun backFragment() {
val manager = (context as AppCompatActivity).supportFragmentManager
manager.popBackStackImmediate()
}
fun getAllData(){
//
// val latitude = 17.4
// val longitude = 78.4
// LocationUtils().getInstance(appContext)
// LocationUtils().getLocation().observe(this, Observer {loc: Location? ->
// location = loc!!
// // Yay! location recived. Do location related work here
// Log.i(TAG,"Location: ${location.latitude} ${location.longitude}")
//
// })
if(lastLocation!=null){
makeComplaintobject1 = Observables.final(
Observables.ComplaintTypes(MyCategory!!.typeName),
// Observables.Location(lastLocation.longitude.toString(),lastLocation.latitude.toString()) //lateinit wala
Observables.Location(lastLocation!!.longitude.toString(),lastLocation!!.latitude.toString())
)
}
else{
makeComplaintobject1 = Observables.final(
Observables.ComplaintTypes(MyCategory!!.typeName),
// Observables.Location(lastLocation.longitude.toString(),lastLocation.latitude.toString()) //lateinit wala
Observables.Location("","")
)
}
typename = MyCategory!!.typeName
val call = myAPI.checkExistingComplain(typename,makeComplaintobject1!!.finalLocation.longitude, makeComplaintobject1!!.finalLocation.latitude ) //new
Log.d("T", typename)
Log.d("Lo", makeComplaintobject1!!.finalLocation.longitude)
Log.d("La", makeComplaintobject1!!.finalLocation.latitude)
call.enqueue(object : retrofit2.Callback<Observables.checkExistingResult> {
override fun onFailure(call: Call<Observables.checkExistingResult>?, t: Throwable?) {
Log.d("NO", t!!.message)
}
override fun onResponse(call: Call<Observables.checkExistingResult>?, response: Response<Observables.checkExistingResult>?) {
Log.d("response popup", response!!.code().toString())
//
if(response.code() == 200){
Log.d("YES", response.code().toString())
Log.d("response", response.body().toString())
if(response.body()!!.Complain === null){
//if type and location are in db but does not match
Log.d("null",response.body()!!.Complain.toString())
var item1 = makeComplaintobject1
Log.d("wohoooooo",makeComplaintobject1.toString())
listener!!.onLocationFragmentInteraction1(item1!!) // typeName and location going to category description
}
else{
//if location or type matched
objectComplaint = response.body()!!.Complain!!
Log.d("got the complaint",objectComplaint.toString())
setExistingData(objectComplaint)
val item = objectComplaint
listener!!.onLocationFragmentInteraction(item) // all complaint going to popup
}
}
else if(response.code() == 500){
//if location or type is not in db
Log.d("response error", response.body().toString())
var item1 = makeComplaintobject1
Log.d("NOT IN DB",makeComplaintobject1.toString())
listener!!.onLocationFragmentInteraction1(item1!!) // typeName and location going to category description
}
else{
var item1 = makeComplaintobject1
Log.d("wohoooooo!1111",makeComplaintobject1.toString())
listener!!.onLocationFragmentInteraction1(item1!!) // typeName and location going to category description
//descriptionFragment()
}
}
})
}
interface OnLocationFragmentInteractionListener {
fun onLocationFragmentInteraction(item: Observables.Complaint?) // all complaint going to popup
fun onLocationFragmentInteraction1(item1: Observables.final) // typeName and location going to category description
}
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnLocationFragmentInteractionListener) {
listener = context
}
else {
throw RuntimeException("$context must implement OnLocationFragmentInteractionListener")
}
}
fun setExistingData(test: Observables.Complaint) {
objectComplaint = test
}
}
Я уже запросил разрешение ACCESS_FINE_LOCATION в манифесте, и моя версия min sdk - 23, а targetdk - 26.
После многих попыток я Я все еще получаю следующую ошибку.
java.lang.SecurityException: my location requires permission ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION
Пожалуйста, если кто-нибудь может мне помочь с этим, я действительно ценю это!