2016-10-11 3 views
1

Gestern fragte ich this Frage, wo ich einige statische Daten über einen Inhaltsanbieter zu SQLite legte. Jetzt möchte ich noch einen Schritt weiter gehen. Ich lade einige Daten von einem Webserver (mit Volley) herunter und speichere sie erneut in SQLite. Als nächstes möchte ich sie mit einem CursorLoader lesen. Allerdings kann ich die Titel der Bilder nur in der Gridview anzeigen. Lass mich also mit meinem Code beginnen.Gespeichertes Bild in SQLite wird in Gridview nicht angezeigt

MainActivityFragment

public class MainActivityFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>{ 
static public ArrayList<MyCity> cityList; 

private static final String LOG_TAG = MainActivityFragment.class.getSimpleName(); 
private MyCityAdpapter myCityAdpapter; 
private static final int CURSOR_LOADER_ID = 0; 
private GridView mGridView; 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

} 

public MainActivityFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    Cursor c = 
      getActivity().getContentResolver().query(MyCityContract.MyCityEntry.CONTENT_URI, 
        new String[]{MyCityContract.MyCityEntry._ID}, 
        null, 
        null, 
        null); 
    if (c.getCount() == 0){ 
     updateImagesList(); 
    } 
    // initialize loader 
    getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this); 
    super.onActivityCreated(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    // inflate fragment_main layout 
    final View rootView = inflater.inflate(R.layout.fragment_main_activity, container, false); 

    cityList = new ArrayList<>(); 

    // initialize our FlavorAdapter 
    myCityAdpapter = new MyCityAdpapter(getActivity(), null, 0, CURSOR_LOADER_ID); 
    // initialize mGridView to the GridView in fragment_main.xml 
    mGridView = (GridView) rootView.findViewById(R.id.flavors_grid); 
    // set mGridView adapter to our CursorAdapter 
    mGridView.setAdapter(myCityAdpapter); 

    return rootView; 

} 


@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args){ 
    return new CursorLoader(getActivity(), 
      MyCityContract.MyCityEntry.CONTENT_URI, 
      null, 
      null, 
      null, 
      null); 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    myCityAdpapter.swapCursor(data); 
} 
public void updateImagesList() { 


    // Instantiate the RequestQueue. 
    RequestQueue queue = Volley.newRequestQueue(getActivity()); 

    // Request a string response from the provided URL. 
    JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, API.API_URL, new Response.Listener<JSONArray>() { 

     @Override 
     public void onResponse(JSONArray response) { 
      cityList.clear(); 
      Log.d(TAG, response.toString()); 
      //hidePD(); 

      // Parse json data. 
      // Declare the json objects that we need and then for loop through the children array. 
      // Do the json parse in a try catch block to catch the exceptions 
      try { 

       for (int i = 0; i < response.length(); i++) { 
        //insert images information into the database 
        JSONObject post = response.getJSONObject(i); 

        MyCity item = new MyCity(); 
        item.setName(post.getString("title")); 
        item.setImage(API.IMAGE_URL + post.getString("image")); 

        ContentValues imageValues = new ContentValues(); 

        imageValues.put(MyCityContract.MyCityEntry._ID, post.getString("id")); 
        imageValues.put(MyCityContract.MyCityEntry.COLUMN_NAME, post.getString("title")); 
        imageValues.put(MyCityContract.MyCityEntry.COLUMN_ICON, post.getString("image")); 

        getActivity().getContentResolver().insert(MyCityContract.MyCityEntry.CONTENT_URI, imageValues); 

        cityList.add(item); 
       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

      // Update list by notifying the adapter of changes 
      myCityAdpapter.notifyDataSetChanged(); 
     } 
    }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      VolleyLog.d(TAG, "Error: " + error.getMessage()); 
      //hidePD(); 
     } 
    }); 
    queue.add(jsObjRequest); 

} 

@Override 
public void onLoaderReset(Loader<Cursor> loader){ 
    myCityAdpapter.swapCursor(null); 
} 

}

MyCityAdapter

public class MyCityAdpapter extends CursorAdapter { 
private static final String LOG_TAG = MyCityAdpapter.class.getSimpleName(); 
private Context mContext; 
private static int sLoaderID; 

public MyCityAdpapter(Context context, Cursor c, int flags,int loaderID) { 
    super(context, c, flags); 
    Log.d(LOG_TAG, "MyCityAdpapter"); 
    mContext = context; 
    sLoaderID = loaderID; 
} 
public static class ViewHolder { 
    public final ImageView imageView; 
    public final TextView textView; 

    public ViewHolder(View view){ 
     imageView = (ImageView) view.findViewById(R.id.flavor_image); 
     textView = (TextView) view.findViewById(R.id.flavor_text); 
    } 
} 
@Override 
public View newView(Context context, Cursor cursor, ViewGroup parent) { 
    int layoutId = R.layout.flavor_item; 

    Log.d(LOG_TAG, "In new View"); 

    View view = LayoutInflater.from(context).inflate(layoutId, parent, false); 
    ViewHolder viewHolder = new ViewHolder(view); 
    view.setTag(viewHolder); 

    return view; 
} 

@Override 
public void bindView(View view, Context context, Cursor cursor) { 
    ViewHolder viewHolder = (ViewHolder) view.getTag(); 

    Log.d(LOG_TAG, "In bind View"); 

    int versionIndex = cursor.getColumnIndex(MyCityContract.MyCityEntry.COLUMN_NAME); 
    final String versionName = cursor.getString(versionIndex); 
    Log.i(LOG_TAG, "Text reference extracted: " + versionName); 
    viewHolder.textView.setText(versionName); 

    int imageIndex = cursor.getColumnIndex(MyCityContract.MyCityEntry.COLUMN_ICON); 
    int image = cursor.getInt(imageIndex); 
    Log.i(LOG_TAG, "Image reference extracted: " + image); 

    viewHolder.imageView.setImageResource(image); 
    } 
} 

Plese daran denkt, dass die logcat dieser Klasse gibt mir

I/MyCityAdpapter: Text reference extracted: Ancient Theatre - Larissa 
I/MyCityAdpapter: Image reference extracted: 0 
I/MyCityAdpapter: Text reference extracted: Old trains 
I/MyCityAdpapter: Image reference extracted: 0 

und so weiter.

MyCityContract

public class MyCityContract { 

public static final String CONTENT_AUTHORITY = "theo.testing.customloaders.app"; 

public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); 

public static final class MyCityEntry implements BaseColumns{ 
    //table name 
    public static final String TABLE_MY_CITY = "my_city"; 
    //columns 
    public static final String _ID = "_id"; 
    public static final String COLUMN_NAME = "name"; 
    public static final String COLUMN_ICON = "icon"; 

    // create content uri 
    public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon() 
      .appendPath(TABLE_MY_CITY).build(); 
    // create cursor of base type directory for multiple entries 
    public static final String CONTENT_DIR_TYPE = 
      ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + TABLE_MY_CITY; 
    // create cursor of base type item for single entry 
    public static final String CONTENT_ITEM_TYPE = 
      ContentResolver.CURSOR_ITEM_BASE_TYPE +"/" + CONTENT_AUTHORITY + "/" + TABLE_MY_CITY; 

    // for building URIs on insertion 
    public static Uri buildFlavorsUri(long id){ 
     return ContentUris.withAppendedId(CONTENT_URI, id); 
    } 

    } 
} 

Vielleicht gibt es etwas falsch mit meiner MyCityDbHelperClass, wo ich alle Daten speichern.

public class MyCityDbHelper extends SQLiteOpenHelper{ 
public static final String LOG_TAG = MyCityDbHelper.class.getSimpleName(); 
//name & version 
public static final String DATABASE_NAME = "city.db"; 
public static final int DATABASE_VERSION = 7; 
// Create the database 
public MyCityDbHelper(Context context) { 
    super(context, DATABASE_NAME,null,DATABASE_VERSION); 
} 

@Override 
public void onCreate(SQLiteDatabase sqLiteDatabase) { 
    final String SQL_CREATE_MY_CITY_TABLE = "CREATE TABLE " + 
      MyCityContract.MyCityEntry.TABLE_MY_CITY + "(" + MyCityContract.MyCityEntry._ID + 
      " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
      MyCityContract.MyCityEntry.COLUMN_NAME + " TEXT NOT NULL, " + 
      MyCityContract.MyCityEntry.COLUMN_ICON + " INTEGER NOT NULL);"; 


    sqLiteDatabase.execSQL(SQL_CREATE_MY_CITY_TABLE); 
} 

@Override 
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { 
    Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to " + 
      newVersion + ". OLD DATA WILL BE DESTROYED"); 
    // Drop the table 
    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + MyCityContract.MyCityEntry.TABLE_MY_CITY); 
    sqLiteDatabase.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + 
      MyCityContract.MyCityEntry.TABLE_MY_CITY + "'"); 

    // re-create database 
    onCreate(sqLiteDatabase); 
} 
} 

und schließlich habe ich meinen Provider.

public class MyCityProvider extends ContentProvider { 
private static final String LOG_TAG = MyCityProvider.class.getSimpleName(); 
private static final UriMatcher sUriMatcher = buildUriMatcher(); 
private MyCityDbHelper myCityDbHelper; 

//Codes for UriMatcher 
private static final int MY_CITY = 100; 
private static final int MY_CITY_WITH_ID = 200; 


private static UriMatcher buildUriMatcher(){ 
    // Build a UriMatcher by adding a specific code to return based on a match 
    // It's common to use NO_MATCH as the code for this case. 
    final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); 
    final String authority = MyCityContract.CONTENT_AUTHORITY; 

    //add code for each URI 
    matcher.addURI(authority,MyCityContract.MyCityEntry.TABLE_MY_CITY,MY_CITY); 
    matcher.addURI(authority,MyCityContract.MyCityEntry.TABLE_MY_CITY + "/#",MY_CITY_WITH_ID); 

    return matcher; 

} 
@Override 
public boolean onCreate() { 
    myCityDbHelper = new MyCityDbHelper(getContext()); 

    return true; 
} 

@Override 
public String getType(Uri uri) { 
    final int match = sUriMatcher.match(uri); 

    switch (match){ 
     case MY_CITY: { 
      return MyCityContract.MyCityEntry.CONTENT_DIR_TYPE; 
     } 
     case MY_CITY_WITH_ID:{ 
      return MyCityContract.MyCityEntry.CONTENT_ITEM_TYPE; 

     } 
     default:{ 
      throw new UnsupportedOperationException("Unknown uri: " + uri); 
     } 
    } 
} 
@Override 
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){ 
    Cursor retCursor; 
    switch(sUriMatcher.match(uri)){ 
     // All Flavors selected 
     case MY_CITY:{ 
      retCursor = myCityDbHelper.getReadableDatabase().query(
        MyCityContract.MyCityEntry.TABLE_MY_CITY, 
        projection, 
        selection, 
        selectionArgs, 
        null, 
        null, 
        sortOrder); 
      return retCursor; 
     } 
     // Individual flavor based on Id selected 
     case MY_CITY_WITH_ID:{ 
      retCursor = myCityDbHelper.getReadableDatabase().query(
        MyCityContract.MyCityEntry.TABLE_MY_CITY, 
        projection, 
        MyCityContract.MyCityEntry._ID + " = ?", 
        new String[] {String.valueOf(ContentUris.parseId(uri))}, 
        null, 
        null, 
        sortOrder); 
      return retCursor; 
     } 
     default:{ 
      // By default, we assume a bad URI 
      throw new UnsupportedOperationException("Unknown uri: " + uri); 
     } 
    } 
} 




@Override 
public Uri insert(Uri uri, ContentValues contentValues) { 
    final SQLiteDatabase db = myCityDbHelper.getWritableDatabase(); 

    Uri returnUri; 

    switch (sUriMatcher.match(uri)){ 
     case MY_CITY: 

      long _id = db.insertWithOnConflict(MyCityContract.MyCityEntry.TABLE_MY_CITY,null,contentValues,SQLiteDatabase.CONFLICT_REPLACE); 
      Log.d("id",String.valueOf(_id)); 
      // insert unless it is already contained in the database 
      if(_id>0){ 
       returnUri = MyCityContract.MyCityEntry.buildFlavorsUri(_id); 
      }else { 
       throw new android.database.SQLException("Failed to insert row into: " + uri); 
      } 
      break; 
     default: { 
      throw new UnsupportedOperationException("Unknown uri: " + uri); 
     } 
    } 

    getContext().getContentResolver().notifyChange(uri,null); 
    return returnUri; 
} 

@Override 
public int delete(Uri uri, String selection, String[] selectionArgs) { 
    final SQLiteDatabase db = myCityDbHelper.getWritableDatabase(); 
    final int match = sUriMatcher.match(uri); 
    int numDeleted; 
    switch(match){ 
     case MY_CITY: 
      numDeleted = db.delete(
        MyCityContract.MyCityEntry.TABLE_MY_CITY, selection, selectionArgs); 
      // reset _ID 
      db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + 
        MyCityContract.MyCityEntry.TABLE_MY_CITY + "'"); 
      break; 
     case MY_CITY_WITH_ID: 
      numDeleted = db.delete(MyCityContract.MyCityEntry.TABLE_MY_CITY, 
        MyCityContract.MyCityEntry._ID + " = ?", 
        new String[]{String.valueOf(ContentUris.parseId(uri))}); 
      // reset _ID 
      db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + 
        MyCityContract.MyCityEntry.TABLE_MY_CITY + "'"); 

      break; 
     default: 
      throw new UnsupportedOperationException("Unknown uri: " + uri); 
    } 

    return numDeleted; 
} 


@Override 
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs){ 
    final SQLiteDatabase db = myCityDbHelper.getWritableDatabase(); 
    int numUpdated = 0; 

    if (contentValues == null){ 
     throw new IllegalArgumentException("Cannot have null content values"); 
    } 

    switch(sUriMatcher.match(uri)){ 
     case MY_CITY:{ 
      numUpdated = db.update(MyCityContract.MyCityEntry.TABLE_MY_CITY, 
        contentValues, 
        selection, 
        selectionArgs); 
      break; 
     } 
     case MY_CITY_WITH_ID: { 
      numUpdated = db.update(MyCityContract.MyCityEntry.TABLE_MY_CITY, 
        contentValues, 
        MyCityContract.MyCityEntry._ID + " = ?", 
        new String[] {String.valueOf(ContentUris.parseId(uri))}); 
      break; 
     } 
     default:{ 
      throw new UnsupportedOperationException("Unknown uri: " + uri); 
     } 
    } 

    if (numUpdated > 0){ 
     getContext().getContentResolver().notifyChange(uri, null); 
    } 

    return numUpdated; 
    } 
} 

Also warum ist das Bild nicht da? Ich wollte immer das Problem der Speicherung von dynamischen Daten lösen und sie auch im Offline-Modus lesen :).

Danke,

Theo.

Antwort

1

Sie speichern Bild URL in Ihrer Datenbank, aber Sie lesen eine Ganzzahl in Ihrem MyCityAdapter. Sie müssen die Image-URL erneut in bindView() Methode abrufen. Sobald Sie die URL des Bildes erhalten haben, müssen Sie das Bild selbst herunterladen und speichern. Aber es ist nicht nötig, alles selbst zu schreiben. Ich empfehle Picasso Bibliothek. Sobald Sie diese Bibliothek zu Ihrem dependecies hinzufügen, können Sie Bild auf Ihren Imageview wie folgt festgelegt: Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

So, Ihr bindView() Methode Körper so etwas wie dies sein wird:

@Override 
public void bindView(View view, Context context, Cursor cursor) { 
    ViewHolder viewHolder = (ViewHolder) view.getTag(); 

    Log.d(LOG_TAG, "In bind View"); 

    int versionIndex = cursor.getColumnIndex(MyCityContract.MyCityEntry.COLUMN_NAME); 
    final String versionName = cursor.getString(versionIndex); 
    Log.i(LOG_TAG, "Text reference extracted: " + versionName); 
    viewHolder.textView.setText(versionName); 

    int imageIndex = cursor.getColumnIndex(MyCityContract.MyCityEntry.COLUMN_ICON); 
    String imageUrl = cursor.getString(imageIndex); 
    Log.i(LOG_TAG, "Image reference extracted: " + image); 

    Picasso.with(context).load(imageUrl).into(viewHolder.imageView); 
} 
+0

Danke für die Hilfe, aber ich habe noch habe das gleiche Problem :( – Theo

+0

Es heißt in meinem logcat I/MyCityAdapter: Bildreferenz extrahiert: larissa1.png, I/MyCityAdapter: Bildreferenz extrahiert: larissa2.png etc aber kann sie nicht in der gridview.lol. – Theo

+0

und wo sind diese Bilder? – egoldx