【问题标题】:How to check if user has granted permission from outside an activity/fragment in android如何检查用户是否已从android中的活动/片段外部授予权限
【发布时间】:2021-05-27 09:13:00
【问题描述】:

我正在使用 dexter 为导航组件提供运行时权限。

我有一个包含多个片段的活动。

在活动中,我想请求用户授予权限(存储)。

然后我有一个类(不是 Activity 或 Fragment),需要在访问一些需要运行时权限的代码之前检查用户是否已授予权限..

我还有一个 viewModel 运行需要运行时权限的代码

问题

我无法在任何这些类/viewModel 中访问上下文。我现在如何检查用户是否已授予权限。

实用类

fun requestExternalStoragePermission(context: Context, callback: PermissionsCallback) {
    Dexter.withContext(context) //
        .withPermissions(listOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE))
        .withListener(object : MultiplePermissionsListener {
            override fun onPermissionsChecked(p0: MultiplePermissionsReport?) {
                p0?.let {
                    if (p0.areAllPermissionsGranted()) {
                        callback.onPermissionRequest(granted = true)
                    } else {
                        callback.onPermissionRequest(granted = false)
                    }
                }
            }
            override fun onPermissionRationaleShouldBeShown(
                p0: MutableList<PermissionRequest>?,
                p1: PermissionToken?
            ) {
                p1?.continuePermissionRequest()
            }
        })
        .check()
}

界面

 interface PermissionsCallback {
  fun onPermissionRequest(granted: Boolean)
}

MainActivity

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    checkForPermission()
    setContentView(binding.root)
}

 private fun checkForPermission(){
  Utility.requestExternalStoragePermission(
      this,
      object : PermissionsCallback {
      override fun onPermissionRequest(granted: Boolean) {
      if (granted) {
       //good
       } else {
       //show settings
     }
}

更新

音乐服务

class MusicService : MediaBrowserServiceCompat() {

 private val serviceJob = Job()
 private val serviceScope = CoroutineScope(Dispatchers.Main + 
serviceJob)

var context: Context? = null
   
    override fun onCreate() {
    super.onCreate()
    context = this
    checkForPermission()
  
 }

  private fun checkForPermission(){
    Utility.requestExternalStoragePermission(
        this,
        object : PermissionsCallback {
            override fun onPermissionRequest(granted: Boolean) {
                if (granted) {
                    //good, load songs
                    serviceScope.launch {
                        musicSource.fetchMediaData()
                    }
                } else {
                    //do something else
                    Toast.makeText(context, "We need permission nowwww", Toast.LENGTH_LONG)
                        .show()
                }
            }
        })
 }

 override fun onDestroy() {
    super.onDestroy()
    serviceScope.cancel()

    exoPlayer.removeListener(musicPlayerEventListener)
    exoPlayer.release()

}

}

视图模型

 init {
    viewModelScope.launch {
        val allArtistes = artisteDatabase.getAllArtiste().....//I need to check here tooo
        _artisteList.value = Resource.success(allArtistes)
    }
}

fun doGetArtisteSongs(long: Long){
    viewModelScope.launch {
         val artisteSongs = artisteDatabase.getArtisteSongs(long).....//I need to check here too
        _artisteSongList.value = Resource.success(artisteSongs)
    }
}

我无法使用我的实用程序函数来检查该非活动/片段类和视图模型的权限,因为它需要一个“上下文”。

正确的出路是什么?

【问题讨论】:

  • 我可以看到你的实用程序类中有一个函数,并且有一个上下文参数,并且从活动传递,错误是什么?
  • 没有错误...我想检查是否在非活动/片段类和视图模型(没有上下文)中授予了相同的权限

标签: android android-studio kotlin android-fragments


【解决方案1】:

如果 MusicService 是服务类,您可以从服务中获取上下文。

 Context context;
    
    @Override
    public void onCreate() {
        super.onCreate();
        context = this;
    }
    
 //then you can call requestExternalStoragePermission() using context.

 //If you want context in viewmodel use HILT dependency injection library.

 @ViewModelInject
    public MainViewModel(MainRepository mainRepository, @ApplicationContext Context context) {
        this.repository = mainRepository;
        this.context = context;

    }

【讨论】:

  • 这行得通...谢谢,但我有一个问题。当用户单击 MainActivity 授予权限时(通常应用程序会立即加载歌曲列表)...但是现在,我必须关闭应用程序并在歌曲出现之前重新打开(来自 MusicService 类)
  • 无需关闭并重新打开应用程序。在 MainActivity 中使用 onStart() 调用您的 checkForPermission()。@Ibramazin
  • 我这样做了,但没有工作。事情在 MainActivity 中,如果已获得许可……我什么也没做。我正在编写相同的代码来签入(MusicService),但如果授予 ->(然后 serviceScope.launch { musicSource.fetchMediaData() } )//获取歌曲...
  • 你能显示 MusicService 中的所有代码吗?@Ibramazin
  • 当然,检查更新的 MusicService 类。我尝试从 MainActivity 应用相同的逻辑 -> 如果授予 -> serviceScope.launch{ musicSource.fetchMediaData()} 但如果我使用 MainActivity 则歌曲不会出现
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多