Ошибка доставки результата ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup...}}

Я пытаюсь выбрать контакт из списка контактов и добавить его в базу данных. Но всякий раз, когда я выбираю контакт и обрабатываю данные в 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);

1 ответ

Проблема, скорее всего, здесь:

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

Вы создаете новый экземпляр вместо вызова метода на существующем экземпляре. Спасти Fragment экземпляр в переменной-члене и после проверки на ноль вместо этого вызовите метод этого экземпляра.

Ваша вторая ошибка - NullPointerException - что происходит здесь:

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

Скорее всего, вызвано тем же. Так как вы создаете новый Fragment экземпляр, который не привязан ни к какому Activity метод getActivity вернусь null,

Таким образом, чтобы исправить обе ваши ошибки, просто позвоните onActivityResult(...) метод на существующий Fragment экземпляр, который прикреплен к 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 случаи вы должны переопределить onAttachFragment() в вашем Activity как это:

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 не нулевые!