tbruyelle / RxPermissions

Android runtime permissions powered by RxJava2
Apache License 2.0
10.48k stars 1.31k forks source link

targetSdkVersion 28, and REQUEST_INSTALL_PACKAGES permission always return false #281

Open Jack-Xiao opened 5 years ago

Jack-Xiao commented 5 years ago
  1. targetSdkVersion 28 packageManager.canRequestPackageInstalls() return true when i setting install permission, but rxPermissions?.request(Manifest.permission.REQUEST_INSTALL_PACKAGES) always return false。How to relsolve

  2. the test project: https://github.com/Jack-Xiao/RxPermissionsTest

qqnp1100 commented 5 years ago

I wrote a simple extension for RxPermissions.

import android.annotation.TargetApi
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject

fun RxPermissions.requestPackageInstalls(activity: FragmentActivity): Observable<Boolean> {
    var fragment: PackageInstallsFragment? = null
    if (activity != null && !activity.isFinishing) {
        val fm = activity.supportFragmentManager
        fragment = fm.findFragmentByTag(PackageInstallsFragment.TAG) as PackageInstallsFragment?
        if (fragment == null) {
            fragment = PackageInstallsFragment()
            fm.beginTransaction()
                .add(fragment, PackageInstallsFragment.TAG)
                .commitNow()
        }
        var isGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            activity.packageManager.canRequestPackageInstalls()
        } else {
            true
        }
        if (isGranted) {
            return Observable.just(true)
        } else {
            if (!fragment.isRequest) {
                fragment.sub = PublishSubject.create()
            }
            fragment.requestPermissions()
        }
    }
    return fragment!!.sub!!
}

class PackageInstallsFragment : Fragment() {
    var sub: PublishSubject<Boolean>? = null
    var isRequest = false

    companion object {
        const val TAG = "PackageInstallsFragment"
        const val CODE = 10086
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        retainInstance = true
    }

    fun requestPermissions() {
        isRequest = true
        val uri = Uri.fromParts("package", activity!!.packageName, null)
        startActivityForResult(Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, uri), CODE)
    }

    @TargetApi(Build.VERSION_CODES.O)
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        isRequest = false
        sub!!.onNext(activity!!.packageManager.canRequestPackageInstalls())
        sub!!.onComplete()
    }
}

use

val rxPermissions = RxPermissions(this)
rxPermissions.requestPackageInstalls(this).subscribe {
                if (it) {

                } else {

                }
            }

ezgif-3-5ea05e68ded3

Jack-Xiao commented 5 years ago

@qqnp1100 thank you, i understand your means, and use getPackageManager().canRequestPackageInstalls() can resolve it。 However i means why rxPermissions?.request(Manifest.permission.REQUEST_INSTALL_PACKAGES) always return false when turn on the switch。

yungtat commented 5 years ago

是继承RxPermission写的吗?

consp1racy commented 4 years ago

Request_install_packages is not a dangerous/runtime permission. You can't use RxPermissions with it.

It's a normal permission. You declare it in manifest and then you can use PackageInstaller API to install packages interactively.