我是Android新手,我遇到运行时权限问题。 我的应用程序读取手机的所有联系人并在列表中提取。问题是允许阅读手机的联系人。到目前为止,当我第一次打开我的应用程序时,应用程序崩溃,然后...请求允许阅读联系人。 当我再次打开它时,第二次我的应用程序出现任何问题。 所以问题是在崩溃前请求许可...... 我的主要活动是:
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CODE_ASK_PERMISSIONS = 123;
ReadContacts values = new ReadContacts();
@Override
protected void onCreate(Bundle savedInstanceState) {
// Readcontacts val = new Readcontacts();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get ListView object from xml
/*
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.READ_CONTACTS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
REQUEST_CODE_ASK_PERMISSIONS); }*/
final ListView listView = (ListView) findViewById(R.id.list);
final int frth = listView.getHeight();
ToggleButton toggle = (ToggleButton) findViewById(R.id.toggleButton9);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
for (int i = 0; i < listView.getChildCount(); i++) {
double max = 2 * 90;
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 72, r.getDisplayMetrics());
listView.getChildAt(i).setMinimumHeight((int) px);
}
// The toggle is enabled
} else {
// The toggle is disabled
for (int i = 0; i < listView.getChildCount(); i++) {
listView.getChildAt(i).setMinimumHeight(frth);
}
}
}
});
String[] values = new String[1000000];
int temp =0 ;
final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 225);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
} else {
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
values[temp] = name;
temp += 1;
}
phones.close();}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.row, R.id.text, values);
listView.setAdapter(adapter);
// Assign adapter to ListView
listView.setAdapter(adapter);
// ListView Item Click Listener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ListView Clicked item index
int itemPosition = position;
// ListView Clicked item value
String itemValue = (String) listView.getItemAtPosition(position);
// Show Alert
Toast.makeText(getApplicationContext(),
itemValue, Toast.LENGTH_LONG)
.show();
}
});
}
}
当然我已经通过添加
更改了我的清单<uses-permission android:name="android.permission.READ_CONTACTS" />
任何想法???
编辑: 我新的主动,但我的问题仍然存在......任何想法?
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CODE_ASK_PERMISSIONS = 123;
ReadContacts values = new ReadContacts();
@Override
protected void onCreate(Bundle savedInstanceState) {
// Readcontacts val = new Readcontacts();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get ListView object from xml
// Here, thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation 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(this,
new String[]{Manifest.permission.READ_CONTACTS},
REQUEST_CODE_ASK_PERMISSIONS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
/*
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.READ_CONTACTS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
REQUEST_CODE_ASK_PERMISSIONS); }*/
final ListView listView = (ListView) findViewById(R.id.list);
final int frth = listView.getHeight();
ToggleButton toggle = (ToggleButton) findViewById(R.id.toggleButton9);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
for (int i = 0; i < listView.getChildCount(); i++) {
double max = 2 * 90;
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 72, r.getDisplayMetrics());
listView.getChildAt(i).setMinimumHeight((int) px);
}
// The toggle is enabled
} else {
// The toggle is disabled
for (int i = 0; i < listView.getChildCount(); i++) {
listView.getChildAt(i).setMinimumHeight(frth);
}
}
}
});
String[] values = new String[1000000];
int temp =0 ;
//final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
// requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
// ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 225);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
//} else {
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
values[temp] = name;
temp += 1;
}
phones.close();//}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.row, R.id.text, values);
listView.setAdapter(adapter);
// Assign adapter to ListView
listView.setAdapter(adapter);
// ListView Item Click Listener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ListView Clicked item index
int itemPosition = position;
// ListView Clicked item value
String itemValue = (String) listView.getItemAtPosition(position);
// Show Alert
Toast.makeText(getApplicationContext(),
itemValue, Toast.LENGTH_LONG)
.show();
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS: {
// 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
}
}
}
错误是
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.serepasf.myapp4/com.example.serepasf.myapp4.MainActivity}: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{c638436 27660:com.example.serepasf.myapp4/u0a756} (pid=27660, uid=10756) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
答案 0 :(得分:0)
从Android 6.0(API级别23)开始,用户需要在应用运行时授予权限。
步骤-1 您需要通过实现此代码来检查是否在MAnifest中声明了权限:
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);
步骤-2 您可以向用户解释您为什么要请求这些权限。然后最后显示requestPermissions对话框。使用下面的代码编写逻辑。
// 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 explanation 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.
}
}
步骤-3-
现在将出现一个对话框,用户可以在该对话框中授予应用程序权限。用户的响应将传递给以下方法: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
}
}
您还可以查看官方文档:https://developer.android.com/training/permissions/requesting.html
我尝试的示例代码:
package com.karan.permissions;
import android.Manifest;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* @author karan
* @date 20/3/17
*/
public class MainActivity extends AppCompatActivity {
// Request code for READ_CONTACTS. It can be any number > 0.
private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
// The ListView
private ListView name_list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the list view
this.name_list = (ListView) findViewById(R.id.name_list);
// Read and show the contacts
showContacts();
}
/**
* Show the contacts in the ListView.
*/
private void showContacts() {
// Check the SDK version and whether the permission is already granted or not.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
} else {
// Android version is lesser than 6.0 or the permission is already granted.
List<String> contacts = getContactNames();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contacts);
name_list.setAdapter(adapter);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted
showContacts();
} else {
Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
}
}
}
/**
* Read the name of all the contacts.
*
* @return a list of names.
*/
private List<String> getContactNames() {
List<String> contacts = new ArrayList<>();
// Get the ContentResolver
ContentResolver cr = getContentResolver();
// Get the Cursor of all the contacts
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
// Move the cursor to first. Also check whether the cursor is empty or not.
if (cursor.moveToFirst()) {
// Iterate through the cursor
do {
// Get the contacts name
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contacts.add(name);
} while (cursor.moveToNext());
}
// Close the curosor
cursor.close();
return contacts;
}
}