android - Loader not loading data when sqlite data changes -
i have dialogfragment
i'm working on display 2 spinners, side side, 1 displays list of drivers, other list of vehicles.
the data populate these spinners retrieved sqlite database. trying use loadermanager
keep spinners updated or in sync database tables, (drivers , vehicles).
when add/delete/edit record in either drivers table or vehicles table in database, spinners don't updated, driver or vehicle remains unchanged in spinner.
i'm not sure i'm missing because thought loadermanager
supposed keep lists updated or in sync database tables automatically right?
i created button called adddrivervehicle()
supposed allow user add driver/vehicle in future i'm using test delete driver kind of simulate database tables changing can see if spinner gets updated automatically it's not happening. record being deleted spinner continues show it.
public class drivervehiclepickersdialogfragment extends dialogfragment implements loadermanager.loadercallbacks<cursor>, onitemselectedlistener { public static final string arg_listener_type = "listenertype"; public static final string arg_dialog_type = "dialogtype"; public static final string arg_title_resource = "titleresource"; public static final string arg_set_driver = "setdriver"; public static final string arg_set_vehicle = "setvehicle"; private static final int drivers_loader = 0; private static final int vehicles_loader = 1; private drivervehicledialoglistener mlistener; // these adapter being used display driver's , vehicle's data. simplecursoradapter mdriversadapter, mvehiclesadapter; // define dialog view private view mview; // store driver , vehicle selected private long[] mdrivers, mvehicles; // spinners containing driver , vehicle list private spinner driversspinner; private spinner vehiclesspinner; private static enum listenertype { activity, fragment } public static enum dialogtype { driver_spinner, vehicle_spinner, driver_vehicle_spinner } public interface drivervehicledialoglistener { public void ondialogpositiveclick(long[] mdrivers, long[] mvehicles); } public drivervehiclepickersdialogfragment() { // empty constructor log.d("default", "default constructor ran"); } public static drivervehiclepickersdialogfragment newinstance(drivervehicledialoglistener listener, bundle dialogsettings) { final drivervehiclepickersdialogfragment instance; if (listener instanceof activity) { instance = createinstance(listenertype.activity, dialogsettings); } else if (listener instanceof fragment) { instance = createinstance(listenertype.fragment, dialogsettings); instance.settargetfragment((fragment) listener, 0); } else { throw new illegalargumentexception(listener.getclass() + " must either activity or fragment"); } return instance; } private static drivervehiclepickersdialogfragment createinstance(listenertype listenertype, bundle dialogsettings) { drivervehiclepickersdialogfragment fragment = new drivervehiclepickersdialogfragment(); if (!dialogsettings.containskey(arg_listener_type)) { dialogsettings.putserializable(arg_listener_type, listenertype); } if (!dialogsettings.containskey(arg_dialog_type)) { dialogsettings.putserializable(arg_dialog_type, dialogtype.driver_vehicle_spinner); } if (!dialogsettings.containskey(arg_title_resource)) { dialogsettings.putint(arg_title_resource, 0); } fragment.setarguments(dialogsettings); return fragment; } @override public void onattach(activity activity) { super.onattach(activity); // find out how dialoglistener instance send callback events bundle args = getarguments(); listenertype listenertype = (listenertype) args.getserializable(arg_listener_type); switch (listenertype) { case activity: { // send callback events hosting activity mlistener = (drivervehicledialoglistener) activity; break; } case fragment: { // send callback events "target" fragment mlistener = (drivervehicledialoglistener) gettargetfragment(); break; } } } @override public void onactivitycreated(bundle savedinstancestate) { // todo auto-generated method stub super.onactivitycreated(savedinstancestate); button btnadddrivervehicle = (button) mview.findviewbyid(r.id.adddrivervehiclebutton); btnadddrivervehicle.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { databasehelper1 mopenhelper = new databasehelper1(getactivity()); try { sqlitedatabase db = mopenhelper.getwritabledatabase(); db.delete("drivers", " driver_number = 70", null); } catch (sqlexception e) { } } }); } @override public dialog oncreatedialog(bundle savedinstancestate) { super.onsaveinstancestate(savedinstancestate); bundle args = getarguments(); int titleresource = args.getint(arg_title_resource); dialogtype dialogtype = (dialogtype) args.getserializable(arg_dialog_type); if (args.containskey(arg_set_driver)) { mdrivers = args.getlongarray(arg_set_driver); } if (args.containskey(arg_set_vehicle)) { mvehicles = args.getlongarray(arg_set_vehicle); } mview = layoutinflater.from(getactivity()).inflate(r.layout.driver_vehicle_dialog, null); if ((dialogtype == dialogtype.driver_spinner) || (dialogtype == dialogtype.driver_vehicle_spinner)) { driversspinner = (spinner) mview.findviewbyid(r.id.driversspinner); vehiclesspinner = (spinner) mview.findviewbyid(r.id.vehiclesspinner); driversspinner.setvisibility(view.visible); mdriversadapter = new simplecursoradapter(getactivity(), r.layout.driver_listview_row, null, new string[] { consolecontract.drivers.driver_number, consolecontract.drivers.driver_name }, new int[] { r.id.driver_number, r.id.driver_name }, 0); driversspinner.setadapter(mdriversadapter); driversspinner.setonitemselectedlistener(this); } if ((dialogtype == dialogtype.vehicle_spinner) || (dialogtype == dialogtype.driver_vehicle_spinner)) { vehiclesspinner.setvisibility(view.visible); mvehiclesadapter = new simplecursoradapter(getactivity(), r.layout.vehicle_listview_row, null, new string[] { consolecontract.vehicles.vehicle_number, consolecontract.vehicles.vehicle_vin }, new int[] { r.id.vehicle_number, r.id.vehicle_vin }, 0); vehiclesspinner.setadapter(mvehiclesadapter); vehiclesspinner.setonitemselectedlistener(this); } // prepare loader. either re-connect existing one, or start new one. getloadermanager().initloader(drivers_loader, null, this); getloadermanager().initloader(vehicles_loader, null, this); alertdialog.builder builder = new alertdialog.builder(getactivity()); builder.setview(mview); if (titleresource == 0) { builder.setmessage("select driver , vehicle"); } else { builder.setmessage(getstring(titleresource)); } builder.setpositivebutton(android.r.string.ok, new onclicklistener() { public void onclick(dialoginterface dialog, int which) { mlistener.ondialogpositiveclick(mdrivers, mvehicles); } }); builder.setnegativebutton(android.r.string.cancel, null); return builder.create(); } private static class databasehelper1 extends sqliteopenhelper { private static final string database_name = "test.db"; private static final int database_version = 1; databasehelper1(context context) { super(context, database_name, null, database_version); } @override public void oncreate(sqlitedatabase db) { } @override public void onupgrade(sqlitedatabase db, int oldversion, int newversion) { } } @override public void ondetach() { super.ondetach(); mlistener = null; } // these contacts rows retrieve. static final string[] drivers_summary_projection = new string[] { consolecontract.drivers._id, consolecontract.drivers.driver_id, consolecontract.drivers.driver_number, consolecontract.drivers.driver_name }; static final string[] vehicles_summary_projection = new string[] { consolecontract.vehicles._id, consolecontract.vehicles.vehicle_id, consolecontract.vehicles.vehicle_number, consolecontract.vehicles.vehicle_vin }; @override public loader<cursor> oncreateloader(int id, bundle args) { // called when new loader needs created. // sample has 1 loader, don't care id. // first, pick base uri use depending on whether // filtering. uri baseuri = null; string select = null, sortorder = null; string[] projection = null; switch (id) { case drivers_loader: baseuri = consolecontract.drivers.content_uri; select = "((" + drivers.driver_name + " not null) , (" + drivers.driver_name + " != '' ))"; sortorder = drivers.driver_number; projection = drivers_summary_projection; break; case vehicles_loader: baseuri = consolecontract.vehicles.content_uri; select = "((" + vehicles.vehicle_number + " not null) , (" + vehicles.vehicle_number + " != '' ))"; sortorder = vehicles.vehicle_number; projection = vehicles_summary_projection; break; } return new cursorloader(getactivity(), baseuri, projection, select, null, sortorder); } @override public void onloadfinished(loader<cursor> loader, cursor data) { // swap new cursor in. (the framework take care of closing // old cursor once return.) int id = loader.getid(); matrixcursor newcursor = null; switch (id) { case drivers_loader: newcursor = new matrixcursor(drivers_summary_projection); break; case vehicles_loader: newcursor = new matrixcursor(vehicles_summary_projection); break; } newcursor.addrow(new string[] { "0", "0", "", "" }); cursor[] cursors = { newcursor, data }; cursor mergedcursor = new mergecursor(cursors); switch (id) { case drivers_loader: mdriversadapter.swapcursor(mergedcursor); break; case vehicles_loader: mvehiclesadapter.swapcursor(mergedcursor); break; } } @override public void onloaderreset(loader<cursor> loader) { // called when last cursor provided onloadfinished() // above closed. need make sure no // longer using it. int id = loader.getid(); switch (id) { case drivers_loader: mdriversadapter.swapcursor(null); break; case vehicles_loader: mvehiclesadapter.swapcursor(null); break; } } @override public void onitemselected(adapterview<?> parent, view view, int pos, long id) { if (parent.getid() == r.id.driversspinner) { mdriver = id; } else { mvehicle = id; } } @override public void onnothingselected(adapterview<?> parent) { } }
make sure in contentprovider
call notifychange()
method inside insert, delete , update methods.
here snippet taken grokking android blog
public uri insert(uri uri, contentvalues values) { if (uri_matcher.match(uri) != lentitem_list) { throw new illegalargumentexception("unsupported uri insertion: " + uri); } long id = db.insert(dbschema.tbl_items, null, values); if (id > 0) { // notify listeners of changes , return itemuri: uri itemuri = contenturis.withappendedid(uri, id); getcontext().getcontentresolver().notifychange(itemuri, null); return itemuri; } // s.th. went wrong: throw new sqlexception("problem while inserting " + dbschema.tbl_items + ", uri: " + uri); // use exception here!!! }
conversely loader won't "heard" db changes.
Comments
Post a Comment