В Android 6.0 несколько разрешений
Я знаю, что Android 6.0 имеет новые разрешения, и я знаю, что могу вызвать их с чем-то вроде этого
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, PERMISSION_WRITE_STORAGE);
}
сегодня я видел приложение Google, которое нуждается в 3 разрешения: контакты, sms и камеры. Он делает страницу 1-3 и вызывает их все вместе одновременно для активации.
может ли кто-нибудь сказать мне, как я могу позвонить 4 разрешения для активации в то же время, как sms, камера, контакты и хранения?
пример (забыл название приложения google :( )
Приложение нуждается в sms, контакты и камеры
приложение попросило меня (и сделало диалоговое окно page1-3) активировать sms, активировать контакты, а затем камеру. Таким образом, это приложение google вызывало все 3 необходимых разрешения вместе, и мой вопрос в том, как я могу достичь того же ?
19 ответов
просто включите все 4 разрешения в ActivityCompat.requestPermissions(...)
вызов и Android будет автоматически страницы их вместе, как вы упомянули.
у меня есть вспомогательный метод для проверки нескольких разрешений и посмотреть, не предоставляется ли какой-либо из них.
public static boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
тогда просто отправьте все разрешения. Android будет просить только те, которые ему нужны.
// The request code used in ActivityCompat.requestPermissions()
// and returned in the Activity's onRequestPermissionsResult()
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
android.Manifest.permission.READ_CONTACTS,
android.Manifest.permission.WRITE_CONTACTS,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_SMS,
android.Manifest.permission.CAMERA
};
if(!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
вот подробный пример с несколькими просит разрешения:-
приложение требует 2 разрешения при запуске . SEND_SMS и ACCESS_FINE_LOCATION (оба упомянуты в манифесте.XML.)
Я использую библиотека поддержки v4 который готов обрабатывать Android pre-Marshmallow и поэтому не нужно проверять версии сборки.
Как только приложение запускается, он просит разрешения. Если оба разрешения имеют нормальный поток идет.
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(checkAndRequestPermissions()) {
// carry on the normal flow, as the case of permissions granted.
}
}
private boolean checkAndRequestPermissions() {
int permissionSendMessage = ContextCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS);
int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.SEND_SMS);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
ContextCompat.checkSelfPermission (), ActivityCompat.requestPermissions (), ActivityCompat.shouldShowRequestPermissionRationale () являются частью библиотеки поддержки.
Если одно или несколько разрешений не предоставлены, ActivityCompat.requestPermissions () запрашивает разрешения, и элемент управления переходит к обратному вызову onRequestPermissionsResult() метод.
вы должны проверить значение флага shouldShowRequestPermissionRationale() в методе обратного вызова onRequestPermissionsResult ().
есть только два случая:--
Пример 1: - каждый раз, когда пользователь нажимает запретить разрешения (включая самый первый раз), он вернет true. Поэтому, когда пользователь отрицает, мы можем показать больше объяснений и еще раз прошу
Пример 2:-только если пользователь выбирает "не спрашивает снова " он вернет false. В этом случае мы можем продолжить с ограниченной функциональностью и направлять пользователя, чтобы активировать разрешения из настроек для более функциональных возможностей, или мы можем закончить настройку, если разрешения тривиальны для приложения.
случае -1
случай-2
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
Log.d(TAG, "Permission callback called-------");
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
// Initialize the map with both permissions
perms.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
// Fill with actual results from user
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for both permissions
if (perms.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "sms & location services permission granted");
// process the normal flow
//else any one or both the permissions are not granted
} else {
Log.d(TAG, "Some permissions are not granted ask again ");
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// // shouldShowRequestPermissionRationale will return true
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.SEND_SMS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
showDialogOK("SMS and Location Services Permission required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
.show();
// //proceed with logic by disabling the related features or quit the app.
}
}
}
}
}
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
небольшой код :
public static final int MULTIPLE_PERMISSIONS = 10; // code you want.
String[] permissions= new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION};
if (checkPermissions())
// permissions granted.
}
private boolean checkPermissions() {
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
for (String p:permissions) {
result = ContextCompat.checkSelfPermission(getActivity(),p);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(p);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),MULTIPLE_PERMISSIONS );
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissionsList[], int[] grantResults) {
switch (requestCode) {
case MULTIPLE_PERMISSIONS:{
if (grantResults.length > 0) {
String permissionsDenied = "";
for (String per : permissionsList) {
if(grantResults[0] == PackageManager.PERMISSION_DENIED){
permissionsDenied += "\n" + per;
}
}
// Show permissionsDenied
updateViews();
}
return;
}
}
}
список разрешений Android обычные разрешения и опасные разрешения в API 23
фрагмент
public class Homefragment extends Fragment {
View hfrag;
Context context;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//first we must check the permissions are already granted
hfrag = inflater.inflate(R.layout.home, container, false);
context = getActivity();
checkAndRequestPermissions();
}
}
private boolean checkAndRequestPermissions() {
int permissionSendMessage = ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_SMS);
int contactpermission = ContextCompat.checkSelfPermission(context, Manifest.permission.GET_ACCOUNTS);
int writepermission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int callpermission = ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE);
int receivepermission = ContextCompat.checkSelfPermission(context, Manifest.permission.RECEIVE_SMS);
int locationpermission = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationpermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (contactpermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.GET_ACCOUNTS);
}
if (writepermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_SMS);
}
if (receivepermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.RECEIVE_SMS);
}
if (callpermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CALL_PHONE);
}
if (!listPermissionsNeeded.isEmpty()) {
requestPermissions(listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_ID_MULTIPLE_PERMISSIONS) {
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++) {
if (permissions[i].equals(Manifest.permission.GET_ACCOUNTS)) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.e("msg", "accounts granted");
}
} else if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.e("msg", "storage granted");
}
} else if (permissions[i].equals(Manifest.permission.CALL_PHONE)) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.e("msg", "call granted");
}
} else if (permissions[i].equals(Manifest.permission.RECEIVE_SMS)) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.e("msg", "sms granted");
}
} else if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.e("msg", "location granted");
}
}
}
}
}
}
}
это легко, сделать так
private static final int REQUEST_READ_PHONE_STATE = 110 , REQUEST_ACCESS_FINE_LOCATION = 111, REQUEST_WRITE_STORAGE = 112;
в вашем onCreate
//request permission
boolean hasPermissionPhoneState = (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermissionPhoneState) {
ActivityCompat.requestPermissions(LoginActivity.this,
new String[]{Manifest.permission.READ_PHONE_STATE},
REQUEST_READ_PHONE_STATE);
}
boolean hasPermissionLocation = (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);
if (!hasPermissionLocation) {
ActivityCompat.requestPermissions(LoginActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_ACCESS_FINE_LOCATION);
}
boolean hasPermissionWrite = (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermissionWrite) {
ActivityCompat.requestPermissions(LoginActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
}
затем проверить результат
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case REQUEST_READ_PHONE_STATE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(LoginActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show();
//reload my activity with permission granted or use the features what required the permission
finish();
startActivity(getIntent());
} else
{
Toast.makeText(LoginActivity.this, "The app was not allowed to get your phone state. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
case REQUEST_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(LoginActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show();
//reload my activity with permission granted or use the features what required the permission
finish();
startActivity(getIntent());
} else
{
Toast.makeText(LoginActivity.this, "The app was not allowed to get your location. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
case REQUEST_WRITE_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(LoginActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show();
//reload my activity with permission granted or use the features what required the permission
finish();
startActivity(getIntent());
} else
{
Toast.makeText(LoginActivity.this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
мой класс обработчика для запроса нескольких разрешений. Вы можете проверить использование здесь
public class RequestPermissionHandler {
private Activity mActivity;
private RequestPermissionListener mRequestPermissionListener;
private int mRequestCode;
public void requestPermission(Activity activity, @NonNull String[] permissions, int requestCode,
RequestPermissionListener listener) {
mActivity = activity;
mRequestCode = requestCode;
mRequestPermissionListener = listener;
if (!needRequestRuntimePermissions()) {
mRequestPermissionListener.onSuccess();
return;
}
requestUnGrantedPermissions(permissions, requestCode);
}
private boolean needRequestRuntimePermissions() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
private void requestUnGrantedPermissions(String[] permissions, int requestCode) {
String[] unGrantedPermissions = findUnGrantedPermissions(permissions);
if (unGrantedPermissions.length == 0) {
mRequestPermissionListener.onSuccess();
return;
}
ActivityCompat.requestPermissions(mActivity, unGrantedPermissions, requestCode);
}
private boolean isPermissionGranted(String permission) {
return ActivityCompat.checkSelfPermission(mActivity, permission)
== PackageManager.PERMISSION_GRANTED;
}
private String[] findUnGrantedPermissions(String[] permissions) {
List<String> unGrantedPermissionList = new ArrayList<>();
for (String permission : permissions) {
if (!isPermissionGranted(permission)) {
unGrantedPermissionList.add(permission);
}
}
return unGrantedPermissionList.toArray(new String[0]);
}
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == mRequestCode) {
if (grantResults.length > 0) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
mRequestPermissionListener.onFailed();
return;
}
}
mRequestPermissionListener.onSuccess();
} else {
mRequestPermissionListener.onFailed();
}
}
}
public interface RequestPermissionListener {
void onSuccess();
void onFailed();
}
}
следующая методология о
- динамически запрашивать разрешения;
- отображение AlertDialog, если пользователь отрицает какие-либо разрешения
- цикл, пока пользователь не примет разрешения(ы)
создайте "статический" класс для методов разрешений
public class PermissionsUtil {
public static final int PERMISSION_ALL = 1;
public static boolean doesAppNeedPermissions(){
return android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1;
}
public static String[] getPermissions(Context context)
throws PackageManager.NameNotFoundException {
PackageInfo info = context.getPackageManager().getPackageInfo(
context.getPackageName(), PackageManager.GET_PERMISSIONS);
return info.requestedPermissions;
}
public static void askPermissions(Activity activity){
if(doesAppNeedPermissions()) {
try {
String[] permissions = getPermissions(activity);
if(!checkPermissions(activity, permissions)){
ActivityCompat.requestPermissions(activity, permissions,
PERMISSION_ALL);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
public static boolean checkPermissions(Context context, String... permissions){
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null &&
permissions != null) {
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission) !=
PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
}
В MainActivity.java
private void checkPermissions(){
PermissionsUtil.askPermissions(this);
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PermissionsUtil.PERMISSION_ALL: {
if (grantResults.length > 0) {
List<Integer> indexesOfPermissionsNeededToShow = new ArrayList<>();
for(int i = 0; i < permissions.length; ++i) {
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
indexesOfPermissionsNeededToShow.add(i);
}
}
int size = indexesOfPermissionsNeededToShow.size();
if(size != 0) {
int i = 0;
boolean isPermissionGranted = true;
while(i < size && isPermissionGranted) {
isPermissionGranted = grantResults[indexesOfPermissionsNeededToShow.get(i)]
== PackageManager.PERMISSION_GRANTED;
i++;
}
if(!isPermissionGranted) {
showDialogNotCancelable("Permissions mandatory",
"All the permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
checkPermissions();
}
});
}
}
}
}
}
}
private void showDialogNotCancelable(String title, String message,
DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setCancelable(false)
.create()
.show();
}
мой подход основан на ответе Никса и, надеюсь, немного более пригоден для нескольких (столько, сколько необходимо, а не только два) разрешения. Он предлагает добавить класс PermissionsHelper с одной ответственностью:
import android.app.Activity;
import android.app.AlertDialog;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PermissionsHelper {
private static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 100; // any code you want.
public void checkAndRequestPermissions(Activity activity, String... permissions) {
List<String> listPermissionsNeeded = new ArrayList<>();
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(permission);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(activity, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
}
}
public void onRequestPermissionsResult(Activity activity, int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
for (String permission : permissions) {
perms.put(permission, PackageManager.PERMISSION_GRANTED);
}
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
boolean allPermissionsGranted = true;
for (String permission1 : permissions) {
allPermissionsGranted = allPermissionsGranted && (perms.get(permission1) == PackageManager.PERMISSION_GRANTED);
}
if (allPermissionsGranted) {
Log.d(PermissionsHelper.class.getSimpleName(), "onRequestPermissionsResult: all permissions granted");
} else {
for (String permission2 : perms.keySet())
if (perms.get(permission2) == PackageManager.PERMISSION_GRANTED)
perms.remove(permission2);
StringBuilder message = new StringBuilder("The app has not been granted permissions:\n\n");
for (String permission : perms.keySet()) {
message.append(permission);
message.append("\n");
}
message.append("\nHence, it cannot function properly." +
"\nPlease consider granting it this permission in phone Settings.");
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(R.string.permission_required)
.setMessage(message)
.setPositiveButton(android.R.string.ok, (dialog, id) -> dialog.cancel());
AlertDialog alert = builder.create();
alert.show();
}
}
}
}
}
}
Если один или несколько необходимых разрешений не были предоставлены пользователем, ему будет показано подробное сообщение AlertDialog.
пример использования в работе:
private PermissionsHelper permissionsHelper;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkPermissions();
//any other code
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
permissionsHelper.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
private void checkPermissions() {
permissionsHelper = new PermissionsHelper();
permissionsHelper.checkAndRequestPermissions(this,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION);
}
надеюсь, что это будет полезно для кто-то.
проверка любой ситуации
Если отказано-отображение диалога оповещения пользователю, почему нам нужно разрешение
public static final int MULTIPLE_PERMISSIONS = 1;
public static final int CAMERA_PERMISSION_REQUEST_CODE = 2;
public static final int STORAGE_PERMISSION_REQUEST_CODE = 3;
private void askPermissions() {
int permissionCheckStorage = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
int permissionCheckCamera = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA);
// we already asked for permisson & Permission granted, call camera intent
if (permissionCheckStorage == PackageManager.PERMISSION_GRANTED && permissionCheckCamera == PackageManager.PERMISSION_GRANTED) {
launchCamera();
} //asking permission for the first time
else if (permissionCheckStorage != PackageManager.PERMISSION_GRANTED && permissionCheckCamera != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
MULTIPLE_PERMISSIONS);
} else {
// Permission denied, so request permission
// if camera request is denied
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need to give permission to take pictures in order to work this feature.");
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.setPositiveButton("GIVE PERMISSION", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
// Show permission request popup
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_PERMISSION_REQUEST_CODE);
}
});
builder.show();
} // if storage request is denied
else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need to give permission to access storage in order to work this feature.");
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.setPositiveButton("GIVE PERMISSION", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
// Show permission request popup
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
STORAGE_PERMISSION_REQUEST_CODE);
}
});
builder.show();
}
}
}
Проверка Результатов Разрешения
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case CAMERA_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.CAMERA)) {
// check whether camera permission granted or not.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
}
}
break;
case STORAGE_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// check whether storage permission granted or not.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
}
}
break;
case MULTIPLE_PERMISSIONS:
if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.CAMERA) && permissions[1].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// check whether All permission granted or not.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
}
}
break;
default:
break;
}
}
вы можете просто скопировать и вставить этот код, он отлично работает. изменить контекст (это) и разрешения в соответствии с вами.
Я успешно реализовал простой код для нескольких разрешений сразу. Выполните следующие действия 1:Утилита Make.класс java, как показано ниже
public class Utility {
public static final int MY_PERMISSIONS_REQUEST = 123;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static boolean checkPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE,Manifest.permission.GET_ACCOUNTS}, MY_PERMISSIONS_REQUEST);
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE,Manifest.permission.GET_ACCOUNTS}, MY_PERMISSIONS_REQUEST);
}
return false;
}
}
}
return true;
}
}
2: Сейчас позвоню
boolean permissionCheck = Utility.checkPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE, Manifest.permission.GET_ACCOUNTS);
В вашей деятельности onCreate () или в соответствии с вашей логикой.
3: Теперь проверьте разрешение перед выполнением операции для конкретной задачи
if (permissionCheck) {
performTaskOperation();//this method what you need to perform
} else {
Toast.makeText(this, "Need permission ON.", Toast.LENGTH_SHORT).show();
}
4: Теперь реализуйте метод onRequestPermissionsResult () в своей деятельности, как показано ниже
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case Utility.MY_PERMISSIONS_REQUEST:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (userChoosenTask.equals("STORAGE"))
performTaskOperation();//this method what you need to perform
}
break;
}
}
после просмотра всех длинных и сложных ответов. Я хочу опубликовать этот ответ.
RxPermission широко используется библиотека теперь для запроса разрешения в одной строке кода.
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
.request(Manifest.permission.CAMERA,
Manifest.permission.READ_PHONE_STATE)
.subscribe(granted -> {
if (granted) {
// All requested permissions are granted
} else {
// At least one permission is denied
}
});
добавить в свой build.gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}
разве это не легко?
см. эту ссылку для полного понимания нескольких разрешений, а также полной загрузки исходного кода, нажмите здесь
private boolean checkAndRequestPermissions() {
int permissionReadPhoneState = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
int permissionProcessOutGogingCalls = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS);
int permissionProcessReadContacts = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
int permissionProcessReadCallLog = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG);
int permissionWriteStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int permissionReadStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionReadPhoneState != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
}
if (permissionProcessOutGogingCalls != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
}
if (permissionProcessReadContacts != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CONTACTS);
}
if (permissionProcessReadCallLog != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CALL_LOG);
}
if (permissionWriteStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (permissionReadStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length == 0 || grantResults == null) {
/*If result is null*/
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/*If We accept permission*/
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
/*If We Decline permission*/
}
}
Я обнаружил, что это в Примере разрешений во время выполнения из GitHub Google.
private static String[] PERMISSIONS_CONTACT = {Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS};
private static final int REQUEST_CONTACTS = 1;
ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS);
проверьте раздел "запрос нескольких разрешений одновременно"в этой статье:
вещи, которые вам нужно знать о разрешениях Android M
Это очень хорошо объяснено, а также может коснуться других связанных тем, о которых вы не думали.
коротко и ясно :). во что я верю.
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; // List of permissions required
public void askPermission()
{
for (String permission : PERMISSIONS) {
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(PERMISSIONS, PERMISSION_ALL);
return;
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case 1:{
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
//Do your work.
} else {
Toast.makeText(this, "Until you grant the permission, we cannot proceed further", Toast.LENGTH_SHORT).show();
}
return;
}
}
используйте помощник, как это (имена разрешений не имеют значения).
public class MyPermission {
private static final int PERMISSION_REQUEST_ALL = 127;
private MainActivity mMainActivity;
MyPermission(MainActivity mainActivity) {
mMainActivity = mainActivity;
}
public static boolean hasPermission(String permission, Context context) {
if (isNewPermissionModel()) {
return (ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED);
}
return true;
}
private static boolean hasPermissions(Context context, String... permissions) {
if (isNewPermissionModel() && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
private static boolean shouldShowRationale(Activity activity, String permission) {
return isNewPermissionModel() && ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
}
private static boolean isNewPermissionModel() {
return VERSION.SDK_INT > VERSION_CODES.LOLLIPOP_MR1;
}
/**
* check all permissions
*/
void checkAll() {
//check dangerous permissions, make request if need (Android will ask only for the ones it needs)
String[] PERMISSIONS = {
permission.READ_CALENDAR,
permission.ACCESS_COARSE_LOCATION
};
if (!hasPermissions(mMainActivity, PERMISSIONS)) {
ActivityCompat.requestPermissions(mMainActivity, PERMISSIONS, PERMISSION_REQUEST_ALL);
}
}
void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_ALL) {
if (grantResults.length > 0) {
//for not granted
for (int i = 0; i < permissions.length; i++) {
if (permissions[i].equals(permission.READ_CALENDAR)) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
smartRequestPermissions(permission.READ_CALENDAR, R.string.permission_required_dialog_read_calendar);
}
} else if (permissions[i].equals(permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
smartRequestPermissions(permission.ACCESS_COARSE_LOCATION, R.string.permission_required_dialog_access_coarse_location);
}
}
}
}
}
}
private void smartRequestPermissions(final String permissionName, int permissionRequiredDialog) {
if (shouldShowRationale(mMainActivity, permissionName)) {// If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false.
//Show an explanation to the user with action
mMainActivity.mSnackProgressBarManager.show(
new SnackProgressBar(
SnackProgressBar.TYPE_ACTION, mMainActivity.getString(permissionRequiredDialog)
)
.setAction("OK", new OnActionClickListener() {
@Override
public void onActionClick() {
checkAll();
}
})
.setSwipeToDismiss(true).setAllowUserInput(true)
, MainActivity.SNACKBAR_WARNING_DURATION
);
} // else do nothing
}
}
простой способ задать несколько разрешений,
https://github.com/sachinvarma/EasyPermission
Как добавить :
repositories {
maven { url "https://jitpack.io" }
}
implementation 'com.github.sachinvarma:EasyPermission:1.0.1'
Как спросить разрешение:
List<String> permission = new ArrayList<>();
permission.add(EasyPermissionList.READ_EXTERNAL_STORAGE);
permission.add(EasyPermissionList.ACCESS_FINE_LOCATION);
new EasyPermissionInit(MainActivity.this, permission);
подробнее - >
Это может помочь кому-то в будущем.
Я просто использую массив для достижения нескольких запросов, надеюсь, что это поможет кому-то. (Котлин)
// got all permission
private fun requestPermission(){
var mIndex: Int = -1
var requestList: Array<String> = Array(10, { "" } )
// phone call Permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.CALL_PHONE
}
// SMS Permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.SEND_SMS
}
// Access photos Permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.READ_EXTERNAL_STORAGE
}
// Location Permission
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.ACCESS_FINE_LOCATION
}
if(mIndex != -1){
ActivityCompat.requestPermissions(this, requestList, PERMISSIONS_REQUEST_ALL)
}
}
// permission response
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
PERMISSIONS_REQUEST_ALL -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Phone Call permission accept.")
}
// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "SMS permission accept.")
}
// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "SMS permission accept.")
}
// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Location permission accept.")
}
} else {
Toast.makeText(mContext, "Permission Failed!", Toast.LENGTH_LONG).show()
}
return
}
}
}
нет ничего плохого в ответах на запрос нескольких разрешений, но код результата множественного разрешения не реализован очень элегантно и может вызвать проверку неправильного результата разрешения.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
ужасная логика для проверки результата нескольких разрешений, я не знаю, почему Google реализовал такой ужасный код.
это беспорядок, особенно когда вы проверяете несколько разрешений. Пусть говорят, что вы просите CAMERA
, ACCESS_FINE_LOCATION
и ACCESS_NETWORK_STATE
.
вы нужно проверить на ACCESS_FINE_LOCATION
но пользователь только предоставил CAMERA
при первом запуске и проверке grantResults[1]
но во втором запуске ACCESS_FINE_LOCATION
становится разрешением с индексом 0. У меня так много проблем с пользователем, не предоставляющим все разрешения сразу, и мне нужно написать логику результата бессмысленного разрешения.
вы должны использовать
int size = permissions.length;
boolean locationPermissionGranted = false;
for (int i = 0; i < size; i++) {
if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)
&& grantResults[i] == PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true;
}
}
или проще один
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
// Do something ...
}
на onPermissionRequestResult
метод.