Android Developer Documentation给出了在运行时请求权限的示例:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
此示例中的“MY_PERMISSIONS_REQUEST_READ_CONTACTS”是什么?它说这是一个app定义的int常量,但这是否意味着我应该创建一个Constants.java并声明一个公共的静态int?价值应该是什么?
在其他示例中,我看到人们在这里使用1,或0或0xFFEEDDCC,但我无法找到它的解释。有人可以向我解释一下需要去哪里以及为什么? (在我的情况下,我需要确保应用程序有权访问正确的位置)
ActivityCompat文档说“应用程序特定的请求代码与报告给onRequestPermissionsResult的结果相匹配”?这对我没有帮助。
答案 0 :(得分:19)
什么是" MY_PERMISSIONS_REQUEST_READ_CONTACTS"在这个例子中?
将int
个特定呼叫与相应的requestPermissions()
回调联系起来onRequestPermissionsResult()
。
在幕后,requestPermissions()
使用startActivityForResult()
;此int
与startActivityForResult()
中的角色相同。
这是否意味着我应该创建一个Constants.java并声明一个public static int?
我只想在活动中将其设为private static final int
。但是,您可以在任何地方声明它。
价值应该是什么?
我似乎记得它需要低于0x8000000,否则它可以是你想要的任何东西。您在活动中为每个requestPermissions()
调用使用的值应该是不同的int
,但实际数字并不重要。
如果您的活动只有一次requestPermissions()
来电,则int
值无关紧要。但是,许多应用会在一项活动中进行多次requestPermissions()
次调用。在这种情况下,开发人员可能需要在onRequestPermissionsResult()
中知道这是什么请求。
答案 1 :(得分:2)
在&#34下的文档中稍微向下看一下;处理权限请求响应"你会看到它的目的。
一个名为onRequestPermissionsResult
的回调方法被发送回与参数相同的代码,因此您知道正在请求/授予哪个权限:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
由于您只使用常量,因此您可以将其作为public static final int
赋予它任何值。请求的每个权限都需要自己的常量。
答案 2 :(得分:1)
我查看了所有答案,但没有满足我确切需要的答案,因此,这是我编写并可以正常使用的示例,即使用户单击不再询问复选框。 / p>
创建一个方法,当您想请求运行时权限时将调用该方法,例如readContacts()
,或者也可以拥有openCamera()
,如下所示:
private void readContacts() {
if (!askContactsPermission()) {
return;
} else {
queryContacts();
} }
现在我们需要输入askContactsPermission()
,您也可以将其命名为askCameraPermission()
或您要询问的任何权限。
private boolean askContactsPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
return true;
}
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
Snackbar.make(parentLayout, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(android.R.string.ok, new View.OnClickListener() {
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
}).show();
} else if (contactPermissionNotGiven) {
openPermissionSettingDialog();
} else {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
contactPermissionNotGiven = true;
}
return false;
}
在编写此函数之前,请确保已定义如下实例变量:
private View parentLayout;
private boolean contactPermissionNotGiven;;
/**
* Id to identity READ_CONTACTS permission request.
*/
private static final int REQUEST_READ_CONTACTS = 0;
现在是覆盖onRequestPermissionsResult
方法的最后一步,如下所示:
/**
* Callback received when a permissions request has been completed.
*/
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
queryContacts();
}
}
}
在这里,我们已完成运行时权限,附加项为openPermissionSettingDialog()
,如果用户通过单击不再询问复选框永久禁用了权限,则只需打开“设置”屏幕即可。下面是方法:
private void openPermissionSettingDialog() {
String message = getString(R.string.message_permission_disabled);
AlertDialog alertDialog =
new AlertDialog.Builder(MainActivity.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setMessage(message)
.setPositiveButton(getString(android.R.string.ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
dialog.cancel();
}
}).show();
alertDialog.setCanceledOnTouchOutside(true);
}
我们错过了什么?
1.在strings.xml
<string name="permission_rationale">"Contacts permissions are needed to display Contacts."</string>
<string name="message_permission_disabled">You have disabled the permissions permanently,
To enable the permissions please go to Settings -> Permissions and enable the required Permissions,
pressing OK you will be navigated to Settings screen</string>
在parentLayout
方法中初始化onCreate
变量
parentLayout = findViewById(R.id.content);
在AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
queryContacts
方法,根据您的需要或运行时权限,您可以在需要permission
之前调用您的方法。就我而言,我只是使用加载程序来获取联系人,如下所示:
private void queryContacts() {
getLoaderManager().initLoader(0, null, this);}
这很不错,编码很愉快:)
答案 3 :(得分:0)
public class SplashActivity extends RuntimePermissionsActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
SplashActivity.super.requestAppPermissions(new
String[]{android.Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, R.string.app_name
, 20);
}
@Override
public void onPermissionsGranted(int requestCode) {
try {
TelephonyManager tele = (TelephonyManager) getApplicationContext()
.getSystemService(Context.TELEPHONY_SERVICE);
String imei =tele.getDeviceId()
} catch (Exception e) {
e.printStackTrace();
}
}
public abstract class RuntimePermissionsActivity extends AppCompatActivity {
private SparseIntArray mErrorString;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mErrorString = new SparseIntArray();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
int permissionCheck = PackageManager.PERMISSION_GRANTED;
for (int permission : grantResults) {
permissionCheck = permissionCheck + permission;
}
if ((grantResults.length > 0) && permissionCheck == PackageManager.PERMISSION_GRANTED) {
onPermissionsGranted(requestCode);
} else {
finish();
}
}
public void requestAppPermissions(final String[] requestedPermissions,
final int stringId, final int requestCode) {
mErrorString.put(requestCode, stringId);
int permissionCheck = PackageManager.PERMISSION_GRANTED;
boolean shouldShowRequestPermissionRationale = false;
for (String permission : requestedPermissions) {
permissionCheck = permissionCheck + ContextCompat.checkSelfPermission(this, permission);
shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale || ActivityCompat.shouldShowRequestPermissionRationale(this, permission);
}
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale) {
ActivityCompat.requestPermissions(RuntimePermissionsActivity.this, requestedPermissions, requestCode);
/*Snackbar.make(findViewById(android.R.id.content), stringId,
Snackbar.LENGTH_INDEFINITE).setAction("GRANT",
new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(RuntimePermissionsActivity.this, requestedPermissions, requestCode);
}
}).show();*/
} else {
ActivityCompat.requestPermissions(this, requestedPermissions, requestCode);
}
} else {
onPermissionsGranted(requestCode);
}
}
public abstract void onPermissionsGranted(int requestCode);
}