it-roy-ru.com

Android M запросить разрешение не активность

Мой виджет выполняет вызовы для защиты разрешений вне области Activity. Можно ли запрашивать разрешения для Android M вне Activity?

32
Dave Honly

Нет, это невозможно. Что вы можете сделать, это отправить уведомление, где пользователь может нажать, а затем использовать действие для запроса/управления разрешением (возможно, с темой диалога).

5
greywolf82

Я думаю, что можно запросить разрешение вне Activity, если вы используете метод

ActivityCompat.requestPermissions (активность Activity, разрешения String [], int requestCode)

из библиотеки поддержки и передайте Activity в качестве параметра метода.

Например:

ActivityCompat.requestPermissions(targetActivity, new String[] {Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);

где targetActivity - это действие, которое должно реализовывать метод:

onRequestPermissionsResult (разрешения типа int requestCode, String [], int [] grantResults)

Это метод, который будет обрабатывать результат запроса разрешения.

3
Fede

Вы можете использовать библиотеку Easy Permissions

Android требует, чтобы этот запрос исходил от Activity. С Easy Permissions это больше не проблема, вы можете запросить разрешение в любом месте, пока вы предоставляете Context. Кроме того, если вы запрашиваете разрешение, которое уже предоставлено, пользователю не будет предложено.

 enter image description here

Полное раскрытие, наша компания управляет и развивает эту бесплатную библиотеку. При этом, мы уверены, что это полезный инструмент, и мы не поделились бы им в противном случае. 

2
Newtron Labs

Вы можете запросить разрешение только у Activity или у фрагмента.

Выясните точку в вашей деятельности или фрагменте, где, по вашему мнению, приложению потребуется разрешение, затем вызовите метод requestPermission. отправка уведомления не будет работать, потому что вы хотите обрабатывать код до тех пор, пока не получите запрошенные разрешения, а затем возобновите работу с помощью метода onRequestPermissionResult ().

1
dex

Я нашел обходной путь, который, кажется, работает нормально. Хитрость в том, чтобы создать прозрачную активность, которая существует только для запроса разрешений, и сразу же завершается. Конечно, вам все равно понадобится контекст, но он не обязательно должен быть активностью . Активность может возвращать результат (предоставленный или отклоненный) через широковещательную рассылку (поскольку startActivtyForResult невозможна вне действия).

Вы можете использовать эту деятельность:

import Android.content.Intent
import Android.content.pm.PackageManager
import Android.os.Bundle
import Android.support.v4.app.ActivityCompat
import Android.support.v7.app.AppCompatActivity

internal const val PERMISSIONS_KEY = "permissions"
internal const val ACTION_PERMISSIONS_GRANTED = "GetPermissionsActivity.permissions_granted"
internal const val ACTION_PERMISSIONS_DENIED = "GetPermissionsActivity.permissions_denied"

class GetPermissionsActivity: AppCompatActivity() {

    private val permissionRequestCode = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityCompat.requestPermissions(
            this,
            intent.getStringArrayExtra(PERMISSIONS_KEY),
            permissionRequestCode
        )
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == permissionRequestCode) {
            if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                sendBroadcast(Intent(ACTION_PERMISSIONS_GRANTED))
            } else {
                sendBroadcast(Intent(ACTION_PERMISSIONS_DENIED))
            }
            finish()
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    }
}

И этот стиль для деятельности

<style name="Theme.Transparent" parent="Theme.AppCompat">
    <item name="Android:windowIsTranslucent">true</item>
    <item name="Android:windowBackground">@Android:color/transparent</item>
    <item name="Android:windowContentOverlay">@null</item>
    <item name="Android:windowNoTitle">true</item>
    <item name="Android:windowIsFloating">true</item>
    <item name="Android:backgroundDimEnabled">false</item>
    <item name="Android:windowAnimationStyle">@null</item>
</style>

В манифесте:

<activity Android:name="GetPermissionsActivity" Android:theme="@style/Theme.Transparent" />

А затем использовать его так (требуется контекст)

class SomeClass : BroadcastReceiver() {

    private fun someFunction(context: Context) {
        val intentFilter = IntentFilter()
        intentFilter.addAction(ACTION_PERMISSIONS_GRANTED)
        intentFilter.addAction(ACTION_PERMISSIONS_DENIED)
        context.registerReceiver(this, intentFilter)
        val intent = Intent(context, GetPermissionsActivity::class.Java)
        intent.putExtra(PERMISSIONS_KEY, arrayOf(<your permissions>))
        context.startActivity(intent)
    }

    override fun onReceive(context: Context, intent: Intent) {
        when {
            intent.action == ACTION_PERMISSIONS_GRANTED -> {
                context.unregisterReceiver(this)
                onPermissionsGranted()
            }
            intent.action == ACTION_PERMISSIONS_DENIED -> {
                context.unregisterReceiver(this)
                onPermissionsDenied()
            }
            else -> super.onReceive(context, intent)
        }
    }

    private fun onPermissionsGranted() {
        // ...
    }

    private fun onPermissionsDenied() {
        // ...
    }
}
0
Benni Bsngr