Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

Если вы хотите запросить разрешение за пределами действия, вы можете создать другой класс и расширить класс из Activity. Используйте конструктор для получения и установки Контекста для класса.

public class Permissions extends Activity {

private static final int MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 1;
private Context context;

public Permissions(Context context) {
    this.context = context;
}
public void checkWriteExternalStoragePermission() {
    final int MY_PERMISSIONS_REQUEST_PHONE_CALL = 1;
    ContextCompat.checkSelfPermission(context,      Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions((Activity) context,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {

        case MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
            return;

        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}
}

Теперь создайте объект create и передайте контекст конструктору везде, где вам нужно запросить разрешения.

Permissions permissions = new Permissions(SplashScreen.this);
    permissions.checkWriteExternalStoragePermission();

Ответ 2

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

Ответ 3

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

ActivityCompat.requestPermissions(Активность активности, String [] permissions, int requestCode)

из библиотеки поддержки и передать Activity как параметр метода.

Например:

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

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

onRequestPermissionsResult (int requestCode, String [] permissions, int [] grantResults)

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

Ответ 4

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

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

Ответ 5

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

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

enter image description here

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

Ответ 6

Я нашел обходной путь, который, кажется, работает нормально. Хитрость заключается в создании прозрачного действия, которое существует только для запроса разрешений и сразу же завершается. Конечно, вам все равно понадобится контекст, но это не обязательно должно быть занятие. Действие может возвратить результат (предоставленный или отклоненный) через широковещательную startActivtyForResult (поскольку 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() {
        // ...
    }
}

Ответ 7

Можно вызвать requestPermissions() из-за пределов вашей активности, но в вашем классе вы должны иметь контекст этого действия.

ActivityCompat.requestPermissions((Activity)context, new String[]{permission.READ_PHONE_STATE}, REQUEST_CODE);

Чтобы работать, вы должны реализовать ниже метод в своей деятельности

onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults)

Чтобы этот метод переопределения выполнялся, когда пользователь нажимал кнопку разрешения или запрета при всплывании