0

I am in the process of making an app where I make a call to a web server, pull down the JSON data, parse it and save it to a SQLite database and show the information to the user.

The first page of the app just displays the movie poster, or so it is meant to! Whenever the app is freshly installed, the GridView never updates, but when it is closed and re-opened the movie posters are displaying as should be. I am not sure what I am doing wrong that it does not update when it is freshly installed.

Here is my code;

MainActivityFrament

public void update() {
    Log.e(LOG_TAG, "In onUpdate");
    FetchMovieTask movieTask = new FetchMovieTask(getContext());
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
    String userChoice = sharedPreferences.getString(getString(R.string.pref_sort_key), getString(R.string.pref_sort_value_mostpop));
    movieTask.execute(userChoice);
    progressBar.setVisibility(View.VISIBLE);
}

@Override
public void onStart() {
    super.onStart();
    Log.e(LOG_TAG, "In onStart");
    update();
}

@Override
public void onActivityCreated(Bundle savedInstanceState){
    Log.e(LOG_TAG, "In onActivityCreated");
    getLoaderManager().initLoader(MOVIE_LOADER, null, this);
    super.onActivityCreated(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.e(LOG_TAG, "In onCreateView");
    Cursor cursor = getActivity().getContentResolver().query(MovieContract.MovieEntry.CONTENT_URI, null, null, null, null);

    customAdapter = new CustomAdapter(getActivity(), cursor, 0);

    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    progressBar = (ProgressBar) rootView.findViewById(R.id.progressBar);
    gridView = (GridView) rootView.findViewById(R.id.gridView_movies);
    gridView.setAdapter(customAdapter);
    gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Cursor cursor = (Cursor) parent.getItemAtPosition(position);

            Log.i(LOG_TAG, "set movie object values");
            int _id = cursor.getInt(cursor.getColumnIndex(MovieContract.MovieEntry._ID));
            if (cursor != null) {
                Intent intent = new Intent(getActivity(), MovieDetailActivity.class);
                intent.putExtra("movieId", _id);
                Log.i(LOG_TAG, "About to start intent");
                startActivity(intent);
            }
        }

    });

    return rootView;
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    Log.e(LOG_TAG, "In onCreateLoader");
    return new CursorLoader(
            getActivity(),
            MovieContract.MovieEntry.CONTENT_URI,
            MOVIE_COLUMNS,
            null,
            null,
            null
    );
}


@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    Log.e(LOG_TAG, "In onLoadFinished");
    customAdapter.swapCursor(data);
}


@Override
public void onLoaderReset(Loader<Cursor> loader) {
    Log.e(LOG_TAG, "In onLoadReset");
    customAdapter.swapCursor(null);
}

CursorAdapter

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    Log.e(LOG_TAG, "In newView()");
    View view = LayoutInflater.from(context).inflate(R.layout.list_image_movie, parent, false);

    return view;
}


@Override
public void bindView(View view, Context context, Cursor cursor) {

    Log.e(LOG_TAG, "in bindView()");
    String title =cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_MOVIE_TITLE));
    Log.e(LOG_TAG, "Movie Title - " + title);

    ImageView iv = (ImageView) view.findViewById(R.id.list_movie_pics_imageview);

    int columIndex = cursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_POSTER);
    Bitmap image = Utility.getImage(cursor.getBlob(columIndex));

    iv.setImageBitmap(image);
}

AsyncTask

@Override
protected Void doInBackground(String... params) {
    Log.e(LOG_TAG, "In doInBackground");
    HttpURLConnection urlConnection = null;
    BufferedReader reader = null;

    String movieJsonStr = null;

    try {
       final String MOVIE_BASE_URL = "https://api.themoviedb.org/3/discover/movie?";
        final String SORT_PARAM = "sort_by";
        final String APIKEY_PARAM = "api_key";

        Uri builtUri = Uri.parse(MOVIE_BASE_URL).buildUpon()
                .appendQueryParameter(SORT_PARAM, params[0])
                .appendQueryParameter(APIKEY_PARAM, BuildConfig.OPEN_MOVIE_MAP_API_KEY)
                .build();

        URL url = new URL(builtUri.toString());

        Log.v(LOG_TAG, "Built URI :" + builtUri.toString());

        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();

        InputStream inputStream = urlConnection.getInputStream();

        StringBuffer buffer = new StringBuffer();
        if (inputStream == null) {
            return null;
        }

        reader = new BufferedReader(new InputStreamReader(inputStream));

        String line;
        while ((line = reader.readLine()) != null) {
            buffer.append(line + "\n");
        }

        if (buffer.length() == 0) {
            return null;
        }

        movieJsonStr = buffer.toString();
        parseMovieData(new JSONObject(movieJsonStr));
        checkDBValues(mContext);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (JSONException e) {
        e.printStackTrace();
    } finally {

        if (urlConnection != null) {
            urlConnection.disconnect();
        }

        if (reader != null) {
            try {
                reader.close();
            } catch (final IOException e) {
                Log.e(LOG_TAG, "Error closing stream", e);
            }
        }
    }
    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    Log.e(LOG_TAG, "In onPostExecute");
    customAdapter.notifyDataSetChanged();
    MainActivityFragment.progressBar.setVisibility(View.GONE);
}

public void parseMovieData(JSONObject movieData) {
    Log.e(LOG_TAG, "In parseMovieData");
    try {
        JSONArray movieArray = movieData.getJSONArray("results");

        Time dayTime = new Time();
        dayTime.setToNow();
        int julianStartDay = Time.getJulianDay(System.currentTimeMillis(), dayTime.gmtoff);

        if (movieArray != null) {
            for (int i = 0; i < movieArray.length(); i++) {
                JSONObject movies = movieArray.getJSONObject(i);

                long dateTime = dayTime.setJulianDay(julianStartDay + i);
                Bitmap moviePoster = Utility.getBitmapFromURL(CustomAdapter.IMAGE_BASE_URL + movies.getString(CustomAdapter.IMAGE_PATH));
                String moviePosterUrl = CustomAdapter.IMAGE_BASE_URL + movies.getString(CustomAdapter.IMAGE_PATH);
                String movieTitle = movies.getString(CustomAdapter.MOVIE_TITLE);
                String movieDescription = movies.getString(CustomAdapter.MOVIE_DESCRIPTION);
                double movieRating = movies.getDouble(CustomAdapter.MOVIE_RATING);
                String movieReleaseDate = movies.getString(CustomAdapter.MOVIE_RELEASE_DATE);

                ContentValues movieValues = new ContentValues();
                movieValues.put(MovieContract.MovieEntry.COLUMN_POSTER_URL, moviePosterUrl);
                movieValues.put(MovieContract.MovieEntry.COLUMN_POSTER, Utility.getBytes(moviePoster));
                movieValues.put(MovieContract.MovieEntry.COLUMN_RELEASE_DATE, movieReleaseDate);
                movieValues.put(MovieContract.MovieEntry.COLUMN_DESCRIPTION, movieDescription);
                movieValues.put(MovieContract.MovieEntry.COLUMN_MOVIE_RATING, movieRating);
                movieValues.put(MovieContract.MovieEntry.COLUMN_MOVIE_TITLE, movieTitle);
                movieValues.put(MovieContract.MovieEntry.COLUMN_DATE, dateTime);

                if (MovieProvider.rowExists(movieTitle)) {
                    continue;
                }

                insertMoviesToDB(movieValues);
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

public void insertMoviesToDB(ContentValues movieValues){
    Log.e(LOG_TAG, "In insertMoviesToDB");
    MovieProvider.mOpenHelper.getReadableDatabase().insert(MovieContract.MovieEntry.TABLE_NAME, null, movieValues);
}

public void checkDBValues(Context context) {
    Log.e(LOG_TAG, "In checkDBValues");
    Cursor cursor = context.getContentResolver().query(
            MovieContract.MovieEntry.CONTENT_URI,
            null,
            null,
            null,
            null
    );

    int count = 0;
    while (cursor.moveToNext()) {
        count++;
    }
    Log.i(LOG_TAG, "Got " + count + " values from the DB");
}

MainLayout

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:tools="http://schemas.android.com/tools"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         tools:context=".MainActivityFragment">

<GridView
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:verticalSpacing="0dp"
        android:horizontalSpacing="0dp"
        android:id="@+id/gridView_movies"
        android:layout_gravity="center"
        android:stretchMode="columnWidth"
        android:numColumns="2"/>

<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_gravity="center"
    android:visibility="gone" />

I think I have included all relevant information. There is no errors produced so no relevant logs are shown. If theres any extra information required please do ask and I will provide it.

Any information on this would be greatly appreciated

Dan
  • 2,020
  • 5
  • 32
  • 55

1 Answers1

1

In onPostExecute, notifyDatasetChanged will not work as data in your customAdapter's cursor is still same.

You need to get the new cursor with updated information and then call change cursor. So before of notifyDataSetChanged it should be something like this

Cursor newCursor = getActivity().getContentResolver().query(MovieContract.MovieEntry.CONTENT_URI, null, null, null, null);

customAdapter.changeCusrsor(newCursor);

customAdapter.notifyDataSetChanged();
Sarang
  • 61
  • 1
  • 6
  • I have tried to to this in the `onPostExecute` method but it doesnt allow me to call `getActivity()` – Dan Jun 01 '16 at 11:29
  • you just need a context to call getContentResolver, if getActivity() is not allowed then pass context to asynctask in constructor and use that context in onPostExecute – Sarang Jun 01 '16 at 12:07