如何在Android 8.1版中获取日历电子邮件ID?

时间:2018-12-22 05:06:06

标签: android android-permissions runtime-permissions

我正在尝试使用日历运行时权限来获取日历的电子邮件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日历。

应用程序崩溃:

App crashes

所有授予的权限:

App permissions screen

要求访问联系人

Asking for contacts permissions

1 个答案:

答案 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_CALENDARMY_PERMISSIONS_REQUEST_READ_CONTACTS提供不同的请求代码是明智的。