Handle no books installed on start properly.

This commit is contained in:
Bradlee Speice 2014-09-03 22:49:18 -04:00
parent 54d0157785
commit 80238f3cf2
6 changed files with 150 additions and 68 deletions

View File

@ -0,0 +1,42 @@
package org.bspeice.minimalbible.test.activity.viewer;
import android.test.ActivityInstrumentationTestCase2;
import org.bspeice.minimalbible.Modules;
import org.bspeice.minimalbible.activity.viewer.BibleViewer;
import org.bspeice.minimalbible.activity.viewer.BookManager;
import org.crosswire.jsword.book.Book;
import java.util.ArrayList;
import rx.Observable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class BibleViewerTest extends ActivityInstrumentationTestCase2<BibleViewer> {
public BibleViewerTest() {
super(BibleViewer.class);
}
public void setUp() {
// For some reason this test requires us to set the dexcache...
System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext()
.getCacheDir().toString());
}
/**
* It may happen to be the case that we start and there are no installed books.
* This likely triggers a runtime exception from Rx, and is no excuse for dying.
*/
public void testInitializationNoInstalledBooks() {
BookManager mockBookManager = mock(BookManager.class);
when(mockBookManager.getInstalledBooks()).thenReturn(
Observable.from(new ArrayList<Book>()));
Modules.testModules.setBookManager(mockBookManager);
assertNotNull(getActivity());
}
}

View File

@ -25,6 +25,7 @@ import javax.inject.Inject;
import dagger.ObjectGraph; import dagger.ObjectGraph;
import rx.android.schedulers.AndroidSchedulers; import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1; import rx.functions.Action1;
import rx.functions.Func1;
public class BibleViewer extends BaseActivity implements public class BibleViewer extends BaseActivity implements
NavDrawerFragment.NavigationDrawerCallbacks, NavDrawerFragment.NavigationDrawerCallbacks,
@ -66,34 +67,41 @@ public class BibleViewer extends BaseActivity implements
bvObjectGraph.inject(o); bvObjectGraph.inject(o);
} }
/**
* Set up the application
* TODO: Get the main book, rather than the first installed book.
*
* @param savedInstanceState Android's savedInstanceState
*/
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
this.inject(this); this.inject(this);
// If no books are installed, we need to download one first. // If no books are installed, we need to download one first. However,
int count = bookManager.getInstalledBooks() // RxJava will error if there's nothing installed.
.count()
.toBlocking()
.last();
if (count <= 0) {
Intent i = new Intent(this, DownloadActivity.class);
startActivityForResult(i, 0);
finish();
} else {
bookManager.getInstalledBooks() bookManager.getInstalledBooks()
.first() .first()
.onErrorReturn(new Func1<Throwable, Book>() {
@Override
public Book call(Throwable throwable) {
// If there are no books installed...
Log.e(getLocalClassName(), "No books are currently installed, starting DownloadManager");
Intent i = new Intent(BibleViewer.this, DownloadActivity.class);
startActivityForResult(i, 0);
finish();
return null;
}
})
.subscribeOn(AndroidSchedulers.mainThread()) .subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Book>() { .subscribe(new Action1<Book>() {
@Override @Override
public void call(Book book) { public void call(Book book) {
Log.d("BibleViewer", "Subscribed to display book: " + book.getName()); Log.e("BibleViewer", "Subscribed to display book: " + book.getName());
displayMainBook(book); displayMainBook(book);
} }
}); });
}
setContentView(R.layout.activity_bible_viewer); setContentView(R.layout.activity_bible_viewer);
mNavigationDrawerFragment = (ExpListNavDrawerFragment) getSupportFragmentManager() mNavigationDrawerFragment = (ExpListNavDrawerFragment) getSupportFragmentManager()

View File

@ -2,13 +2,12 @@ package org.bspeice.minimalbible.activity.viewer;
import android.util.Log; import android.util.Log;
import com.google.gson.Gson;
import org.bspeice.minimalbible.activity.navigation.ExpListNavAdapter; import org.bspeice.minimalbible.activity.navigation.ExpListNavAdapter;
import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil; import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
import org.bspeice.minimalbible.service.book.VerseLookupModules; import org.bspeice.minimalbible.service.book.VerseLookupModules;
import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.Book;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Named; import javax.inject.Named;
@ -69,13 +68,25 @@ public class BibleViewerModules {
}); });
if (mBook.get() == null) { if (mBook.get() == null) {
try {
Book fallback; Book fallback;
fallback = bookManager.getInstalledBooks() fallback = bookManager.getInstalledBooks()
.onErrorReturn(new Func1<Throwable, Book>() {
@Override
public Book call(Throwable throwable) {
// If there's no book installed, we can't select the main one...
return null;
}
})
.toBlocking().first(); .toBlocking().first();
prefs.defaultBookName(fallback.getName()); prefs.defaultBookName(fallback.getName());
return fallback; return fallback;
} catch (NoSuchElementException e) {
// If no books are installed, there's really nothing we can do...
Log.d("BibleViewerModules", "No books are installed, so can't select a main book.");
return null;
}
} else { } else {
return mBook.get(); return mBook.get();
} }

View File

@ -58,14 +58,20 @@ public class ExpListNavDrawerFragment extends NavDrawerFragment {
}); });
*/ */
List<String> bibleBooks = vUtil.getBookNames(mainBook) List<String> bibleBooks;
if (mainBook != null) {
bibleBooks = vUtil.getBookNames(mainBook)
.toList().toBlocking().first(); .toList().toBlocking().first();
} else {
bibleBooks = new ArrayList<String>();
}
// I really don't like how we build the chapters, but I'm not adding Guava just for Range. // I really don't like how we build the chapters, but I'm not adding Guava just for Range.
// RXJava does get ridiculous with the angle brackets, you have me there. But Intellij // RXJava does get ridiculous with the angle brackets, you have me there. But Intellij
// folds nicely. // folds nicely.
Map<String, List<Integer>> chapterMap = Map<String, List<Integer>> chapterMap = new HashMap<String, List<Integer>>();
if (mainBook != null) {
vUtil.getBooks(mainBook).map(new Func1<BibleBook, Map<String, List<Integer>>>() { vUtil.getBooks(mainBook).map(new Func1<BibleBook, Map<String, List<Integer>>>() {
@Override @Override
public Map<String, List<Integer>> call(BibleBook bibleBook) { public Map<String, List<Integer>> call(BibleBook bibleBook) {
@ -97,7 +103,7 @@ public class ExpListNavDrawerFragment extends NavDrawerFragment {
}) })
.toBlocking() .toBlocking()
.first(); .first();
}
ExpListNavAdapter<String, Integer> adapter = ExpListNavAdapter<String, Integer> adapter =
new ExpListNavAdapter<String, Integer>(bibleBooks, chapterMap); new ExpListNavAdapter<String, Integer>(bibleBooks, chapterMap);

View File

@ -6,12 +6,14 @@ package org.bspeice.minimalbible;
*/ */
public class Modules { public class Modules {
public static TestModules testModules = new TestModules();
private Modules() {} private Modules() {}
public static Object[] list(MinimalBible app) { public static Object[] list(MinimalBible app) {
return new Object[] { return new Object[] {
new MinimalBibleModules(app), new MinimalBibleModules(app),
new TestModules() testModules
}; };
} }
} }

View File

@ -2,6 +2,7 @@ package org.bspeice.minimalbible;
import org.bspeice.minimalbible.activity.downloader.DownloadActivity; import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
import org.bspeice.minimalbible.activity.viewer.BookManager;
import org.crosswire.jsword.book.BookCategory; import org.crosswire.jsword.book.BookCategory;
import java.util.ArrayList; import java.util.ArrayList;
@ -22,7 +23,10 @@ import dagger.Provides;
public class TestModules { public class TestModules {
public static CharSequence testActivityTitle = "Test"; public static CharSequence testActivityTitle = "Test";
@Provides CharSequence provideString() { private BookManager bookManager;
@Provides
CharSequence provideString() {
return testActivityTitle; return testActivityTitle;
} }
@ -36,4 +40,13 @@ public class TestModules {
add(BookCategory.MAPS); add(BookCategory.MAPS);
}}; }};
} }
public void setBookManager(BookManager bookManager) {
this.bookManager = bookManager;
}
@Provides
BookManager provideBookManager() {
return bookManager;
}
} }