Ich versuche, Daten aus zwei verschiedenen Tabellen mit einem LoaderManager in einem ListFragment
abzufragen. Meine Tabellen haben definitiv Daten, die ich überprüft habe, aber aus irgendeinem Grund gibt meine Abfrage/Cursor null zurück. Ich vermute, es ist ein Syntaxproblem, aber ich bin mir nicht ganz sicher. Ich habe die gleiche Abfrage in MySql Workbench ausgeführt, und es hat funktioniert. Iv versucht, die Abfrage wie folgt ausgeführt werden:Cursor, der nullpointer wirft, wenn er vom Inhaltsanbieter
cursor = db.query("Customer, Appointment", new String[]{"fullname", "physicalAddress", "date","time"}, "Customer.ID IN(?)", new String[]{"select customerID from Appointment"},null,null,null);
und diese:
cursor = db.rawQuery("select fullName, physicalAddress, date, time from Customer, Appointment where Customer.ID IN(select customerID from Appointment);", null);
Aber jedes dieser Codezeile lautet:
cursor.setNotificationUri(getContext().getContentResolver(), uri);
ich erhalte eine Nullpointer . Falls dies etwas bedeutet, verwende ich kein FrameLayout und füge mein ListFragment dynamisch hinzu. Iv definiert es in der XML-Datei Aktivitäten. Jede Hilfe wird geschätzt. Bitte lassen Sie mich wissen, wenn ich etwas ausgelassen habe.
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;
}
}
Telefonvorwahl:
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);
}
}
Ah! Das war es, ich habe vergessen, die URI zu meinem UriMatcher hinzuzufügen. Danke mein Herr – BiGGZ