添加到授予权限后未立即执行的联系人

Posted

技术标签:

【中文标题】添加到授予权限后未立即执行的联系人【英文标题】:Add to contacts not performed immediately after permission is granted 【发布时间】:2021-05-27 22:06:23 【问题描述】:

在我的 android 应用程序(用 Java 编写)中,我有一个使用扫描信息将联系人添加到用户手机的功能。一旦用户授予应用程序编辑设备联系人的权限,该功能就会完美运行。但是,在授予权限后,用户需要再次按下“添加到联系人”按钮,因为该操作没有执行,才能开始。就好像原始命令在请求用户允许执行该操作时被丢弃了。 有什么办法可以在获得许可后立即添加联系人?第一次使用该应用程序的用户不会知道他们第一次添加联系人时需要在授予权限后再次按下按钮。

这是“添加到联系人”方法的代码:

private void addToContact(View v) 
    //if the permission if off
    Ask.on(this)
            .forPermissions(Manifest.permission.WRITE_CONTACTS)
            .go();

    int phoneType = 1;
    int emailType = 1;

    // Prepare contact creation request
    //
    // Note: We use RawContacts because this data must be associated with a
    // particular account.
    // The system will aggregate this with any other data for this contact
    // and create a coresponding entry in the ContactsContract.Contacts provider for us.
    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
            .build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                    ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
            .withValue(
                    ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
                    mContactName).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                    ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,
                    mContactPhoneNumber)
            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
                    phoneType).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                    ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Email.DATA,
                    mContactEmail)
            .withValue(ContactsContract.CommonDataKinds.Email.TYPE,
                    emailType).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                    ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
            .withValue(
                    ContactsContract.CommonDataKinds.Organization.COMPANY,
                    mContactOrg)
            .withValue(ContactsContract.CommonDataKinds.Organization.TITLE,
                    mContactTitle)
            .withValue(ContactsContract.CommonDataKinds.Organization.TYPE,
                    1).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(
                    ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
            .withValue(
                    ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS,
                    mContactAddress).build());

    // Ask the Contact provider to create a new contact
    Log.i(TAG, "Selected account: " + ACCOUNT_TYPE + " (" + ACCOUNT_NAME
            + ")");
    Log.i(TAG, "Creating contact: " + mContactName);
    int duration = Toast.LENGTH_SHORT;
    Context ctx = getApplicationContext();
    try 
        getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        Toast toast = Toast.makeText(ctx, "contact created  successfully",
                duration);
        toast.show();

     catch (Exception e) 
        // Display warning

        Toast toast = Toast.makeText(ctx, "contact creation failed",
                duration);
        toast.show();

        // Log exception
        Log.e(TAG, "Exception encountered while inserting contact: " + e);
    

这里是调用方法的地方:

mAddToContactButton.setOnClickListener(new Button.OnClickListener() 
        public void onClick(View v) 
            addToContact(v);
        
    );

【问题讨论】:

解释一下。也添加你的代码。 @Danish 我将添加我的代码,但是在用户授予权限后代码可以完美运行。基本上,当第一次使用应用程序并按下“添加到联系人”按钮时,应用程序会请求编辑手机联系人的权限。给定后,用户会期望已添加联系人,但事实并非如此。用户需要再次按下按钮来添加他们的第一个联系人。之后就没有问题了。 【参考方案1】:

这不是 Android 或 ContactsContract 的问题,而是您对 Ask 的使用。

Ask 支持您可以在向您的应用授予请求时添加的回调,您需要添加它并再次调用您的方法。像这样的:

@AskGranted(Manifest.permission.WRITE_CONTACTS)
public void writeContactsGranted(int id) 
    Log.i(TAG, "the permission was granted, calling 'addToContact' again");
    // call addToContact() here with the view you need.

【讨论】:

非常感谢!我现在的问题是如何拨打电话以及将此方法放在哪里。目前,当用户单击“添加到联系人”按钮时,会调用 addToContact() 方法。我会打电话给 writeContactsGranted 吗?然后我将如何将视图传递给该方法? 实际上,我很确定该视图从未使用过,因此我将其取出。所以为了清楚起见,我需要做的就是将此方法添加到活动中并再次在其中调用 addToContacts() ? 你可以在@AskGranted(Manifest.permission.WRITE_CONTACTS) 中试试这个 public void writeContactsGranted(int id) Log.i(TAG, "权限被授予,再次调用 'addToContact'") ; mAddToContactButton.setOnClickListener(new Button.OnClickListener() public void onClick(View v) addToContact(v); ); 别忘了在 maddtocontactbutton.setonclicklistener 之前使用 findviewbyid 初始化按钮 我尝试直接调用该方法,但从未调用过。然后我尝试在该方法中添加点击监听器,它说'联系人创建失败。【参考方案2】:

我使用这个问题的答案使其工作:Android contacts permission granted without asking at runtime@Marmor 在问题所在方面是正确的,但是,Ask 功能不起作用。对于 Android 23 及更高版本,需要更多。

【讨论】:

以上是关于添加到授予权限后未立即执行的联系人的主要内容,如果未能解决你的问题,请参考以下文章

在请求并授予权限后立即执行 ACTION_CALL 意图

java 添加联系人到Android手机...你需要权限

解决“你没有权限访问,请与网络管理员联系”

Android6.0运行时权限

Android6.0运行时权限

每当将新联系人添加到联系人时,如何添加类似whatsapp的选项以进行联系