首先,我會給你風險的權限列表中版本的Android M版及更高版本
然後給你舉例如何在版本的Android M和許可申請後來版本號爲。
請求用戶WRITE_EXTERNAL_STORAGE權限。
首先在你的Android menifest文件添加權限
步驟1申報requestcode
private static String TAG = "PermissionDemo";
private static final int REQUEST_WRITE_STORAGE = 112;
步驟2當你想詢問用戶是否允許添加該代碼
//ask for the permission in android M
int permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission to record denied");
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Permission to access the SD-CARD is required for this app to Download PDF.")
.setTitle("Permission required");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.i(TAG, "Clicked");
makeRequest();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
makeRequest();
}
}
protected void makeRequest() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
}
步驟3添加替代方法請
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_WRITE_STORAGE: {
if (grantResults.length == 0
|| grantResults[0] !=
PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission has been denied by user");
} else {
Log.i(TAG, "Permission has been granted by user");
}
return;
}
}
}
注:不要忘了在menifest文件中添加權限
BEST下面的例子具有多項權限PLUS覆蓋所有情景
我添加評論,以便您可以輕鬆理解。
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.production.hometech.busycoder.R;
import java.util.ArrayList;
public class PermissionInActivity extends AppCompatActivity implements View.OnClickListener {
private static final int REQUEST_PERMISSION_SETTING = 99;
private Button bt_camera;
private static final String[] PARAMS_TAKE_PHOTO = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private static final int RESULT_PARAMS_TAKE_PHOTO = 11;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission_in);
bt_camera = (Button) findViewById(R.id.bt_camera);
bt_camera.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_camera:
takePhoto();
break;
}
}
/**
* shouldShowRequestPermissionRationale() = This will return true if the user had previously declined to grant you permission
* NOTE : that ActivityCompat also has a backwards-compatible implementation of
* shouldShowRequestPermissionRationale(), so you can avoid your own API level
* checks.
* <p>
* shouldShowRequestPermissionRationale() = returns false if the user declined the permission and checked the checkbox to ask you to stop pestering the
* user.
* <p>
* requestPermissions() = request for the permisssiion
*/
private void takePhoto() {
if (canTakePhoto()) {
Toast.makeText(this, "You can take PHOTO", Toast.LENGTH_SHORT).show();
} else if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "You should give permission", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, netPermisssion(PARAMS_TAKE_PHOTO), RESULT_PARAMS_TAKE_PHOTO);
} else {
ActivityCompat.requestPermissions(this, netPermisssion(PARAMS_TAKE_PHOTO), RESULT_PARAMS_TAKE_PHOTO);
}
}
// This method return permission denied String[] so we can request again
private String[] netPermisssion(String[] wantedPermissions) {
ArrayList<String> result = new ArrayList<>();
for (String permission : wantedPermissions) {
if (!hasPermission(permission)) {
result.add(permission);
}
}
return (result.toArray(new String[result.size()]));
}
private boolean canTakePhoto() {
return (hasPermission(Manifest.permission.CAMERA) && hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
}
/**
* checkSelfPermission() = you can check if you have been granted a runtime permission or not
* ex = ContextCompat.checkSelfPermission(this,permissionString)== PackageManager.PERMISSION_GRANTED
* <p>
* ContextCompat offers a backwards-compatible implementation of checkSelfPermission(), ActivityCompat offers a backwards-compatible
* implementation of requestPermissions() that you can use.
*
* @param permissionString
* @return
*/
private boolean hasPermission(String permissionString) {
return (ContextCompat.checkSelfPermission(this, permissionString) == PackageManager.PERMISSION_GRANTED);
}
/**
* requestPermissions() action goes to onRequestPermissionsResult() whether user can GARNT or DENIED those permisssions
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RESULT_PARAMS_TAKE_PHOTO) {
if (canTakePhoto()) {
Toast.makeText(this, "You can take picture", Toast.LENGTH_SHORT).show();
} else if (!(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
final AlertDialog.Builder settingDialog = new AlertDialog.Builder(PermissionInActivity.this);
settingDialog.setTitle("Permissioin");
settingDialog.setMessage("Now you need to enable permisssion from the setting because without permission this app won't run properly \n\n goto -> setting -> appInfo");
settingDialog.setCancelable(false);
settingDialog.setPositiveButton("Setting", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
Toast.makeText(getBaseContext(), "Go to Permissions to Grant all permission ENABLE", Toast.LENGTH_LONG).show();
}
});
settingDialog.show();
Toast.makeText(this, "You need to grant permission from setting", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_PERMISSION_SETTING) {
if (canTakePhoto()) {
Toast.makeText(this, "You can take PHOTO", Toast.LENGTH_SHORT).show();
}
}
}
}
的配置更改特例
這可能是用戶將旋轉設備或其他觸發配置變化,而我們的權限對話框是在前景。由於我們的活動在該對話框中仍然可見,因此我們會被銷燬並重新創建......但我們不想再次重新提高權限對話框。
這就是爲什麼我們有一個名爲isInPermission的布爾值,它跟蹤我們是否正在請求權限 。我們守住該值在 onSaveInstanceState()
:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_IN_PERMISSION, isInPermission);
}
我們它onCreate()
恢復。如果我們沒有保留所有期望的權限,但isInPermission爲true,則我們跳過請求權限,因爲我們已經在 的中間。
你可以發佈你的Logcat嗎? –
是你的'targetSdkVersion' 23嗎?還是早期版本? – ianhanniballake
logcat中沒有什麼異常,大概是因爲「錯誤」被應用程序困住了。 –
RudyF