【问题标题】:Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup...}}传递结果失败 ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup...}}
【发布时间】:2014-06-20 20:31:31
【问题描述】:

我正在尝试从联系人列表中选择一个联系人并将其添加到数据库中。但是,每当我在 onActivityResult 中选择联系人和处理数据时,它都会引发此异常:

 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/80i23a826b40e879ef2/314 flg=0x1 }} to activity {com.example.MyApplication/com.example.MyApplication.MainActivity}: java.lang.NullPointerException
Caused by: java.lang.NullPointerException at com.example.myapplication.ChildTab1.onActivityResult(ChildTab1.java:92)

点击“添加联系人”按钮(在ChildTab2 类中):

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
getActivity().startActivityForResult(intent, PICK_CONTACT);

onActivityResult 方法(在ChildTab2 类中):

@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
    super.onActivityResult(reqCode, resultCode, data);

    switch (reqCode) {
    case (PICK_CONTACT) :
        if (resultCode == Activity.RESULT_OK) {
            Uri contactData = data.getData();
            Cursor c =  getActivity().getContentResolver().query(contactData, null, null, null, null);
            if (c.moveToFirst()) {

                String contactId = c.getString(c.getColumnIndex(ContactsContract.Contacts._ID));
                String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                String phoneNumber = null;

                String hasPhone = c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

                if (hasPhone.equalsIgnoreCase("1")) 
                {
                    Cursor phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,null, null);
                    while (phones.moveToNext()) 
                    {
                        phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    }
                    phones.close();

                    ContentValues values = new ContentValues();
                    values.put(ProfilesProvider.NAME,name);
                    values.put(ProfilesProvider.NUMBER,phoneNumber);
                    getActivity().getContentResolver().insert(ProfilesProvider.PROFILES_CONTENT_URI, values);

                }
                else {
                    Toast.makeText(getActivity().getBaseContext(), "Phone Number Not Found", Toast.LENGTH_SHORT).show();
                }


            }
        }
    break;
    }
}

在我的应用程序中,我实现了ActionBarShelock。因此,有三个选项卡(扩展 SherlockFragment),并且在第二个选项卡中包含另外两个选项卡(也扩展了 SherlockFragment)。所以,我将 onActivityResult 值从 MainActivity 传递到 FragmentTab2 到 ChildTab1 的 onActivityResult 方法,如下所示:

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
      super.onActivityResult(requestCode, resultCode, intent);
      new FragmentTab2().onActivityResult(requestCode, resultCode, intent);
 }

创建前三个选项卡的代码(在MainActivity 类中):

// Activate Navigation Mode Tabs
    mActionBar = getSupportActionBar();
    mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // Locate ViewPager in activity_main.xml
    mPager = (ViewPager) findViewById(R.id.pager);

    // Activate Fragment Manager
    FragmentManager fm = getSupportFragmentManager();

    // Capture ViewPager page swipes
    ViewPager.SimpleOnPageChangeListener ViewPagerListener = new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);
            // Find the ViewPager Position
            mActionBar.setSelectedNavigationItem(position);
        }
    };

    mPager.setOnPageChangeListener(ViewPagerListener);
    // Locate the adapter class called ViewPagerAdapter.java
    ViewPagerAdapter viewpageradapter = new ViewPagerAdapter(fm);
    // Set the View Pager Adapter into ViewPager
    mPager.setAdapter(viewpageradapter);

// Create first Tab
    tab = mActionBar.newTab().setText("Tab 1").setTabListener(tabListener);
    mActionBar.addTab(tab);

    // Create second Tab
    tab = mActionBar.newTab().setText("Tab 2").setTabListener(tabListener);
    mActionBar.addTab(tab);

    // Create third Tab
    tab = mActionBar.newTab().setText("Tab 3").setTabListener(tabListener);
    mActionBar.addTab(tab);

以及创建子标签的代码(在FragmentTab2类中):

tabHost = new FragmentTabHost(getSherlockActivity());
    tabHost.setup(getSherlockActivity(), getChildFragmentManager(), R.layout.fragmenttab2);

    // Create Child Tab1
    tabHost.addTab(tabHost.newTabSpec("childTab1").setIndicator("Child Tab 1"), ChildTab1.class, null);

    // Create Child Tab2
    tabHost.addTab(tabHost.newTabSpec("childTab2").setIndicator("Child Tab 2"), ChildTab2.class, null);

【问题讨论】:

  • 你想在这里做什么:new FragmentTab2().onActivityResult(requestCode, resultCode, intent);?另外请发布更多您的logcat。这一行没有多大帮助,我们需要看更多才能查明错误的根源。
  • onActivityResult 方法没有在ChildTab1 中被调用,但它正在调用MainActivity 的onActivityResult 方法,所以我将MainActivity 中的值传递给它的子FragmentTab2 到是孩子ChildTab1。我在FragmentTab2 的onActivityResult 方法中调用new ChildTab1().onActivityResult(requestCode, resultCode, intent);。
  • 但是您没有将任何值传递给FragmentTab2,您只需创建一个FragmentTab2 的新实例并在其上调用一个方法,然后这个新实例将立即被垃圾收集并再次销毁.如果要将值传递给现有实例,则必须在现有实例上调用此方法。仍然请发布更多相关代码和更多您的 logcat。没有它,我们只能猜测问题可能是什么。
  • 糟糕,没有注意到我每次都在创建新实例。愚蠢的错误。 :) 而且,日志还有一件事,我忘了补充。现在,我已经添加了它。它在线抛出 NullPointerException :Cursor c = getActivity().getContentResolver().query(contactData, null, null, null, null);
  • 这很可能是因为您每次都创建了一个新实例。如果您创建 Fragment 的新实例,它不会立即附加到任何 Activity,因此 getActivity() 将返回 null 并导致此 NullPointerException。

标签: android actionbarsherlock android-tabhost onactivityresult android-nested-fragment


【解决方案1】:

问题最有可能出在这里:

new FragmentTab2().onActivityResult(requestCode, resultCode, intent);

您正在创建一个新实例,而不是在现有实例上调用该方法。将Fragment 实例保存在成员变量中,然后在空检查后调用此实例上的方法。

您的第二个错误 - NullPointerException - 发生在这里:

Cursor c =  getActivity().getContentResolver().query(contactData, null, null, null, null);

很可能是由同一件事引起的。由于您创建了一个未附加到任何 Activity 的新 Fragment 实例,因此 getActivity 方法将返回 null。

所以基本上要修复你的两个错误,只需在现有的Fragment 实例上调用onActivityResult(...) 方法,该实例附加到Activity。它应该看起来像这样:

private FragmentTab2 fragmentTab2;  // Save the instance in this variable   

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if(fragmentTab2 != null) {
        fragmentTab2.onActivityResult(requestCode, resultCode, intent);
    }
}

编辑:

要获取 Fragment 实例,您必须像这样覆盖 Activity 中的 onAttachFragment():

private FragmentTab2 fragmentTab2;
private SomeOtherFragment someOtherFragment;

@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);

    // For each of your Fragments add an if statement here checking for 
    // the class of the Fragment and assign if it to the member variables 
    // if a match is found
    if (fragment instanceof FragmentTab2) {

        this.fragmentTab2 = (FragmentTab2) fragment;

    } else if(fragment instanceof SomeOtherFragment) {

        this.someOtherFragment = (SomeOtherFragment) fragment;

    } else ...
}

使用这种方法,每次您想在实例上调用方法时,空值检查变得更加重要,所以不要忘记始终检查 Fragments 是否不为空!

【讨论】:

  • 感谢您的回答。但是,有了这个我只能获得FragmentTab2 的实例而不是ChildTab2 的实例,其中包含我要运行的onActivityResult 方法。而且,onAttachFragment 方法在FragmentTab2 类(扩展了 SherlockFragment)中不可用,所以即使在FragmentTab2 类中我也无法获得ChildTab2 的实例。
  • 为什么要ChildTab2 的实例?你并没有真正发布很多代码,所以我不能真正说出你的架构是什么,但这看起来肯定是糟糕的设计。如果它是FragmentTab2 的子标签,那么它应该与Activity 无关。在FragmentTab2 上调用一个方法并将其传递给孩子是正确的做法。
  • 架构是这样的:MainActivity 创建了三个标签FragmentTab1,2,3,它们扩展了SherlockFragment。在FragmentTab2 类中,我创建了两个子选项卡ChildTab1,2,它也扩展了SherlockFragment。我已经添加了用于创建所有这些选项卡的代码。另外,现在我已经编辑了代码以显示哪个代码在哪个类中以避免任何混淆。而且,我想调用的onActivityResult 方法在ChildTab2 中。但是,每当结果出现时,它都会调用MainActivity 的onActivityResult 方法而不是ChildTab2。
  • 问题已解决,感谢您的帮助。 :) 要获得 ChildTab2,我必须使用 FragmentTab2 的 getChildFragmentManager 方法。所以,MainActivity 的 onActivityResult 方法中的最终代码:Fragment childTab2 = fragmentTab2.getChildFragmentManager().findFragmentByTag("childTab2"); childTab2.onActivityResult(requestCode, resultCode, intent);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多