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);
}
}
Ах! Вот и все, я забыл добавить uri к моему uriMatcher. Спасибо, сэр – BiGGZ