You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Fragment中获取Activity的权限申请结果?

解决Fragment中权限申请结果的回调问题

你的问题本质是权限申请结果无法从Activity传递到Fragment,导致用户授权后Fragment没法触发显示地图的逻辑。下面给你三种实用的解决方案,按推荐程度排序:


方案1:让Fragment直接处理权限请求(最推荐)

其实Fragment本身就自带权限申请和结果回调的能力,完全不需要通过Activity中转。这样逻辑更内聚,也避免了跨组件通信的麻烦。

修改你的MapFragment代码:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    if (ContextCompat.checkSelfPermission(requireContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) 
        == PackageManager.PERMISSION_GRANTED) {
        // 权限已授予,显示地图
        permission_button.visibility = View.GONE
        val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment?.getMapAsync(callback)
    } else {
        // 权限未授予,自己申请
        requestPermissions(
            arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
            Constants.LOCATION_PREMMISION_CODE
        )
    }
}

// 重写Fragment的权限结果回调
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == Constants.LOCATION_PREMMISION_CODE) {
        if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 用户授予权限,显示地图
            permission_button.visibility = View.GONE
            val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
            mapFragment?.getMapAsync(callback)
        } else {
            // 用户拒绝权限,隐藏地图
            permission_button.visibility = View.VISIBLE
            // 可以在这里提示用户需要权限才能使用地图
        }
    }
}

这样Fragment完全自主处理权限逻辑,不用依赖Activity的uiCommunicationListener,代码更清晰。


方案2:扩展接口回调,让Activity通知Fragment结果

如果一定要保留Activity的权限检查逻辑,可以扩展你的uiCommunicationListener接口,增加一个权限结果回调方法,让Activity在收到权限结果后通知Fragment。

第一步:修改接口定义

interface UiCommunicationListener {
    fun isLocationPermissionGranted(): Boolean
    // 新增权限结果回调方法
    fun onLocationPermissionResult(granted: Boolean)
}

第二步:修改MainActivity的权限处理

override fun isLocationPermissionGranted(): Boolean {
    if (ContextCompat.checkSelfPermission(
            this,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
            Constants.LOCATION_PREMMISION_CODE
        )
        return false
    } else {
        return true
    }
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == Constants.LOCATION_PREMMISION_CODE) {
        val granted = grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED
        // 通知所有实现了接口的Fragment,或者指定你的MapFragment
        supportFragmentManager.fragments.forEach { fragment ->
            if (fragment is UiCommunicationListener) {
                fragment.onLocationPermissionResult(granted)
            }
        }
    }
}

第三步:在MapFragment中实现回调

class MapFragment : Fragment(), UiCommunicationListener {
    // ... 其他代码 ...

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        checkLocationPermission()
    }

    private fun checkLocationPermission() {
        if (uiCommunicationListener.isLocationPermissionGranted()) {
            showMap()
        } else {
            hideMap()
        }
    }

    private fun showMap() {
        permission_button.visibility = View.GONE
        val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment?.getMapAsync(callback)
    }

    private fun hideMap() {
        permission_button.visibility = View.VISIBLE
        // 隐藏地图的逻辑
    }

    override fun onLocationPermissionResult(granted: Boolean) {
        if (granted) {
            showMap()
        } else {
            hideMap()
        }
    }
}

方案3:用ViewModel共享权限状态(适合复杂场景)

如果你的项目用了Jetpack组件,可以用ViewModel来共享权限状态,Activity更新状态,Fragment观察状态变化。

第一步:创建PermissionViewModel

class PermissionViewModel : ViewModel() {
    val locationPermissionGranted = MutableLiveData<Boolean>()
}

第二步:在MainActivity中更新状态

class MainActivity : AppCompatActivity(), UiCommunicationListener {
    private val permissionViewModel: PermissionViewModel by viewModels()

    override fun isLocationPermissionGranted(): Boolean {
        val granted = ContextCompat.checkSelfPermission(
            this,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
        permissionViewModel.locationPermissionGranted.value = granted
        if (!granted) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                Constants.LOCATION_PREMMISION_CODE
            )
        }
        return granted
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == Constants.LOCATION_PREMMISION_CODE) {
            permissionViewModel.locationPermissionGranted.value = 
                grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED
        }
    }
}

第三步:在MapFragment中观察状态

class MapFragment : Fragment() {
    private val permissionViewModel: PermissionViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        // 观察权限状态变化
        permissionViewModel.locationPermissionGranted.observe(viewLifecycleOwner) { granted ->
            if (granted) {
                showMap()
            } else {
                hideMap()
            }
        }

        // 初始检查权限
        (activity as? UiCommunicationListener)?.isLocationPermissionGranted()
    }

    private fun showMap() {
        permission_button.visibility = View.GONE
        val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment?.getMapAsync(callback)
    }

    private fun hideMap() {
        permission_button.visibility = View.VISIBLE
        // 隐藏地图的逻辑
    }
}

个人最推荐方案1,因为它让Fragment的逻辑更独立,减少了和Activity的耦合。如果你的项目有统一的权限管理需求,方案2或3会更合适。

内容的提问来源于stack exchange,提问作者ScrapeW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:07:30