· 9 years ago · Oct 11, 2016, 03:24 PM
1public class MainActivityFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>{
2static public ArrayList<MyCity> cityList;
3
4private static final String LOG_TAG = MainActivityFragment.class.getSimpleName();
5private MyCityAdpapter myCityAdpapter;
6private static final int CURSOR_LOADER_ID = 0;
7private GridView mGridView;
8
9
10@Override
11public void onCreate(Bundle savedInstanceState) {
12 super.onCreate(savedInstanceState);
13
14}
15
16public MainActivityFragment() {
17 // Required empty public constructor
18}
19
20@Override
21public void onActivityCreated(Bundle savedInstanceState) {
22 Cursor c =
23 getActivity().getContentResolver().query(MyCityContract.MyCityEntry.CONTENT_URI,
24 new String[]{MyCityContract.MyCityEntry._ID},
25 null,
26 null,
27 null);
28 if (c.getCount() == 0){
29 updateImagesList();
30 }
31 // initialize loader
32 getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);
33 super.onActivityCreated(savedInstanceState);
34}
35
36@Override
37public View onCreateView(LayoutInflater inflater, ViewGroup container,
38 Bundle savedInstanceState) {
39 // Inflate the layout for this fragment
40 // inflate fragment_main layout
41 final View rootView = inflater.inflate(R.layout.fragment_main_activity, container, false);
42
43 cityList = new ArrayList<>();
44
45 // initialize our FlavorAdapter
46 myCityAdpapter = new MyCityAdpapter(getActivity(), null, 0, CURSOR_LOADER_ID);
47 // initialize mGridView to the GridView in fragment_main.xml
48 mGridView = (GridView) rootView.findViewById(R.id.flavors_grid);
49 // set mGridView adapter to our CursorAdapter
50 mGridView.setAdapter(myCityAdpapter);
51
52 return rootView;
53
54}
55
56
57@Override
58public Loader<Cursor> onCreateLoader(int id, Bundle args){
59 return new CursorLoader(getActivity(),
60 MyCityContract.MyCityEntry.CONTENT_URI,
61 null,
62 null,
63 null,
64 null);
65}
66
67@Override
68public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
69 myCityAdpapter.swapCursor(data);
70}
71public void updateImagesList() {
72
73
74 // Instantiate the RequestQueue.
75 RequestQueue queue = Volley.newRequestQueue(getActivity());
76
77 // Request a string response from the provided URL.
78 JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, API.API_URL, new Response.Listener<JSONArray>() {
79
80 @Override
81 public void onResponse(JSONArray response) {
82 cityList.clear();
83 Log.d(TAG, response.toString());
84 //hidePD();
85
86 // Parse json data.
87 // Declare the json objects that we need and then for loop through the children array.
88 // Do the json parse in a try catch block to catch the exceptions
89 try {
90
91 for (int i = 0; i < response.length(); i++) {
92 //insert images information into the database
93 JSONObject post = response.getJSONObject(i);
94
95 MyCity item = new MyCity();
96 item.setName(post.getString("title"));
97 item.setImage(API.IMAGE_URL + post.getString("image"));
98
99 ContentValues imageValues = new ContentValues();
100
101 imageValues.put(MyCityContract.MyCityEntry._ID, post.getString("id"));
102 imageValues.put(MyCityContract.MyCityEntry.COLUMN_NAME, post.getString("title"));
103 imageValues.put(MyCityContract.MyCityEntry.COLUMN_ICON, post.getString("image"));
104
105 getActivity().getContentResolver().insert(MyCityContract.MyCityEntry.CONTENT_URI, imageValues);
106
107 cityList.add(item);
108 }
109 } catch (JSONException e) {
110 e.printStackTrace();
111 }
112
113 // Update list by notifying the adapter of changes
114 myCityAdpapter.notifyDataSetChanged();
115 }
116 }, new Response.ErrorListener() {
117 @Override
118 public void onErrorResponse(VolleyError error) {
119 VolleyLog.d(TAG, "Error: " + error.getMessage());
120 //hidePD();
121 }
122 });
123 queue.add(jsObjRequest);
124
125}
126
127@Override
128public void onLoaderReset(Loader<Cursor> loader){
129 myCityAdpapter.swapCursor(null);
130}
131
132public class MyCityAdpapter extends CursorAdapter {
133private static final String LOG_TAG = MyCityAdpapter.class.getSimpleName();
134private Context mContext;
135private static int sLoaderID;
136
137public MyCityAdpapter(Context context, Cursor c, int flags,int loaderID) {
138 super(context, c, flags);
139 Log.d(LOG_TAG, "MyCityAdpapter");
140 mContext = context;
141 sLoaderID = loaderID;
142}
143public static class ViewHolder {
144 public final ImageView imageView;
145 public final TextView textView;
146
147 public ViewHolder(View view){
148 imageView = (ImageView) view.findViewById(R.id.flavor_image);
149 textView = (TextView) view.findViewById(R.id.flavor_text);
150 }
151}
152@Override
153public View newView(Context context, Cursor cursor, ViewGroup parent) {
154 int layoutId = R.layout.flavor_item;
155
156 Log.d(LOG_TAG, "In new View");
157
158 View view = LayoutInflater.from(context).inflate(layoutId, parent, false);
159 ViewHolder viewHolder = new ViewHolder(view);
160 view.setTag(viewHolder);
161
162 return view;
163}
164
165@Override
166public void bindView(View view, Context context, Cursor cursor) {
167 ViewHolder viewHolder = (ViewHolder) view.getTag();
168
169 Log.d(LOG_TAG, "In bind View");
170
171 int versionIndex = cursor.getColumnIndex(MyCityContract.MyCityEntry.COLUMN_NAME);
172 final String versionName = cursor.getString(versionIndex);
173 Log.i(LOG_TAG, "Text reference extracted: " + versionName);
174 viewHolder.textView.setText(versionName);
175
176 int imageIndex = cursor.getColumnIndex(MyCityContract.MyCityEntry.COLUMN_ICON);
177 int image = cursor.getInt(imageIndex);
178 Log.i(LOG_TAG, "Image reference extracted: " + image);
179
180 viewHolder.imageView.setImageResource(image);
181 }
182}
183
184I/MyCityAdpapter: Text reference extracted: Ancient Theatre - Larissa
185I/MyCityAdpapter: Image reference extracted: 0
186I/MyCityAdpapter: Text reference extracted: Old trains
187I/MyCityAdpapter: Image reference extracted: 0
188
189public class MyCityContract {
190
191public static final String CONTENT_AUTHORITY = "theo.testing.customloaders.app";
192
193public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
194
195public static final class MyCityEntry implements BaseColumns{
196 //table name
197 public static final String TABLE_MY_CITY = "my_city";
198 //columns
199 public static final String _ID = "_id";
200 public static final String COLUMN_NAME = "name";
201 public static final String COLUMN_ICON = "icon";
202
203 // create content uri
204 public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
205 .appendPath(TABLE_MY_CITY).build();
206 // create cursor of base type directory for multiple entries
207 public static final String CONTENT_DIR_TYPE =
208 ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + TABLE_MY_CITY;
209 // create cursor of base type item for single entry
210 public static final String CONTENT_ITEM_TYPE =
211 ContentResolver.CURSOR_ITEM_BASE_TYPE +"/" + CONTENT_AUTHORITY + "/" + TABLE_MY_CITY;
212
213 // for building URIs on insertion
214 public static Uri buildFlavorsUri(long id){
215 return ContentUris.withAppendedId(CONTENT_URI, id);
216 }
217
218 }
219}
220
221public class MyCityDbHelper extends SQLiteOpenHelper{
222public static final String LOG_TAG = MyCityDbHelper.class.getSimpleName();
223//name & version
224public static final String DATABASE_NAME = "city.db";
225public static final int DATABASE_VERSION = 7;
226// Create the database
227public MyCityDbHelper(Context context) {
228 super(context, DATABASE_NAME,null,DATABASE_VERSION);
229}
230
231@Override
232public void onCreate(SQLiteDatabase sqLiteDatabase) {
233 final String SQL_CREATE_MY_CITY_TABLE = "CREATE TABLE " +
234 MyCityContract.MyCityEntry.TABLE_MY_CITY + "(" + MyCityContract.MyCityEntry._ID +
235 " INTEGER PRIMARY KEY AUTOINCREMENT, " +
236 MyCityContract.MyCityEntry.COLUMN_NAME + " TEXT NOT NULL, " +
237 MyCityContract.MyCityEntry.COLUMN_ICON + " INTEGER NOT NULL);";
238
239
240 sqLiteDatabase.execSQL(SQL_CREATE_MY_CITY_TABLE);
241}
242
243@Override
244public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
245 Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to " +
246 newVersion + ". OLD DATA WILL BE DESTROYED");
247 // Drop the table
248 sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + MyCityContract.MyCityEntry.TABLE_MY_CITY);
249 sqLiteDatabase.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" +
250 MyCityContract.MyCityEntry.TABLE_MY_CITY + "'");
251
252 // re-create database
253 onCreate(sqLiteDatabase);
254 }
255}
256
257public class MyCityProvider extends ContentProvider {
258private static final String LOG_TAG = MyCityProvider.class.getSimpleName();
259private static final UriMatcher sUriMatcher = buildUriMatcher();
260private MyCityDbHelper myCityDbHelper;
261
262//Codes for UriMatcher
263private static final int MY_CITY = 100;
264private static final int MY_CITY_WITH_ID = 200;
265
266
267private static UriMatcher buildUriMatcher(){
268 // Build a UriMatcher by adding a specific code to return based on a match
269 // It's common to use NO_MATCH as the code for this case.
270 final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
271 final String authority = MyCityContract.CONTENT_AUTHORITY;
272
273 //add code for each URI
274 matcher.addURI(authority,MyCityContract.MyCityEntry.TABLE_MY_CITY,MY_CITY);
275 matcher.addURI(authority,MyCityContract.MyCityEntry.TABLE_MY_CITY + "/#",MY_CITY_WITH_ID);
276
277 return matcher;
278
279}
280@Override
281public boolean onCreate() {
282 myCityDbHelper = new MyCityDbHelper(getContext());
283
284 return true;
285}
286
287@Override
288public String getType(Uri uri) {
289 final int match = sUriMatcher.match(uri);
290
291 switch (match){
292 case MY_CITY: {
293 return MyCityContract.MyCityEntry.CONTENT_DIR_TYPE;
294 }
295 case MY_CITY_WITH_ID:{
296 return MyCityContract.MyCityEntry.CONTENT_ITEM_TYPE;
297
298 }
299 default:{
300 throw new UnsupportedOperationException("Unknown uri: " + uri);
301 }
302 }
303}
304@Override
305public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
306 Cursor retCursor;
307 switch(sUriMatcher.match(uri)){
308 // All Flavors selected
309 case MY_CITY:{
310 retCursor = myCityDbHelper.getReadableDatabase().query(
311 MyCityContract.MyCityEntry.TABLE_MY_CITY,
312 projection,
313 selection,
314 selectionArgs,
315 null,
316 null,
317 sortOrder);
318 return retCursor;
319 }
320 // Individual flavor based on Id selected
321 case MY_CITY_WITH_ID:{
322 retCursor = myCityDbHelper.getReadableDatabase().query(
323 MyCityContract.MyCityEntry.TABLE_MY_CITY,
324 projection,
325 MyCityContract.MyCityEntry._ID + " = ?",
326 new String[] {String.valueOf(ContentUris.parseId(uri))},
327 null,
328 null,
329 sortOrder);
330 return retCursor;
331 }
332 default:{
333 // By default, we assume a bad URI
334 throw new UnsupportedOperationException("Unknown uri: " + uri);
335 }
336 }
337}
338
339
340
341
342@Override
343public Uri insert(Uri uri, ContentValues contentValues) {
344 final SQLiteDatabase db = myCityDbHelper.getWritableDatabase();
345
346 Uri returnUri;
347
348 switch (sUriMatcher.match(uri)){
349 case MY_CITY:
350
351 long _id = db.insertWithOnConflict(MyCityContract.MyCityEntry.TABLE_MY_CITY,null,contentValues,SQLiteDatabase.CONFLICT_REPLACE);
352 Log.d("id",String.valueOf(_id));
353 // insert unless it is already contained in the database
354 if(_id>0){
355 returnUri = MyCityContract.MyCityEntry.buildFlavorsUri(_id);
356 }else {
357 throw new android.database.SQLException("Failed to insert row into: " + uri);
358 }
359 break;
360 default: {
361 throw new UnsupportedOperationException("Unknown uri: " + uri );
362 }
363 }
364
365 getContext().getContentResolver().notifyChange(uri,null);
366 return returnUri;
367}
368
369@Override
370public int delete(Uri uri, String selection, String[] selectionArgs) {
371 final SQLiteDatabase db = myCityDbHelper.getWritableDatabase();
372 final int match = sUriMatcher.match(uri);
373 int numDeleted;
374 switch(match){
375 case MY_CITY:
376 numDeleted = db.delete(
377 MyCityContract.MyCityEntry.TABLE_MY_CITY, selection, selectionArgs);
378 // reset _ID
379 db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" +
380 MyCityContract.MyCityEntry.TABLE_MY_CITY + "'");
381 break;
382 case MY_CITY_WITH_ID:
383 numDeleted = db.delete(MyCityContract.MyCityEntry.TABLE_MY_CITY,
384 MyCityContract.MyCityEntry._ID + " = ?",
385 new String[]{String.valueOf(ContentUris.parseId(uri))});
386 // reset _ID
387 db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" +
388 MyCityContract.MyCityEntry.TABLE_MY_CITY + "'");
389
390 break;
391 default:
392 throw new UnsupportedOperationException("Unknown uri: " + uri);
393 }
394
395 return numDeleted;
396}
397
398
399@Override
400public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs){
401 final SQLiteDatabase db = myCityDbHelper.getWritableDatabase();
402 int numUpdated = 0;
403
404 if (contentValues == null){
405 throw new IllegalArgumentException("Cannot have null content values");
406 }
407
408 switch(sUriMatcher.match(uri)){
409 case MY_CITY:{
410 numUpdated = db.update(MyCityContract.MyCityEntry.TABLE_MY_CITY,
411 contentValues,
412 selection,
413 selectionArgs);
414 break;
415 }
416 case MY_CITY_WITH_ID: {
417 numUpdated = db.update(MyCityContract.MyCityEntry.TABLE_MY_CITY,
418 contentValues,
419 MyCityContract.MyCityEntry._ID + " = ?",
420 new String[] {String.valueOf(ContentUris.parseId(uri))});
421 break;
422 }
423 default:{
424 throw new UnsupportedOperationException("Unknown uri: " + uri);
425 }
426 }
427
428 if (numUpdated > 0){
429 getContext().getContentResolver().notifyChange(uri, null);
430 }
431
432 return numUpdated;
433 }
434}