Monday, March 13, 2017

Using Local Json File To Load Data

Some relatively small amounts of data can be stored as json files in the assets directory. This makes the data easier to update than packaging it in an app database or hard coding it in Java objects. I used json to store information about the OpenStax books that are displayed when the app opens. A snippet of the json is below:

{ "bookList":[ { "bookTitle":"College Physics", "title":"College Physics", "contentString":"This introductory, algebra-based, two-semester college physics book is grounded with real-world examples, illustrations, and explanations to help students grasp key, fundamental physics concepts. This online, fully editable and customizable title includes learning objectives, concept questions, links to labs and simulations, and ample practice opportunities to solve traditional physics application problems.", "url":"", "bookUrl":"", "icon":"physics" }, { "bookTitle":"Introduction to Sociology 2e", "title":"Introduction to Sociology 2e", "contentString":"Introduction to Sociology 2e adheres to the scope and sequence of a typical introductory sociology course. In addition to comprehensive coverage of core concepts, foundational scholars, and emerging theories we have incorporated section reviews with engaging questions, discussions that help students apply the sociological imagination, and features that draw learners into the discipline in meaningful ways", "url":"", "bookUrl":"", "icon":"sociology2e" }, { "bookTitle":"Biology", "title":"Biology", "contentString":"Biology is designed for multi-semester biology courses for science majors. It is grounded on an evolutionary basis and includes exciting features that highlight careers in the biological sciences and everyday applications of the concepts at hand.", "url":"", "bookUrl":"", "icon":"biology" }, ... ] }

The json is stored in the assets folder inside the src/main directory. I created 2 objects to deal with the json file: BookList which contains an ArrayList of Content objects. Each Content object is a book from the list. Gson is the library used to read the json file into a BookList object. Gson must be added to the file

compile ''

The json file is read in a Fragment.

private BookList readJson()
    AssetManager assets = getActivity().getAssets();
    BookList bookList = new BookList();

    Gson gson = new Gson();

        InputStream is ="bookList.json");
        BufferedReader bf = new BufferedReader(new InputStreamReader(is));
        bookList = gson.fromJson(bf,BookList.class);
    catch(IOException ioe)
        Log.d("json", "Some problem: " + ioe.toString());


    return bookList;

The data in the objects is used to populate a RecyclerViewAdapter.

public void onBindViewHolder(final ViewHolder holder, int position)
    Content book = contentList.get(position);
    if (holder.logo != null && book.getIcon() != null)
        holder.logo.setImageResource(OSCUtil.getCoverId(book.getIcon(), context));


The source code for the OpenStax app is available on Github. Look for the code discussed here in the LandingListFragment and LandingListRecyclerViewAdapter classes.

Thursday, January 26, 2017

Remember Where Readers Left Off

Apps that allow users to read books need to remember where the reader left off the last time the book was read. In Android, this is very easy to do using SharedPreferences.

Because of the Android lifecycle, there are 3 places to deal with the previous location.

1. In the onPause() method, store the current URL in SharedPreferences using the name of the icon as a unique identifier.

protected void onPause()
    SharedPreferences sharedPref = getSharedPreferences(getString(R.string.osc_package),MODE_PRIVATE);
    SharedPreferences.Editor ed = sharedPref.edit();
    if(webView != null && content != null)
        String url = webView.getUrl().replace("?bookmark=1", "");
        ed.putString(content.getIcon(), url);

2. In onCreate(), SharedPreferences is checked for a previous URL. If one is available, it is used.

SharedPreferences sharedPref = getSharedPreferences(getString(R.string.osc_package), MODE_PRIVATE);
String url = sharedPref.getString(content.getIcon(), "");

3. In onResume(), SharedPreferences is checked for a previous URL. If one is available, it is used.

It is very simple solution that allows the reader to continue where they left off without creating a bookmark. The code is in the WebViewActivity class of the OpenStax app. The code is available on Github .