0

Im пытается запросить данные из двух разных таблиц с помощью LoaderManager в ListFragment. У моих таблиц определенно есть данные, я проверял, но почему-то мой запрос/курсор возвращает нуль. Я подозреваю, что это проблема синтаксиса, но я не совсем уверен. Я выполнил тот же запрос в MySql Workbench, и он сработал. Iv попытался запустить запрос, как это:курсор, бросающий nullpointer при вызове из поставщика контента

cursor = db.query("Customer, Appointment", new String[]{"fullname", "physicalAddress", "date","time"}, "Customer.ID IN(?)", new String[]{"select customerID from Appointment"},null,null,null);

и это:

cursor = db.rawQuery("select fullName, physicalAddress, date, time from Customer, Appointment where Customer.ID IN(select customerID from Appointment);", null);

Но каждый раз, когда эта строка кода работает:

cursor.setNotificationUri(getContext().getContentResolver(), uri);

я получить NullPointer , В случае, если это означает что-то, im не используя FrameLayout и динамически добавляя мой ListFragment. Iv определил его в XML-файле Activities. Любая помощь приветствуется. Пожалуйста, дайте мне знать, если iv оставит что-нибудь.

DatabaseContentProvider:

package com.venon.nakomangsp; 

import android.content.ContentProvider; 
import android.content.ContentValues; 
import android.content.UriMatcher; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.net.Uri; 
import android.support.annotation.Nullable; 

@SuppressWarnings("ConstantConditions") 
public class DatabaseContentProvider extends ContentProvider { 

DatabaseHelper dbHelper; 
private static final String PROVIDER_NAME = "com.venon.nakomangsp.databasecontentprovider"; 
private static final UriMatcher uriMatcher; 
public static final Uri CUSTOMER_URI = Uri.parse("content://"+ PROVIDER_NAME+"/Customer"); 
private static final int CUSTOMER_CODE = 1; 
public static final Uri APPOINTMENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/Appointment"); 
private static final int APPOINTMENT_CODE = 2; 
public static final Uri APPOINTMENT_VIEW_URI = Uri.parse("content://" + PROVIDER_NAME + "/AppointmentView"); 
private static final int APPOINTMENT_VIEW_CODE = 3; 

static{ 
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    uriMatcher.addURI(PROVIDER_NAME,"Customer", CUSTOMER_CODE); 
    uriMatcher.addURI(PROVIDER_NAME, "Appointment", APPOINTMENT_CODE); 
} 


@Override 
public boolean onCreate() { 
    dbHelper = new DatabaseHelper(getContext()); 
    return true; 
} 

@Nullable 
@Override 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    Cursor cursor = null; 

    switch(uriMatcher.match(uri)){ 

     case CUSTOMER_CODE: 
      cursor = db.query("Customer", projection, selection, selectionArgs, null, null, sortOrder); 
      break; 

     case APPOINTMENT_CODE: 
      cursor = db.query("Appointment", projection, selection, selectionArgs, null, null, sortOrder); 
      break; 

     case APPOINTMENT_VIEW_CODE://this is the case triggered 
      //cursor = db.rawQuery("select fullName, physicalAddress, date, time from Customer, Appointment where Customer.ID IN(select customerID from Appointment);", null); 

      cursor = db.query("Customer, Appointment", new String[]{"fullname", "physicalAddress", "date","time"}, "Customer.ID IN(?)", new String[]{"select customerID from Appointment"},null,null,null); 

     default: 
      break; 

    } 

    cursor.setNotificationUri(getContext().getContentResolver(), uri); 

    return cursor; 
} 

@Nullable 
@Override 
public Uri insert(Uri uri, ContentValues values) { 

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 

    switch(uriMatcher.match(uri)){ 

     case CUSTOMER_CODE: 
      db.insertOrThrow("Customer", null, values); 
      break; 

     case APPOINTMENT_CODE: 
      db.insertOrThrow("Appointment", null, values); 
      break; 

     default: 
      break; 

    } 

    getContext().getContentResolver().notifyChange(uri, null, false);//set to true when syncadapter hooked up 
    return null; 
} 

@Override 
public int delete(Uri uri, String selection, String[] selectionArgs) { 

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 

    switch(uriMatcher.match(uri)){ 

     case CUSTOMER_CODE: 
      db.delete("Customer", selection, selectionArgs); 
      break; 

     case APPOINTMENT_CODE: 
      db.delete("Appointment", selection, selectionArgs); 
      break; 

     default: 
      break; 

    } 

    getContext().getContentResolver().notifyChange(uri, null, false);//keep as false when hooking up syncadapter 
    return 0; 
} 

@Override 
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 

    switch(uriMatcher.match(uri)){ 

     case CUSTOMER_CODE: 
      db.update("Customer", values, selection, selectionArgs); 
      break; 

     case APPOINTMENT_CODE: 
      db.update("Appointment", values, selection, selectionArgs); 
      break; 

     default: 
      break; 

    } 
    getContext().getContentResolver().notifyChange(uri, null, false); 
    return 0; 
} 

@Nullable 
@Override 
public String getType(Uri uri) { 
    return null; 
} 
} 

Телефонный код:

package com.venon.nakomangsp; 


import android.content.Intent; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.support.v4.app.ListFragment; 
import android.support.v4.app.LoaderManager; 
import android.support.v4.content.CursorLoader; 
import android.support.v4.content.Loader; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 


public class AppointmentListFragment extends ListFragment implements  LoaderManager.LoaderCallbacks<Cursor> { 
SimpleCursorAdapter adapter; 

public static AppointmentListFragment newInstance() { 
    AppointmentListFragment fragment = new AppointmentListFragment(); 

    return fragment; 
} 

public AppointmentListFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (getArguments() != null) { 
     // mParam1 = getArguments().getString(ARG_PARAM1); 
     // mParam2 = getArguments().getString(ARG_PARAM2); 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

    View view = inflater.inflate(R.layout.fragment_appointment_list, container, false); 

    String[] from = {"fullName", "physicalAddress", "date", "time"}; 
    int[] to = {R.id.customerName_lv, R.id.physicalAddress_lv, R.id.date_lv, R.id.time_lv}; 
    adapter = new SimpleCursorAdapter(getContext(), R.layout.appointment_list, null, from, to, 0); 
    setListAdapter(adapter); 

    getActivity().getSupportLoaderManager().initLoader(0, null, AppointmentListFragment.this); 

    return view; 
} 

@Override 
public void onListItemClick(ListView l, View v, int position, long id) { 
    super.onListItemClick(l, v, position, id); 

    getActivity().startActivity(new Intent(getContext(), AppointmentViewActivity.class)); 
} 

@Override 
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { 
    //this is the calling line 
    return new CursorLoader(getContext(), DatabaseContentProvider.APPOINTMENT_VIEW_URI, null, null, null, null); 
} 

@Override 
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { 

    adapter.swapCursor(cursor); 
} 

@Override 
public void onLoaderReset(Loader<Cursor> cursorLoader) { 
    adapter.swapCursor(null); 
} 


} 

ответ

0

если ваш uri не соответствует ни одному из трех корпусных элементов, курсор будет нулевым, и вы получите NPE:

switch(uriMatcher.match(uri)){ 

    case CUSTOMER_CODE: 
     cursor = db.query("Customer", projection, selection, selectionArgs, null, null, sortOrder); 
     break; 

    case APPOINTMENT_CODE: 
     cursor = db.query("Appointment", projection, selection, selectionArgs, null, null, sortOrder); 
     break; 

    case APPOINTMENT_VIEW_CODE://this is the case triggered 
     //cursor = db.rawQuery("select fullName, physicalAddress, date, time from Customer, Appointment where Customer.ID IN(select customerID from Appointment);", null); 

     cursor = db.query("Customer, Appointment", new String[]{"fullname", "physicalAddress", "date","time"}, "Customer.ID IN(?)", new String[]{"select customerID from Appointment"},null,null,null); 

    default: 
     break; 

} 

cursor.setNotificationUri(getContext().getContentResolver(), uri); 

Лучший способ - исключить исключение IllegalArgument в default.

default: 
     throw new IllegalArgumentException("unknown uri"); 
+0

Ах! Вот и все, я забыл добавить uri к моему uriMatcher. Спасибо, сэр – BiGGZ