Android 6.0 런타임 사용 권한 상세 정보
android.permission.ACCESS LOCATIONEXTRA_COMMANDS
android.permission.ACCESS NETWORKSTATE
android.permission.ACCESS NOTIFICATIONPOLICY
android.permission.ACCESS WIFISTATE
android.permission.ACCESS WIMAXSTATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE NETWORKSTATE
android.permission.CHANGE WIFIMULTICAST_STATE
android.permission.CHANGE WIFISTATE
android.permission.CHANGE WIMAXSTATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND STATUSBAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET PACKAGESIZE
android.permission.INTERNET
android.permission.KILL BACKGROUNDPROCESSES
android.permission.MODIFY AUDIOSETTINGS
android.permission.NFC
android.permission.READ SYNCSETTINGS
android.permission.READ SYNCSTATS
android.permission.RECEIVE BOOTCOMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST INSTALLPACKAGES
android.permission.SET TIMEZONE
android.permission.SET_WALLPAPER
android.permission.SET WALLPAPERHINTS
android.permission.SUBSCRIBED FEEDSREAD
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE SYNCSETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
일반 권한은 필요할 때 명세서 파일에 설명하기만 하면 됩니다.위험 권한은 명세서 파일에 명시해야 하는 것 외에 코드에서 동태적으로 판단 신청을 해야 한다.위험 권한은 다음과 같습니다.
android.permission.READ_CALENDAR
android.permission.WRITE_CALENDAR
android.permission-group.CAMERA
android.permission.CAMERA
android.permission-group.CONTACTS
android.permission.READ_CONTACTS
android.permission.WRITE_CONTACTS
android.permission.GET_ACCOUNTS
android.permission-group.LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
android.permission-group.MICROPHONE
android.permission.RECORD_AUDIO
android.permission-group.PHONE
android.permission.READ_PHONE_STATE
android.permission.CALL_PHONE
android.permission.READ_CALL_LOG
android.permission.WRITE_CALL_LOG
com.android.voicemail.permission.ADD_VOICEMAIL
android.permission.USE_SIP
android.permission.PROCESS_OUTGOING_CALLS
android.permission-group.SENSORS
android.permission.BODY_SENSORS
android.permission-group.SMS
android.permission.SEND_SMS
android.permission.RECEIVE_SMS
android.permission.READ_SMS
android.permission.RECEIVE_WAP_PUSH
android.permission.RECEIVE_MMS
android.permission.READ_CELL_BROADCASTS
android.permission-group.STORAGE
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
위험 권한은 그룹별로 나뉘는데 각 그룹에서 특정한 권한이 허용되거나 거부되면 같은 그룹의 다른 권한도 상응하는 자동으로 허용되거나 거부된다.targetSdkVersion이 23보다 크면 우리가 위험 권한을 사용할 때 이러한 논리에 따라 처리해야 한다.
먼저 현재 응용 프로그램이 권한이 있는지 판단하고 없으면 신청한다. 사용자가 허락하거나 거절한 후에 해당하는 방법을 리셋하고 우리는 리셋에서 자신의 논리를 처리한다.
단일 권한 신청
Activity/Fragment에서 권한이 있는지 판단하는 방법은 checkSelfPermission()이고, 권한을 신청하는 방법은 RequestPermissions()이며, 사용자가 허락하거나 거절하면 리셋 방법인 onRequestPermissionsResult()이다.
Activity/Fragment에서 이러한 방법을 제공했지만 만약에 우리가 이런 방법을 사용한다면 안드로이드 버전이 23보다 큰지 아닌지를 판단하려면 코드는 다음과 같다.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ // }else{ // }
구글 엔지니어는 당연히 이런 것들을 고려하여 개발자에게 호환 패키지를 제공하고Activity/Fragment에서ContextCompat을 사용한다.checkSelfPermission()이 권한이 있는지 여부를 판단합니다.Activity에서 Activity Compat을 사용합니다.requestPermissions() 요청 권한Fragment에서 직접 RequestPermissions()로 권한을 요청하고 앞에ActivityCompat을 붙이지 마십시오. 그렇지 않으면 Fragment가 있는Activity의 리셋 방법을 리셋합니다.Activity/Fragment에서 사용자가 권한을 허용하거나 거부한 후에 onRequestPermissionsResult () 방법을 되돌려줍니다.다음은 일반적인 시스템 카메라 사진 기능을 호출하는 코드입니다.
private void takePhoto() {
Intent photoIn = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(photoIn, TAKE_PHOTO_REQUEST);
}
프로젝트 targetSdkVersion이 23보다 크면 동적 요청 권한이 필요합니다.
if (ContextCompat.checkSelfPermission(MySetupActivity.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MySetupActivity.this,new String[]{Manifest.permission.CAMERA}, 100);
} else {
takePhoto();
}
권한이 있는지 아닌지를 먼저 판단하고 관련 코드를 직접 집행하는 것이 있으면 권한을 신청한다.사용자가 허용 또는 거부 권한을 클릭하면 onRequestPermissionsResult 메서드가 리콜되고 이 메서드에서 처리됩니다.
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 100) {//
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takePhoto();
} else {
// Permission Denied
AlertDialog mDialog = new AlertDialog.Builder(MySetupActivity.this)
.setTitle(" ")
.setMessage(" , !")
.setPositiveButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ShowAppSetDetails.showInstalledAppDetails(MySetupActivity.this, "user.zhuku.com");
LogPrint.logILsj(TAG, " ");
}
})
.setCancelable(true)
.create();
mDialog.show();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
사용자가 권한을 허락한 후에 우리는 관련 코드를 직접 실행하고 거부하면 사용자에게 탄창 알림이 권한을 열어야 하는지 여부를 알립니다.그중의
ShowAppSetDetails.showInstalledAppDetails(MySetupActivity.this, "user.zhuku.com");
현재 app 정보 설정 인터페이스를 여는 코드입니다.구체적인 코드는 다음과 같습니다.
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
/**
* : “ ”
* :Li Shengjie
* :2016/11/25 1:40
* :Li Shengjie
* :2016/11/25 1:40
* :
*/
public class ShowAppSetDetails {
private static final String SCHEME = "package";
/**
* InstalledAppDetails Extra ( Android 2.1 )
*/
private static final String APP_PKG_NAME_21 = "com.android.settings.ApplicationPkgName";
/**
* InstalledAppDetails Extra ( Android 2.2)
*/
private static final String APP_PKG_NAME_22 = "pkg";
/**
* InstalledAppDetails
*/
private static final String APP_DETAILS_PACKAGE_NAME = "com.android.settings";
/**
* InstalledAppDetails
*/
private static final String APP_DETAILS_CLASS_NAME = "com.android.settings.InstalledAppDetails";
/**
* InstalledAppDetails 。 Android 2.3(Api Level
* 9) , SDK ; 2.3 , ( InstalledAppDetails )。
*
* @param context
* @param packageName
*/
public static void showInstalledAppDetails(Context context, String packageName) {
Intent intent = new Intent();
final int apiLevel = Build.VERSION.SDK_INT;
if (apiLevel >= 9) { // 2.3(ApiLevel 9) , SDK
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts(SCHEME, packageName, null);
intent.setData(uri);
} else { // 2.3 , ( InstalledAppDetails )
// 2.2 2.1 ,InstalledAppDetails APP_PKG_NAME 。
final String appPkgName = (apiLevel == 8 ? APP_PKG_NAME_22
: APP_PKG_NAME_21);
intent.setAction(Intent.ACTION_VIEW);
intent.setClassName(APP_DETAILS_PACKAGE_NAME,
APP_DETAILS_CLASS_NAME);
intent.putExtra(appPkgName, packageName);
}
context.startActivity(intent);
}
}
앱이 권한을 신청할 때 사용자가'더 이상 알리지 않음'을 클릭하면 거부 권한을 직접 리셋해 구글 엔지니어에게 shouldshow Request Permission Rationale() 방법을 제공한다.
호환성 패키지의 방법은 Activity Compat입니다.shouldshow RequestPermissionRationale (), Fragment에서 사용하려면 shouldshow RequestPermissionRationale () 를 직접 사용하십시오.
ActivityCompat.shouldshow RequestPermissionRationale () 방법의 반환값은boolean 형식입니다. 첫 번째 권한을 신청할 때false로 되돌아갑니다. 사용자가 '알림 안 하기' 를 누르면true로 되돌아갑니다.세부 코드는 다음과 같습니다.
if (ContextCompat.checkSelfPermission(MySetupActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(MySetupActivity.this, Manifest.permission.CAMERA)) {
//
mDialog = new AlertDialog.Builder(MySetupActivity.this)
.setTitle(" ")
.setMessage(" , , ?")
.setPositiveButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ActivityCompat.requestPermissions(MySetupActivity.this,
new String[]{Manifest.permission.CAMERA},
100);
}
})
.setNegativeButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.setCancelable(true)
.create();
mDialog.show();
} else {
ActivityCompat.requestPermissions(MySetupActivity.this,
new String[]{Manifest.permission.CAMERA},
100);
}
} else {
takePhoto();
}
Fragment의 경우 코드는 다음과 같습니다.
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
//
mDialog = new AlertDialog.Builder(getContext())
.setTitle(" ")
.setMessage(" , , ?")
.setPositiveButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
requestPermissions(new String[]{Manifest.permission.CAMERA},
PERMISSIONS_CAMERA);
}
})
.setNegativeButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.setCancelable(true)
.create();
mDialog.show();
} else {
requestPermissions(new String[]{Manifest.permission.CAMERA},
PERMISSIONS_CAMERA);
}
} else {
selectPicFromCamera();
}
특히 Fragment에서 권한을 요청하면Activity에서도 onRequestPermissionsResult () 를 다시 썼다면 onRequestPermissionsResult () 방법에는 반드시 슈퍼를 써야 합니다.onRequestPermissionsResult(requestCode, permissions, grantResults);이 코드는 쓰지 않으면 Activity에서 Fragment를 실행하는 권한 리셋 방법을 나누어 주지 않습니다.
Fragment에서 RequestPermissions() 소스는 다음과 같습니다.
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
mHost.onRequestPermissionsFromFragment(this, permissions, requestCode);
}
사실 Fragment 요청 권한도 Activity에서 요청한 것이고, 리셋 결과를 Fragment에 전달했을 뿐이다.
한 번에 여러 권한 신청
예를 들어 요청할 권한은 다음과 같습니다.
/**
*
*/
protected String[] permissionList = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
};
우리는 먼저 모든 권한이 이미 허락되었거나 거부되었는지 판단해야 한다. 어떤 권한이 허락되지 않았을 때, 허락되지 않은 권한을 신청해야 한다.
protected void onStart() {
super.onStart();
if (PermissionUtils.checkSelfPermission(SplashActivity.this, permissionList)) {
PermissionUtils.checkPermissions(this, 0, permissionList);
} else {
//
}
}
여기서 PermissionUtils 클래스의 코드는 다음과 같습니다.
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import java.util.ArrayList;
import java.util.List;
public class PermissionUtils {
/**
*
*/
public static void checkPermissions(Activity activity, int permissRequestCode, String... permissions) {
List needRequestPermissonList = findDeniedPermissions(activity, permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
ActivityCompat.requestPermissions(activity,
needRequestPermissonList.toArray(
new String[needRequestPermissonList.size()]),
permissRequestCode);
}
}
/**
*
*/
public static List findDeniedPermissions(Activity activity, String[] permissions) {
List needRequestPermissonList = new ArrayList();
for (String perm : permissions) {
if (ContextCompat.checkSelfPermission(activity,
perm) != PackageManager.PERMISSION_GRANTED) {
needRequestPermissonList.add(perm);
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(
activity, perm)) {
needRequestPermissonList.add(perm);
}
}
}
return needRequestPermissonList;
}
public static boolean checkSelfPermission(Context context, String[] permissions) {
for (String perm : permissions) {
if (ContextCompat.checkSelfPermission(context, perm) != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
public static boolean checkSelfResult(int[] grantResults) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
}
onRequestPermissionsResult 콜백 방법에서는 다음과 같이 처리됩니다.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 0) {
if (PermissionUtils.checkSelfResult(grantResults)) {
// Permission Granted
//
} else {
// Permission Denied
if (null == mDialog)
mDialog = new AlertDialog.Builder(SplashActivity.this)
.setTitle(" ")
.setMessage(" , !")
.setPositiveButton(" ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ShowAppSetDetails.showInstalledAppDetails(SplashActivity.this, "user.zhuku.com");
LogPrint.logILsj(TAG, " ");
}
})
.setCancelable(false)
.create();
if (!mDialog.isShowing()) {
mDialog.show();
}
}
}
}
만약 프로젝트가 페이지에 보일 때 권한 신청을 해야 한다면, onStart () 방법에 넣고, onResume () 에 쓰지 마십시오.onResume () 에 쓰여 있으면 사용자가 권한에 동의하면 괜찮고, 거부를 클릭하면 권한 거부 방법을 되돌려줍니다. 이 때 시스템이 권한을 신청하는 대화상자가 사라지고, onResume () 요청 권한을 다시 호출해서 대화 상자를 표시합니다. 거부를 하면 onResume () 방법을 다시 호출하여 계속 순환합니다.시스템에서 권한을 요청하는 대화 상자가 한 번에 Activity 를 열었기 때문입니다.부분 소스는 다음과 같습니다.
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
if (mHasCurrentPermissionsRequest) {
Log.w(TAG, "Can reqeust only one set of permissions at a time");
// Dispatch the callback with empty arrays which means a cancellation.
onRequestPermissionsResult(requestCode, new String[0], new int[0]);
return;
}
Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
mHasCurrentPermissionsRequest = true;
}
이 블로그는 오리지널로vitamio에서 유래한 것으로 전재는 출처를 밝혀 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.