【问题标题】:Android: Choosing the right settings to prepare ActivityResultLauncher for picking contactsAndroid:选择正确的设置来准备 ActivityResultLauncher 以选择联系人
【发布时间】:2021-02-21 10:35:37
【问题描述】:

在尝试和阅读文档 4 小时后,我无法解决在使用 ActivityResultLauncher 代替我正在使用但已弃用的选择联系人和 contentResolver 以使用数据的解决方案时获取 Uri 数据的问题。

复制的代码至少使我能够使用启动的 Intent 成功选择联系人,但应用 [...data.setData((Uri) uriData)...] 会导致 getContentResolver 出现 NULL 指针异常。

我尝试将 ActivityResultLauncher 声明为 String 并使用 ActivityResultContracts.GetContent() 声明为 Uri 但是当我认为我接近时,我找不到启动 ContactContracts 的正确参数...。 PickContact 因为它没有 MIME,但是使用意图,我无法获得 Uri 结果。猜猜这就是为什么他们只在开发者网站上记录简单的解决方案,例如选择图像 MIME。

Public class InvoiceFragment extends Fragment implements InvoiceListAdapter.OnInvoiceItemListener{
private InvoiceListAdapter iAdapter;
private SubTotalListAdapter sAdapter;
private Locale locale = new Locale("en", "UK");
private NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);
Float invoiceTotal;
RecyclerView.LayoutManager invLayoutManager;
DatabaseHelper myDb;
final Uri uriData = null;
//ArrayList<InvoiceItem> invoiceItemList = new ArrayList<>();
ActivityResultLauncher<Intent> mStartForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {


            @Override
            public void onActivityResult(ActivityResult result) {
                Intent data = result.getData();
                data.setData((Uri) uriData);

                Cursor c =  getContext().getContentResolver().query(uriData, null, null, null, null);
                if(c.moveToFirst()){
                    String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                    Log.d(TAG, "onActivityResult: " + name);
                    c.close();

                }
            }




        });

然后启动它!

       view.findViewById(R.id.btGetContact).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (checkPermissions(getActivity(), READ_CONTACTS)) {
                Intent contactsIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
                //contactsIntent.setData((Uri) uriData);

                mStartForResult.launch(contactsIntent);
            }


        }
    });

结果

    java.lang.RuntimeException: Unable to resume activity {wytonmcs.com.accounts/wytonmcs.com.accounts.InvoiceActivity}: java.lang.NullPointerException: uri
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3581)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3621)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1638)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: java.lang.NullPointerException: uri
    at com.android.internal.util.Preconditions.checkNotNull(Preconditions.java:128)
    at android.content.ContentResolver.query(ContentResolver.java:737)
    at android.content.ContentResolver.query(ContentResolver.java:704)
    at android.content.ContentResolver.query(ContentResolver.java:662)
    at wytonmcs.com.accounts.InvoiceFragment$1.onActivityResult(InvoiceFragment.java:70)
    at wytonmcs.com.accounts.InvoiceFragment$1.onActivityResult(InvoiceFragment.java:62)
    at androidx.activity.result.ActivityResultRegistry$1.onStateChanged(ActivityResultRegistry.java:145)
    at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
    at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:265)
    at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:307)
    at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:148)
    at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134)
    at androidx.fragment.app.Fragment.performStart(Fragment.java:3013)
    at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:586)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:300)
    at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1636)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3112)
    at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:3063)
    at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:262)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:482)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1334)
    at android.app.Activity.performStart(Activity.java:7029)
    at android.app.Activity.performRestart(Activity.java:7104)
    at android.app.Activity.performResume(Activity.java:7109)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3556)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3621) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1638) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6494)

【问题讨论】:

    标签: java android uri


    【解决方案1】:

    在您的 OnClick 调用中,使用 null 启动 mStartForResult.launch(null);

    你可以使用ActivityResultContracts.PickContact()

    ActivityResultLauncher<String> mStartForResult = registerForActivityResult(new ActivityResultContracts.PickContact(),
        new ActivityResultCallback<Uri>() {
            @Override
            public void onActivityResult(Uri uri) {
                Cursor c =  getContext().getContentResolver().query(uri, null, null, null, null);
                    if(c.moveToFirst()){
                        String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                        Log.d(TAG, "onActivityResult: " + name);
                        c.close();
                    }
            }
    });
    

    YouTube 视频中有一些示例,名为:ActivityResultContracts Android

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-16
      • 1970-01-01
      • 1970-01-01
      • 2015-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多