как получить идентификатор электронной почты календаря в Android версии 8.1? - PullRequest
0 голосов
/ 22 декабря 2018

Я пытаюсь получить идентификатор электронной почты календаря, используя разрешение времени выполнения календаря.Это отлично работало в версии Android 6.1.и поэтому я начал тестирование в версии 8.1.

После установки приложения оно будет запрашивать разрешение на чтение контактов, и я спрашивал разрешение, но при попытке входа в приложение выдает ошибку в logcat needs read contact permission.Я не могу понять, почему это происходит.

Мне нужно получить идентификатор электронной почты календаря, чтобы вставить те же данные в календарь 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 // здесь я пытаюсь получить идентификатор электронной почты календаря

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) 

Я хочучтобы получить идентификатор электронной почты и вставить данные в календарь Google.

Сбои приложения:

App crashes

все разрешения даны:

App permissions screen

Запрос доступа к контактам

Asking for contacts permissions

1 Ответ

0 голосов
/ 23 декабря 2018

Похоже, вы неправильно прочитали предупреждение, которое вы получили в 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...