SQLiteデータベースを使用して、ListViewに表示されるReservationsというオブジェクトを保存しています。以前は非推奨の関数startManagingCursor()でカーソルを使用していましたが、ListViewが表示されているアクティビティでアプリがクラッシュしました。
そこで、代わりにCursorLoadersとContentProvidersを使用しようとしましたが、これを使用して次のことを行いました。
package com.example.my.app;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
public class FlightBook extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
private ListView ReservationList = null;
private Cursor c = null;
private ReservationsBDD rdb = new ReservationsBDD(this);
private SimpleCursorAdapter mAdapter;
private static final int LOADER_ID = 0;
private static final String[] PROJECTION = new String[] {MaBaseSQLite.getColReference(), MaBaseSQLite.getColLastname()};//{ "_id", "text_column" };
private LoaderManager.LoaderCallbacks<Cursor> mCallbacks;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flight_book);
ReservationList = (ListView) findViewById(R.id.flightList);
//Initialiser la base de données
rdb.open();
String[] from = { MaBaseSQLite.getColLastname() }; //{ "text_column" };
int[] to = { R.id.reference_entry, R.id.lastname_entry }; //{ R.id.text_view };
/* Display the bdd */
//mAdapter = new SimpleCursorAdapter(this.getBaseContext(), R.layout.flight_book_list, c, from, to);
mAdapter = new SimpleCursorAdapter(this, R.layout.flight_book_list, null, from, to, 0);
mCallbacks = this;
ReservationList.setAdapter(mAdapter);
getSupportLoaderManager().initLoader(LOADER_ID, null, mCallbacks);
//Gérer le clic simple sur un élément de la listView
ReservationList.setOnItemClickListener(new OnItemClickListener()
{
long selectedItemID = 0;
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Reservation res = rdb.getReservationWithID(id);
//Afficher l'activité adéquate
Intent myIntent = new Intent(view.getContext(), ReservationInfo.class);
myIntent.putExtra("ReservationReference", res.getReference());
myIntent.putExtra("LastName", res.getLastname());
startActivityForResult(myIntent, 0);
}
});
//Gérer le clic long sur un élément de la listView
ReservationList.setOnItemLongClickListener (new OnItemLongClickListener()
{
long selectedItemID = 0;
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
//selectedItemID = ((View) parent.getItemAtPosition(position)).getId();
return onLongListItemClick(view, position, id);
}
protected boolean onLongListItemClick(final View v, final int pos, long id)
{
final String str=ReservationList.getItemAtPosition(pos).toString();
Log.i("ListView", "onLongListItemClick string=" + str);
AlertDialog.Builder builder = new AlertDialog.Builder(FlightBook.this);
builder.setMessage("Delete this entry from Flight Book?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
Log.i("ID",""+pos);
rdb.removeReservationWithID((int)mAdapter.getItemId(pos));
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
return true;
}
});
}
public void onPause()
{
super.onPause();
mAdapter.notifyDataSetInvalidated();
mAdapter.changeCursor(null);
}
public void onDestroy()
{
super.onDestroy();
rdb.close();
}
public void onStart()
{
super.onStart();
}
public void onStop()
{
super.onStop();
}
public void onResume(Bundle savedInstanceState)
{
super.onResume();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_flight_book, menu);
return true;
}
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1)
{
// TODO Auto-generated method stub
return new CursorLoader(FlightBook.this, ReservationProvider.CONTENT_URI, PROJECTION, null, null, null);
}
//@Override -> won't work, says "must override a superclass method"
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
{
mAdapter.swapCursor(cursor);
}
//@Override -> won't work, says "must override a superclass method"
public void onLoaderReset(Loader<Cursor> loader)
{
mAdapter.swapCursor(null);
}
}
調査中の何らかの理由で、このアクティビティを起動するとすぐにアプリがクラッシュします。
これが私のContentProviderです:
package com.example.my.app;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
public class ReservationProvider extends ContentProvider
{
private ReservationsBDD mDB;
private static final String AUTHORITY = "com.example.my.app.ReservationProvider";
public static final int RESERVATION = 100;
public static final int RESERVATION_ID = 110;
private static final String RESERVATIONS_BASE_PATH = "reservations";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + RESERVATIONS_BASE_PATH);
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
+ "/mc-reservation";
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
+ "/mt-reservation";
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static
{
sURIMatcher.addURI(AUTHORITY, RESERVATIONS_BASE_PATH, RESERVATION);
sURIMatcher.addURI(AUTHORITY, RESERVATIONS_BASE_PATH + "/#", RESERVATION_ID);
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2)
{
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri arg0)
{
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri arg0, ContentValues arg1)
{
// TODO Auto-generated method stub
return null;
}
@Override
public boolean onCreate()
{
mDB = new ReservationsBDD(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(mDB.getMaBaseSQLite().TABLE_RESERVATION);
int uriType = sURIMatcher.match(uri);
switch (uriType)
{
case RESERVATION_ID:
queryBuilder.appendWhere(ReservationsBDD.COL_ID + "=" + uri.getLastPathSegment());
break;
case RESERVATION:
// no filter
break;
default:
throw new IllegalArgumentException("Unknown URI");
}
Cursor cursor = queryBuilder.query(mDB.getMaBaseSQLite().getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
{
// TODO Auto-generated method stub
return 0;
}
}
何が間違っていたのですか?:( 前もって感謝します。
PS:ReservationsBDDは、SQLiteOpenHelperであるMaBaseSQLiteからアイテムを取得するためのDAOです。