我正在尝试使用日历运行时权限来获取日历的电子邮件ID。它在android版本6.1中完美运行。因此我开始在8.1版中进行测试。
安装该应用程序后,它将询问读取联系人的权限,而我询问了该权限,但是在尝试登录该应用程序时,它在logcat needs read contact permission
中输出了错误。我不明白为什么会这样。
我需要获取日历电子邮件ID,才能在Google日历中插入相同的数据。所以我正在尝试获得读取联系人的权限。
清单
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Permissioncheck.java
public class Permissioncheck extends AppCompatActivity
{
public static final int MY_PERMISSIONS_REQUEST_WRITE_CALENDAR = 123;
public static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 123;
public static int OVERLAY_PERMISSION_REQ_CODE_CHATHEAD = 1234;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
context = Permissioncheck.this;
boolean result = checkPermission();
if (result)
{
writeCalendarEvent();
}
}
private void writeCalendarEvent()
{
Log.d(Utils.LogTag, "lst_StartService -> Utils.canDrawOverlays(Main.this): " + Utils.canDrawOverlays(Permissioncheck.this));
if(Utils.canDrawOverlays(Permissioncheck.this))
{
checkPermission_Contact();
startService();
} else {
requestPermission(OVERLAY_PERMISSION_REQ_CODE_CHATHEAD);
}
}
public void startService()
{
boolean results = checkPermission_Contact();
if (results)
{
Intent k = new Intent(context, Login.class);
startActivity(k);
}
}
private void needPermissionDialog(final int requestCode)
{
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(Permissioncheck.this);
builder.setMessage("You need to allow permission");
builder.setPositiveButton("OK", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
requestPermission(requestCode);
}
});
builder.setNegativeButton("Cancel", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
}
});
builder.setCancelable(false);
builder.show();
}
@Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
}
private void requestPermission(int requestCode)
{
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, requestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OVERLAY_PERMISSION_REQ_CODE_CHATHEAD)
{
if (!Utils.canDrawOverlays(Permissioncheck.this))
{
needPermissionDialog(requestCode);
} else {
startService();
}
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public boolean checkPermission()
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, android.Manifest.permission.WRITE_CALENDAR)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity)context, new String[]{android.Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity)context, new String[]{android.Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public boolean checkPermission_Contact()
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_CONTACTS)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity)context, new String[]{android.Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
} return false;
} else {
return true;
}
} else {
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_CALENDAR:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
writeCalendarEvent();
} else {
//code for deny
}
break;
}
}
}
New_Schedule_Calendar.java //我在这里尝试获取日历电子邮件ID
int calenderId = -1;
String calenderEmaillAddress = possibleEmail;
String[] projection = new String[]{
CalendarContract.Calendars._ID,
CalendarContract.Calendars.ACCOUNT_NAME
};
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(Uri.parse("content://com.android.calendar/calendars"), projection, //here i am getting error
CalendarContract.Calendars.ACCOUNT_NAME + "=? and (" +
CalendarContract.Calendars.NAME + "=? or " +
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + "=?)",
new String[]{calenderEmaillAddress, calenderEmaillAddress,
calenderEmaillAddress}, null);
if (cursor.moveToFirst()) {
if (cursor.getString(1).equals(calenderEmaillAddress)) {
calenderId = cursor.getInt(0);
}
}
cal_id=calenderId;
logcat错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 6789
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.Schedule_Delete}: java.lang.SecurityException: Permission Denial: reading com.android.providers.calendar.CalendarProvider2 uri content://com.android.calendar/calendars from pid=6789, uid=10212 requires android.permission.READ_CALENDAR, or grantUriPermission()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2974)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3059)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1724)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.calendar.CalendarProvider2 uri content://com.android.calendar/calendars from pid=6789, uid=10212 requires android.permission.READ_CALENDAR, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:2021)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:418)
at android.content.ContentResolver.query(ContentResolver.java:760)
at android.content.ContentResolver.query(ContentResolver.java:710)
at android.content.ContentResolver.query(ContentResolver.java:668)
at com.example.myapplication.New_Schedule_Calendar.writeCalendarEvent(New_Schedule_Calendar.java:111)
at com.example.myapplication.New_Schedule_Calendar.Start_Write(New_Schedule_Calendar.java:50)
at com.example.myapplication.Schedule_Delete.onCreate(Schedule_Delete.java:44)
at android.app.Activity.performCreate(Activity.java:7258)
at android.app.Activity.performCreate(Activity.java:7249)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1222)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3059)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1724)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
我想获取电子邮件ID,并将数据插入Google日历。
应用程序崩溃:
所有授予的权限:
要求访问联系人
答案 0 :(得分:0)
您似乎误读了LogCat上的警告,内容为:
由以下原因引起:java.lang.SecurityException:...需要android.permission。 READ_CALENDAR ...
这样做的原因是,您只要求WRITE_CALENDAR权限,而不要求READ_CALENDAR权限,因此在Android 8之前,如果被授予任何权限,您也会自动被授予同一权限组中的所有权限,该行为具有修改后,您需要指定所需的所有权限。
因此只需更改
ActivityCompat.requestPermissions((Activity)context, new String[]{android.Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
收件人:
ActivityCompat.requestPermissions((Activity)context, new String[]{permission.WRITE_CALENDAR, permission.READ_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
此外,我认为为MY_PERMISSIONS_REQUEST_WRITE_CALENDAR
和MY_PERMISSIONS_REQUEST_READ_CONTACTS
提供不同的请求代码是明智的。