mirror of
				https://github.com/MinimalBible/MinimalBible-Legacy
				synced 2025-10-31 01:10:29 -04:00 
			
		
		
		
	Squashed commit of the following: (enable Rx)
commit4269988b7cAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Sat Jun 14 16:41:11 2014 -0400 Backport to Java 6... Android Studio automatically folds lambda-style, so it won't get too out of hand. commite945ef51a7Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Sat Jun 14 16:25:13 2014 -0400 Get the unit tests passing again Note: I need to write more. Lots more. commit04fe4d13b4Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Sat Jun 14 15:13:44 2014 -0400 Add lots of Lint fixes commitdda5c79299Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Sat Jun 14 15:04:17 2014 -0400 Fix books not being removed... commit93abe065a2Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Sat Jun 14 14:10:43 2014 -0400 Fix a NetworkOnMainThreadException commitba3c6ebe6cAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Sat Jun 14 14:08:50 2014 -0400 Some refactoring and Async fixes. commit3869cf0b9bAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 23:46:29 2014 -0400 Synchronization needs fixing, otherwise works. commit8d17b6db64Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 23:44:35 2014 -0400 Silly DownloadManager Injects are for classes that need them. commit7070c933d1Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 23:41:35 2014 -0400 Fix the dagger compile errors If you have an @Singleton with no @Injects inside it, you need to add an @Injects constructor for Dagger to validate. commit28dfec81d7Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 23:17:20 2014 -0400 [broken probably] Refactoring to Rx should be done... But having issues with compiling. Checking if Dagger and retrolambda play nice. commitfb0c5fdaaaAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:56:52 2014 -0400 [broken] BookListFragment to Rx commit6eb5f66dccAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:49:47 2014 -0400 [broken] BookItemHolder to Rx commite356c8d1fcAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:40:46 2014 -0400 Revert "[broken] Remove the BookDownloadThread again" This reverts commit8f346f17e4. commit287b8cb40dAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:39:06 2014 -0400 [broken] Add a note on the InstalledManager commit899b054c8bAuthor: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:37:53 2014 -0400 [broken] Slight semantic change to RefreshManager commit8f346f17e4Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:36:12 2014 -0400 [broken] Remove the BookDownloadThread again commit1a7364da86Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:35:40 2014 -0400 [broken] Convert BookDownloadManager to Rx commitca1ccd9942Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 22:04:53 2014 -0400 [broken] Convert RefreshManager to Rx commit5770e8dd74Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 19:32:23 2014 -0400 Add RxAndroid support, remove eventbus commit3f5909be08Author: Bradlee Speice <bspeice.nc@gmail.com> Date: Tue Jun 10 19:30:45 2014 -0400 Add retrolambda support
This commit is contained in:
		| @ -1,12 +1,14 @@ | |||||||
| apply plugin: 'android' | apply plugin: 'android' | ||||||
| apply plugin: 'android-apt' | apply plugin: 'android-apt' | ||||||
|  | //apply plugin: 'retrolambda' | ||||||
|  |  | ||||||
| buildscript { | buildscript { | ||||||
|     repositories { |     repositories { | ||||||
|         mavenCentral() |         mavenCentral() | ||||||
|     } |     } | ||||||
|     dependencies { |     dependencies { | ||||||
|         classpath 'com.neenbedankt.gradle.plugins:android-apt:1.2+' |         classpath 'com.neenbedankt.gradle.plugins:android-apt:1.3' | ||||||
|  |         //classpath 'me.tatarka:gradle-retrolambda:1.3.2' | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -17,24 +19,18 @@ repositories { | |||||||
| dependencies { | dependencies { | ||||||
|     compile project(path: ':jsword-minimalbible', configuration: 'buildJSword') |     compile project(path: ':jsword-minimalbible', configuration: 'buildJSword') | ||||||
|     compile project(':appcompat_v7') |     compile project(':appcompat_v7') | ||||||
|  |  | ||||||
|     apt 'com.squareup.dagger:dagger-compiler:1.2.0' |     apt 'com.squareup.dagger:dagger-compiler:1.2.0' | ||||||
|     compile 'com.squareup.dagger:dagger:1.2.0' |     compile 'com.squareup.dagger:dagger:1.2.0' | ||||||
|  |  | ||||||
|     apt 'com.jakewharton:butterknife:5.0.1' |     apt 'com.jakewharton:butterknife:5.0.1' | ||||||
|     compile 'com.jakewharton:butterknife:5.0.1' |     compile 'com.jakewharton:butterknife:5.0.1' | ||||||
|  |  | ||||||
|     compile 'de.devland.esperandro:esperandro-api:1.1.2' |     compile 'de.devland.esperandro:esperandro-api:1.1.2' | ||||||
|     apt 'de.devland.esperandro:esperandro:1.1.2' |     apt 'de.devland.esperandro:esperandro:1.1.2' | ||||||
|  |  | ||||||
|     // compile 'com.f2prateek.dart:dart:1.1.0' |     // compile 'com.f2prateek.dart:dart:1.1.0' | ||||||
|  |  | ||||||
|     compile 'com.readystatesoftware.systembartint:systembartint:1.0.3' |     compile 'com.readystatesoftware.systembartint:systembartint:1.0.3' | ||||||
|     compile 'de.greenrobot:eventbus:2.2.0' |     // compile 'de.greenrobot:eventbus:2.2.0' | ||||||
|  |     compile 'com.netflix.rxjava:rxjava-android:0.19.0' | ||||||
|     // Handled by appcompat |     // Handled by appcompat | ||||||
|     // compile 'com.google.android:support-v4:r7' |     // compile 'com.google.android:support-v4:r7' | ||||||
|  |  | ||||||
|     // And our unit testing needs some specific stuff (and specific stuff included again) |     // And our unit testing needs some specific stuff (and specific stuff included again) | ||||||
|     androidTestCompile 'junit:junit:4.11+' |     androidTestCompile 'junit:junit:4.11+' | ||||||
|     androidTestCompile 'com.jayway.awaitility:awaitility:1.6.0' |     androidTestCompile 'com.jayway.awaitility:awaitility:1.6.0' | ||||||
| @ -43,8 +39,7 @@ dependencies { | |||||||
|  |  | ||||||
| android { | android { | ||||||
|     compileSdkVersion 19 |     compileSdkVersion 19 | ||||||
|     buildToolsVersion "19.0.3" |     buildToolsVersion '19.1.0' | ||||||
|  |  | ||||||
|     sourceSets { |     sourceSets { | ||||||
|         main { |         main { | ||||||
|             manifest.srcFile 'AndroidManifest.xml' |             manifest.srcFile 'AndroidManifest.xml' | ||||||
| @ -68,7 +63,6 @@ android { | |||||||
|         debug.setRoot('build-types/debug') |         debug.setRoot('build-types/debug') | ||||||
|         release.setRoot('build-types/release') |         release.setRoot('build-types/release') | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     packagingOptions { |     packagingOptions { | ||||||
|         exclude 'META-INF/LICENSE.txt' |         exclude 'META-INF/LICENSE.txt' | ||||||
|         exclude 'LICENSE.txt' |         exclude 'LICENSE.txt' | ||||||
| @ -78,8 +72,20 @@ android { | |||||||
|         exclude 'META-INF/NOTICE' |         exclude 'META-INF/NOTICE' | ||||||
|         exclude 'META-INF/services/javax.annotation.processing.Processor' |         exclude 'META-INF/services/javax.annotation.processing.Processor' | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     lintOptions { |     lintOptions { | ||||||
|         abortOnError false |         abortOnError false | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |     compileOptions { | ||||||
|  |         sourceCompatibility JavaVersion.VERSION_1_8 | ||||||
|  |         targetCompatibility JavaVersion.VERSION_1_8 | ||||||
|  |     } | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     defaultConfig {} | ||||||
|  |     productFlavors { | ||||||
|  |     } | ||||||
|  |     buildTypes { | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -17,7 +17,7 @@ public class BaseFragment extends Fragment { | |||||||
|      * @param context The {@link android.app.Activity} we are displaying in |      * @param context The {@link android.app.Activity} we are displaying in | ||||||
|      * @param view The {@link android.view.View} we need to calculate the offset for. |      * @param view The {@link android.view.View} we need to calculate the offset for. | ||||||
|      */ |      */ | ||||||
|     public static void setInsets(Activity context, View view) { |     protected static void setInsets(Activity context, View view) { | ||||||
|         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; |         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return; | ||||||
|         SystemBarTintManager tintManager = new SystemBarTintManager(context); |         SystemBarTintManager tintManager = new SystemBarTintManager(context); | ||||||
|         SystemBarTintManager.SystemBarConfig config = tintManager.getConfig(); |         SystemBarTintManager.SystemBarConfig config = tintManager.getConfig(); | ||||||
|  | |||||||
| @ -3,15 +3,11 @@ package org.bspeice.minimalbible.activities.downloader; | |||||||
| import org.bspeice.minimalbible.MinimalBible; | import org.bspeice.minimalbible.MinimalBible; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadManager; | import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadManager; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadThread; | import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadThread; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.BookRefreshTask; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.InstalledManager; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.RefreshManager; | import org.bspeice.minimalbible.activities.downloader.manager.RefreshManager; | ||||||
|  |  | ||||||
| import dagger.Module; | import dagger.Module; | ||||||
| import dagger.Provides; | import dagger.Provides; | ||||||
| import de.devland.esperandro.Esperandro; | import de.devland.esperandro.Esperandro; | ||||||
| import de.greenrobot.event.EventBus; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Module mappings for the classes under the Download Activity |  * Module mappings for the classes under the Download Activity | ||||||
| @ -19,22 +15,14 @@ import de.greenrobot.event.EventBus; | |||||||
| @Module( | @Module( | ||||||
|         injects = { |         injects = { | ||||||
|             BookListFragment.class, |             BookListFragment.class, | ||||||
|             DownloadManager.class, |  | ||||||
|             BookRefreshTask.class, |  | ||||||
|             BookItemHolder.class, |             BookItemHolder.class, | ||||||
|             BookDownloadManager.class, |             BookDownloadManager.class, | ||||||
|             BookDownloadThread.class, |             BookDownloadThread.class, | ||||||
|             RefreshManager.class, |             RefreshManager.class | ||||||
|             InstalledManager.class |  | ||||||
|         } |         } | ||||||
| ) | ) | ||||||
| public class ActivityDownloaderModule { | public class ActivityDownloaderModule { | ||||||
|  |  | ||||||
|     @Provides |  | ||||||
|     EventBus provideBus() { |  | ||||||
|         return new EventBus(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Provides //@Singleton |     @Provides //@Singleton | ||||||
|     DownloadPrefs provideDownloadPrefs() { |     DownloadPrefs provideDownloadPrefs() { | ||||||
|         return Esperandro.getPreferences(DownloadPrefs.class, MinimalBible.getAppContext()); |         return Esperandro.getPreferences(DownloadPrefs.class, MinimalBible.getAppContext()); | ||||||
|  | |||||||
| @ -11,17 +11,18 @@ import org.bspeice.minimalbible.MinimalBible; | |||||||
| import org.bspeice.minimalbible.R; | import org.bspeice.minimalbible.R; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadManager; | import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadManager; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.DLProgressEvent; | import org.bspeice.minimalbible.activities.downloader.manager.DLProgressEvent; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.InstalledManager; | import org.bspeice.minimalbible.activities.downloader.manager.InstalledManager; | ||||||
| import org.crosswire.jsword.book.Book; | import org.crosswire.jsword.book.Book; | ||||||
| import org.crosswire.jsword.book.BookException; |  | ||||||
| import org.crosswire.jsword.book.Books; |  | ||||||
|  |  | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
|  |  | ||||||
| import butterknife.ButterKnife; | import butterknife.ButterKnife; | ||||||
| import butterknife.InjectView; | import butterknife.InjectView; | ||||||
| import butterknife.OnClick; | import butterknife.OnClick; | ||||||
|  | import rx.Subscription; | ||||||
|  | import rx.android.schedulers.AndroidSchedulers; | ||||||
|  | import rx.functions.Action1; | ||||||
|  | import rx.functions.Func1; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| * Created by bspeice on 5/20/14. | * Created by bspeice on 5/20/14. | ||||||
| @ -36,11 +37,11 @@ public class BookItemHolder { | |||||||
|     @InjectView(R.id.download_ibtn_download) ImageButton isDownloaded; |     @InjectView(R.id.download_ibtn_download) ImageButton isDownloaded; | ||||||
|     @InjectView(R.id.download_prg_download) ProgressWheel downloadProgress; |     @InjectView(R.id.download_prg_download) ProgressWheel downloadProgress; | ||||||
|  |  | ||||||
|     @Inject DownloadManager downloadManager; |  | ||||||
|     @Inject BookDownloadManager bookDownloadManager; |     @Inject BookDownloadManager bookDownloadManager; | ||||||
|     @Inject InstalledManager installedManager; |     @Inject InstalledManager installedManager; | ||||||
|  |  | ||||||
|     Book b; |     private final Book b; | ||||||
|  |     private Subscription subscription; | ||||||
|  |  | ||||||
|     public BookItemHolder(View v, Book b) { |     public BookItemHolder(View v, Book b) { | ||||||
|         ButterKnife.inject(this, v); |         ButterKnife.inject(this, v); | ||||||
| @ -57,7 +58,21 @@ public class BookItemHolder { | |||||||
|         } else if (installedManager.isInstalled(b)) { |         } else if (installedManager.isInstalled(b)) { | ||||||
|             displayInstalled(); |             displayInstalled(); | ||||||
|         } |         } | ||||||
|         downloadManager.getDownloadBus().register(this); |         //TODO: Refactor | ||||||
|  |         subscription = bookDownloadManager.getDownloadEvents() | ||||||
|  |                 .observeOn(AndroidSchedulers.mainThread()) | ||||||
|  |                 .filter(new Func1<DLProgressEvent, Boolean>() { | ||||||
|  |                     @Override | ||||||
|  |                     public Boolean call(DLProgressEvent event) { | ||||||
|  |                         return event.getB().getInitials().equals(b.getInitials()); | ||||||
|  |                     } | ||||||
|  |                 }) | ||||||
|  |                 .subscribe(new Action1<DLProgressEvent>() { | ||||||
|  |                     @Override | ||||||
|  |                     public void call(DLProgressEvent event) { | ||||||
|  |                         BookItemHolder.this.displayProgress((int) event.toCircular()); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void displayInstalled() { |     private void displayInstalled() { | ||||||
| @ -75,12 +90,6 @@ public class BookItemHolder { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void onEventMainThread(DLProgressEvent event) { |  | ||||||
|         if (event.getB().getOsisID().equals(b.getOsisID())) { |  | ||||||
|             displayProgress((int) event.toCircular()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Display the current progress of this download |      * Display the current progress of this download | ||||||
|      * @param progress The progress out of 360 (degrees of a circle) |      * @param progress The progress out of 360 (degrees of a circle) | ||||||
| @ -119,6 +128,7 @@ public class BookItemHolder { | |||||||
|             downloadProgress.setProgress(progress); |             downloadProgress.setProgress(progress); | ||||||
|         } else { |         } else { | ||||||
|             // Download complete |             // Download complete | ||||||
|  |             subscription.unsubscribe(); | ||||||
|             RelativeLayout.LayoutParams acronymParams = |             RelativeLayout.LayoutParams acronymParams = | ||||||
|                     (RelativeLayout.LayoutParams)acronym.getLayoutParams(); |                     (RelativeLayout.LayoutParams)acronym.getLayoutParams(); | ||||||
|             acronymParams.addRule(RelativeLayout.LEFT_OF, isDownloaded.getId()); |             acronymParams.addRule(RelativeLayout.LEFT_OF, isDownloaded.getId()); | ||||||
| @ -134,6 +144,6 @@ public class BookItemHolder { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void onScrollOffscreen() { |     public void onScrollOffscreen() { | ||||||
|         downloadManager.getDownloadBus().unregister(this); |         subscription.unsubscribe(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -15,9 +15,9 @@ import java.util.List; | |||||||
|  * Adapter to inflate list_download_items.xml |  * Adapter to inflate list_download_items.xml | ||||||
|  */ |  */ | ||||||
| public class BookListAdapter extends BaseAdapter implements AbsListView.RecyclerListener { | public class BookListAdapter extends BaseAdapter implements AbsListView.RecyclerListener { | ||||||
|     private List<Book> bookList; |     private final List<Book> bookList; | ||||||
|  |  | ||||||
|     private LayoutInflater inflater; |     private final LayoutInflater inflater; | ||||||
|  |  | ||||||
|     public BookListAdapter(LayoutInflater inflater, List<Book> bookList) { |     public BookListAdapter(LayoutInflater inflater, List<Book> bookList) { | ||||||
|         this.bookList = bookList; |         this.bookList = bookList; | ||||||
|  | |||||||
| @ -5,7 +5,6 @@ import android.app.AlertDialog; | |||||||
| import android.app.ProgressDialog; | import android.app.ProgressDialog; | ||||||
| import android.content.DialogInterface; | import android.content.DialogInterface; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.util.Log; |  | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.view.ViewGroup; | import android.view.ViewGroup; | ||||||
| @ -15,22 +14,22 @@ import android.widget.Toast; | |||||||
| import org.bspeice.minimalbible.MinimalBible; | import org.bspeice.minimalbible.MinimalBible; | ||||||
| import org.bspeice.minimalbible.R; | import org.bspeice.minimalbible.R; | ||||||
| import org.bspeice.minimalbible.activities.BaseFragment; | import org.bspeice.minimalbible.activities.BaseFragment; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.EventBookList; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.RefreshManager; | import org.bspeice.minimalbible.activities.downloader.manager.RefreshManager; | ||||||
| import org.crosswire.jsword.book.Book; | import org.crosswire.jsword.book.Book; | ||||||
| import org.crosswire.jsword.book.BookCategory; | import org.crosswire.jsword.book.BookCategory; | ||||||
| import org.crosswire.jsword.book.BookComparators; | import org.crosswire.jsword.book.BookComparators; | ||||||
| import org.crosswire.jsword.book.BookFilter; |  | ||||||
| import org.crosswire.jsword.book.FilterUtil; |  | ||||||
|  |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
|  |  | ||||||
| import butterknife.ButterKnife; | import butterknife.ButterKnife; | ||||||
| import butterknife.InjectView; | import butterknife.InjectView; | ||||||
|  | import rx.Observable; | ||||||
|  | import rx.android.schedulers.AndroidSchedulers; | ||||||
|  | import rx.functions.Action1; | ||||||
|  | import rx.functions.Func1; | ||||||
|  | import rx.functions.Func2; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * A placeholder fragment containing a simple view. |  * A placeholder fragment containing a simple view. | ||||||
| @ -48,9 +47,7 @@ public class BookListFragment extends BaseFragment { | |||||||
|     @InjectView(R.id.lst_download_available) |     @InjectView(R.id.lst_download_available) | ||||||
|     ListView downloadsAvailable; |     ListView downloadsAvailable; | ||||||
|  |  | ||||||
|     @Inject DownloadManager downloadManager; |  | ||||||
|     @Inject RefreshManager refreshManager; |     @Inject RefreshManager refreshManager; | ||||||
|  |  | ||||||
|     @Inject DownloadPrefs downloadPrefs; |     @Inject DownloadPrefs downloadPrefs; | ||||||
|  |  | ||||||
| 	private ProgressDialog refreshDialog; | 	private ProgressDialog refreshDialog; | ||||||
| @ -96,7 +93,7 @@ public class BookListFragment extends BaseFragment { | |||||||
|      * Trigger the functionality to display a list of modules. Prompts user if downloading |      * Trigger the functionality to display a list of modules. Prompts user if downloading | ||||||
|      * from the internet is allowable. |      * from the internet is allowable. | ||||||
|      */ |      */ | ||||||
|  	public void displayModules() { |  	private void displayModules() { | ||||||
| 		boolean dialogDisplayed = downloadPrefs.hasShownDownloadDialog(); | 		boolean dialogDisplayed = downloadPrefs.hasShownDownloadDialog(); | ||||||
| 		 | 		 | ||||||
| 		if (!dialogDisplayed) { | 		if (!dialogDisplayed) { | ||||||
| @ -118,52 +115,49 @@ public class BookListFragment extends BaseFragment { | |||||||
|      */ |      */ | ||||||
| 	private void refreshModules() { | 	private void refreshModules() { | ||||||
|         // Check if the downloadManager has already refreshed everything |         // Check if the downloadManager has already refreshed everything | ||||||
| 		List<Book> bookList = refreshManager.getBookList(); | 		if (!refreshManager.isRefreshComplete()) { | ||||||
| 		if (bookList == null) { |  | ||||||
|             // downloadManager is in progress of refreshing |             // downloadManager is in progress of refreshing | ||||||
|             downloadManager.getDownloadBus().register(this); |  | ||||||
|             refreshDialog = new ProgressDialog(getActivity()); |             refreshDialog = new ProgressDialog(getActivity()); | ||||||
|             refreshDialog.setMessage("Refreshing available modules..."); |             refreshDialog.setMessage("Refreshing available modules..."); | ||||||
|             refreshDialog.setCancelable(false); |             refreshDialog.setCancelable(false); | ||||||
|             refreshDialog.show(); |             refreshDialog.show(); | ||||||
|         } else { |  | ||||||
|             displayBooks(bookList); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // Listen for the books! | ||||||
|  |         refreshManager.getAvailableModulesFlattened() | ||||||
|  |                 .filter(new Func1<Book, Boolean>() { | ||||||
|  |                     @Override | ||||||
|  |                     public Boolean call(Book book) { | ||||||
|  |                         return book.getBookCategory() == | ||||||
|  |                                 BookCategory.fromString(BookListFragment.this.getArguments() | ||||||
|  |                                         .getString(ARG_BOOK_CATEGORY)); | ||||||
|  |                     } | ||||||
|  |                 }) | ||||||
|  |                 // Repack all the books | ||||||
|  |                 .toSortedList(new Func2<Book, Book, Integer>() { | ||||||
|  |                     @Override | ||||||
|  |                     public Integer call(Book book1, Book book2) { | ||||||
|  |                         return BookComparators.getInitialComparator().compare(book1, book2); | ||||||
|  |                     } | ||||||
|  |                 }) | ||||||
|  |                 .observeOn(AndroidSchedulers.mainThread()) | ||||||
|  |                 .subscribe(new Action1<List<Book>>() { | ||||||
|  |                     @Override | ||||||
|  |                     public void call(List<Book> books) { | ||||||
|  |                         downloadsAvailable.setAdapter(new BookListAdapter(inflater, books)); | ||||||
|  |                         if (BookListFragment.this.getActivity() != null) { | ||||||
|  |                             // On a screen rotate, getActivity() will be null. But, the activity will | ||||||
|  |                             // already have been set up correctly, so we don't need to worry about it. | ||||||
|  |                             // If not null, we need to set it up now. | ||||||
|  |                             setInsets(BookListFragment.this.getActivity(), downloadsAvailable); | ||||||
|  |                         } | ||||||
|  |                         if (refreshDialog != null) { | ||||||
|  |                             refreshDialog.cancel(); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Used by GreenRobot for notifying us that the book refresh is complete |  | ||||||
|      */ |  | ||||||
|     @SuppressWarnings("unused") |  | ||||||
| 	public void onEventMainThread(EventBookList event) { |  | ||||||
| 		if (refreshDialog != null) { |  | ||||||
| 			refreshDialog.cancel(); |  | ||||||
| 		} |  | ||||||
| 		displayBooks(event.getBookList()); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Do the hard work of creating the Adapter and displaying books. |  | ||||||
|      * @param bookList The (unfiltered) list of {link org.crosswire.jsword.Book}s to display |  | ||||||
|      */ |  | ||||||
|     public void displayBooks(List<Book> bookList) { |  | ||||||
|         try { |  | ||||||
|             // TODO: Should the filter be applied earlier in the process? |  | ||||||
|             List<Book> displayList; |  | ||||||
|  |  | ||||||
|             BookCategory c = BookCategory.fromString(getArguments().getString(ARG_BOOK_CATEGORY)); |  | ||||||
|             BookFilter f = FilterUtil.filterFromCategory(c); |  | ||||||
|             displayList = FilterUtil.applyFilter(bookList, f); |  | ||||||
|             Collections.sort(displayList, BookComparators.getInitialComparator()); |  | ||||||
|  |  | ||||||
|             downloadsAvailable.setAdapter(new BookListAdapter(inflater, displayList)); |  | ||||||
|             setInsets(getActivity(), downloadsAvailable); |  | ||||||
|         } catch (FilterUtil.InvalidFilterCategoryMappingException e) { |  | ||||||
|             // To be honest, there should be no reason you end up here. |  | ||||||
|             Log.e(TAG, e.getMessage()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| 	private class DownloadDialogListener implements | 	private class DownloadDialogListener implements | ||||||
| 			DialogInterface.OnClickListener { | 			DialogInterface.OnClickListener { | ||||||
| 		@Override | 		@Override | ||||||
|  | |||||||
| @ -1,10 +1,5 @@ | |||||||
| package org.bspeice.minimalbible.activities.downloader; | package org.bspeice.minimalbible.activities.downloader; | ||||||
|  |  | ||||||
| import org.bspeice.minimalbible.R; |  | ||||||
| import org.bspeice.minimalbible.activities.BaseActivity; |  | ||||||
| import org.bspeice.minimalbible.activities.BaseNavigationDrawerFragment; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; |  | ||||||
|  |  | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.support.v4.app.FragmentManager; | import android.support.v4.app.FragmentManager; | ||||||
| import android.support.v4.widget.DrawerLayout; | import android.support.v4.widget.DrawerLayout; | ||||||
| @ -12,6 +7,11 @@ import android.support.v7.app.ActionBar; | |||||||
| import android.view.Menu; | import android.view.Menu; | ||||||
| import android.view.MenuItem; | import android.view.MenuItem; | ||||||
|  |  | ||||||
|  | import org.bspeice.minimalbible.R; | ||||||
|  | import org.bspeice.minimalbible.activities.BaseActivity; | ||||||
|  | import org.bspeice.minimalbible.activities.BaseNavigationDrawerFragment; | ||||||
|  | import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; | ||||||
|  |  | ||||||
| public class DownloadActivity extends BaseActivity implements | public class DownloadActivity extends BaseActivity implements | ||||||
| 		BaseNavigationDrawerFragment.NavigationDrawerCallbacks { | 		BaseNavigationDrawerFragment.NavigationDrawerCallbacks { | ||||||
|  |  | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ import javax.inject.Inject; | |||||||
| import javax.inject.Provider; | import javax.inject.Provider; | ||||||
| import javax.inject.Singleton; | import javax.inject.Singleton; | ||||||
|  |  | ||||||
| import de.greenrobot.event.EventBus; | import rx.subjects.PublishSubject; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Wrapper to convert JSword progress events to MinimalBible EventBus-based |  * Wrapper to convert JSword progress events to MinimalBible EventBus-based | ||||||
| @ -32,18 +32,18 @@ public class BookDownloadManager implements WorkListener, BooksListener { | |||||||
|     /** |     /** | ||||||
|      * Mapping of Job ID to the EventBus we should trigger progress on |      * Mapping of Job ID to the EventBus we should trigger progress on | ||||||
|      */ |      */ | ||||||
|     private Map<String, Book> bookMappings; |     private final Map<String, Book> bookMappings; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Cached copy of downloads in progress so views displaying this info can get it quickly. |      * Cached copy of downloads in progress so views displaying this info can get it quickly. | ||||||
|      */ |      */ | ||||||
|     private Map<Book, DLProgressEvent> inProgressDownloads; |     private final Map<Book, DLProgressEvent> inProgressDownloads; | ||||||
|  |  | ||||||
|  |     private final PublishSubject<DLProgressEvent> downloadEvents = PublishSubject.create(); | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
|     Provider<BookDownloadThread> dlThreadProvider; |     Provider<BookDownloadThread> dlThreadProvider; | ||||||
|  |  | ||||||
|     @Inject DownloadManager downloadManager; |  | ||||||
|  |  | ||||||
|     public BookDownloadManager() { |     public BookDownloadManager() { | ||||||
|         bookMappings = new HashMap<String, Book>(); |         bookMappings = new HashMap<String, Book>(); | ||||||
|         inProgressDownloads = new HashMap<Book, DLProgressEvent>(); |         inProgressDownloads = new HashMap<Book, DLProgressEvent>(); | ||||||
| @ -56,6 +56,7 @@ public class BookDownloadManager implements WorkListener, BooksListener { | |||||||
|         BookDownloadThread dlThread = dlThreadProvider.get(); |         BookDownloadThread dlThread = dlThreadProvider.get(); | ||||||
|         dlThread.downloadBook(b); |         dlThread.downloadBook(b); | ||||||
|         addJob(BookDownloadThread.getJobId(b), b); |         addJob(BookDownloadThread.getJobId(b), b); | ||||||
|  |         downloadEvents.onNext(new DLProgressEvent(DLProgressEvent.PROGRESS_BEGINNING, b)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void addJob(String jobId, Book b) { |     public void addJob(String jobId, Book b) { | ||||||
| @ -66,20 +67,20 @@ public class BookDownloadManager implements WorkListener, BooksListener { | |||||||
|     public void workProgressed(WorkEvent ev) { |     public void workProgressed(WorkEvent ev) { | ||||||
|         Progress job = ev.getJob(); |         Progress job = ev.getJob(); | ||||||
|         Log.d("BookDownloadManager", "Download in progress: " + job.getJobID() + " - " + job.getJobName() + " " + job.getWorkDone() + "/" + job.getTotalWork()); |         Log.d("BookDownloadManager", "Download in progress: " + job.getJobID() + " - " + job.getJobName() + " " + job.getWorkDone() + "/" + job.getTotalWork()); | ||||||
|         EventBus downloadBus = downloadManager.getDownloadBus(); |  | ||||||
|         if (bookMappings.containsKey(job.getJobID())) { |         if (bookMappings.containsKey(job.getJobID())) { | ||||||
|             Book b = bookMappings.get(job.getJobID()); |             Book b = bookMappings.get(job.getJobID()); | ||||||
|  |  | ||||||
|             if (job.getWorkDone() == job.getTotalWork()) { |             if (job.getWorkDone() == job.getTotalWork()) { | ||||||
|                 // Download is complete |                 // Download is complete | ||||||
|                 inProgressDownloads.remove(bookMappings.get(job.getJobID())); |                 inProgressDownloads.remove(bookMappings.get(job.getJobID())); | ||||||
|                 downloadBus.post(new DLProgressEvent(DLProgressEvent.PROGRESS_COMPLETE, b)); |                 bookMappings.remove(job.getJobID()); | ||||||
|  |                 downloadEvents.onNext(new DLProgressEvent(DLProgressEvent.PROGRESS_COMPLETE, b)); | ||||||
|             } else { |             } else { | ||||||
|                 // Track the ongoing download |                 // Track the ongoing download | ||||||
|                 DLProgressEvent event = new DLProgressEvent(job.getWorkDone(), |                 DLProgressEvent event = new DLProgressEvent(job.getWorkDone(), | ||||||
|                         job.getTotalWork(), b); |                         job.getTotalWork(), b); | ||||||
|                 inProgressDownloads.put(b, event); |                 inProgressDownloads.put(b, event); | ||||||
|                 downloadBus.post(event); |                 downloadEvents.onNext(event); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -97,6 +98,10 @@ public class BookDownloadManager implements WorkListener, BooksListener { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public PublishSubject<DLProgressEvent> getDownloadEvents() { | ||||||
|  |         return downloadEvents; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void workStateChanged(WorkEvent ev) { |     public void workStateChanged(WorkEvent ev) { | ||||||
|         Log.d("BookDownloadManager", ev.toString()); |         Log.d("BookDownloadManager", ev.toString()); | ||||||
| @ -114,8 +119,7 @@ public class BookDownloadManager implements WorkListener, BooksListener { | |||||||
|         // Not sure why, but the inProgressDownloads might not have our book, |         // Not sure why, but the inProgressDownloads might not have our book, | ||||||
|         // so we always trigger the PROGRESS_COMPLETE event. |         // so we always trigger the PROGRESS_COMPLETE event. | ||||||
|         // TODO: Make sure all books get to the inProgressDownloads |         // TODO: Make sure all books get to the inProgressDownloads | ||||||
|         downloadManager.getDownloadBus() |         downloadEvents.onNext(new DLProgressEvent(DLProgressEvent.PROGRESS_COMPLETE, b)); | ||||||
|                 .post(new DLProgressEvent(DLProgressEvent.PROGRESS_COMPLETE, b)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|  | |||||||
| @ -9,6 +9,9 @@ import org.crosswire.jsword.book.install.Installer; | |||||||
|  |  | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
|  |  | ||||||
|  | import rx.functions.Action1; | ||||||
|  | import rx.schedulers.Schedulers; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Thread that handles downloading a book |  * Thread that handles downloading a book | ||||||
|  */ |  */ | ||||||
| @ -18,8 +21,9 @@ public class BookDownloadThread { | |||||||
|     private final String TAG = "BookDownloadThread"; |     private final String TAG = "BookDownloadThread"; | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
|     DownloadManager downloadManager; |     BookDownloadManager bookDownloadManager; | ||||||
|     @Inject RefreshManager refreshManager; |     @Inject | ||||||
|  |     RefreshManager refreshManager; | ||||||
|  |  | ||||||
|     public BookDownloadThread() { |     public BookDownloadThread() { | ||||||
|         MinimalBible.getApplication().inject(this); |         MinimalBible.getApplication().inject(this); | ||||||
| @ -29,31 +33,32 @@ public class BookDownloadThread { | |||||||
|         // So, the JobManager can't be injected, but we'll make do |         // So, the JobManager can't be injected, but we'll make do | ||||||
|  |  | ||||||
|         // First, look up where the Book came from |         // First, look up where the Book came from | ||||||
|         final Installer i = refreshManager.installerFromBook(b); |         refreshManager.installerFromBook(b) | ||||||
|  |                 .subscribeOn(Schedulers.io()) | ||||||
|  |                 .subscribe(new Action1<Installer>() { | ||||||
|  |                     @Override | ||||||
|  |                     public void call(Installer installer) { | ||||||
|  |                         try { | ||||||
|  |                             installer.install(b); | ||||||
|  |                         } catch (InstallException e) { | ||||||
|  |                             Log.d(TAG, e.getMessage()); | ||||||
|  |                         } | ||||||
|  |  | ||||||
|         final Thread worker = new Thread() { |                         bookDownloadManager.getDownloadEvents() | ||||||
|             @Override |                                 .onNext(new DLProgressEvent(DLProgressEvent.PROGRESS_BEGINNING, b)); | ||||||
|             public void run() { |                     } | ||||||
|                 try { |                 }); | ||||||
|                     i.install(b); |  | ||||||
|                 } catch (InstallException e) { |  | ||||||
|                     Log.d(TAG, e.getMessage()); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
|         worker.start(); |  | ||||||
|         // The worker automatically communicates with the JobManager for its progress. |  | ||||||
|  |  | ||||||
|         downloadManager.getDownloadBus().post(new DLProgressEvent(DLProgressEvent.PROGRESS_BEGINNING, b)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Build what the installer creates the job name as. |      * Build what the installer creates the job name as. | ||||||
|      * Likely prone to be brittle. |      * Likely prone to be brittle. | ||||||
|      * TODO: Make sure to test that this is an accurate job name |      * TODO: Make sure to test that this is an accurate job name | ||||||
|  |      * | ||||||
|      * @param b The book to predict the download job name of |      * @param b The book to predict the download job name of | ||||||
|      * @return The name of the job that will/is download/ing this book |      * @return The name of the job that will/is download/ing this book | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|     public static String getJobId(Book b) { |     public static String getJobId(Book b) { | ||||||
|         return "INSTALL_BOOK-" + b.getInitials(); |         return "INSTALL_BOOK-" + b.getInitials(); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,86 +0,0 @@ | |||||||
| package org.bspeice.minimalbible.activities.downloader.manager; |  | ||||||
|  |  | ||||||
| import android.content.Context; |  | ||||||
| import android.net.ConnectivityManager; |  | ||||||
| import android.net.NetworkInfo; |  | ||||||
| import android.os.AsyncTask; |  | ||||||
| import android.util.Log; |  | ||||||
|  |  | ||||||
| import org.bspeice.minimalbible.MinimalBible; |  | ||||||
| import org.bspeice.minimalbible.activities.downloader.DownloadPrefs; |  | ||||||
| import org.crosswire.jsword.book.Book; |  | ||||||
| import org.crosswire.jsword.book.install.InstallException; |  | ||||||
| import org.crosswire.jsword.book.install.Installer; |  | ||||||
|  |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Map; |  | ||||||
|  |  | ||||||
| import javax.inject.Inject; |  | ||||||
|  |  | ||||||
| public class BookRefreshTask extends AsyncTask<Installer, Integer, List<Book>> { |  | ||||||
| 	private static final String TAG = "EventBookRefreshTask"; |  | ||||||
|  |  | ||||||
|     // If last refresh was before the below, force an internet refresh |  | ||||||
|     private final Long refreshAfter = System.currentTimeMillis() - 604800000L; // 1 Week in millis |  | ||||||
|  |  | ||||||
|     @Inject DownloadPrefs downloadPrefs; |  | ||||||
|  |  | ||||||
|     @Inject DownloadManager downloadManager; |  | ||||||
|     @Inject InstalledManager installedManager; |  | ||||||
|  |  | ||||||
| 	public BookRefreshTask() { |  | ||||||
|         MinimalBible.getApplication().inject(this); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	@Override |  | ||||||
| 	protected List<Book> doInBackground(Installer... params) { |  | ||||||
|         Map<Installer, List<Book>> bookList = new HashMap<Installer, List<Book>>(); |  | ||||||
|  |  | ||||||
| 		int index = 0; |  | ||||||
| 		for (Installer i : params) { |  | ||||||
| 			if (doRefresh()) { |  | ||||||
| 				try { |  | ||||||
| 					i.reloadBookList(); |  | ||||||
|                     downloadPrefs.downloadRefreshedOn(System.currentTimeMillis()); |  | ||||||
| 				} catch (InstallException e) { |  | ||||||
| 					Log.e(TAG, |  | ||||||
| 							"Error downloading books from installer: " |  | ||||||
| 									+ i.toString(), e); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
|             bookList.put(i, i.getBooks()); |  | ||||||
| 			publishProgress(++index, params.length); |  | ||||||
| 		} |  | ||||||
|         //TODO: Filter duplicates |  | ||||||
|  |  | ||||||
|         installedManager.initialize(); |  | ||||||
|         EventBookList event = new EventBookList(bookList); |  | ||||||
|         downloadManager.getDownloadBus().post(event); |  | ||||||
|  |  | ||||||
|         return event.getBookList(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	private boolean doRefresh() { |  | ||||||
| 		// Check if we should refresh over the internet, or use the local copy |  | ||||||
| 		// TODO: Discover if we need to refresh over Internet, or use a cached |  | ||||||
| 		// copy - likely something time-based, also check network state. |  | ||||||
| 		// Fun fact - jSword handles the caching for us. |  | ||||||
|  |  | ||||||
|         return (isWifi() && downloadEnabled() && needsRefresh()); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|     private boolean isWifi() { |  | ||||||
|         ConnectivityManager mgr = (ConnectivityManager)MinimalBible.getAppContext().getSystemService(Context.CONNECTIVITY_SERVICE); |  | ||||||
|         NetworkInfo networkInfo = mgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI); |  | ||||||
|         return networkInfo.isConnected(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private boolean downloadEnabled() { |  | ||||||
|         return downloadPrefs.hasEnabledDownload(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private boolean needsRefresh() { |  | ||||||
|         return (downloadPrefs.downloadRefreshedOn() > refreshAfter); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -6,8 +6,8 @@ import org.crosswire.jsword.book.Book; | |||||||
|  * Used for notifying that a book's download progress is ongoing |  * Used for notifying that a book's download progress is ongoing | ||||||
|  */ |  */ | ||||||
| public class DLProgressEvent { | public class DLProgressEvent { | ||||||
|     private int progress; |     private final int progress; | ||||||
|     private Book b; |     private final Book b; | ||||||
|  |  | ||||||
|     public static final int PROGRESS_COMPLETE = 100; |     public static final int PROGRESS_COMPLETE = 100; | ||||||
|     public static final int PROGRESS_BEGINNING = 0; |     public static final int PROGRESS_BEGINNING = 0; | ||||||
|  | |||||||
| @ -14,19 +14,12 @@ import java.util.Map; | |||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| import javax.inject.Singleton; | import javax.inject.Singleton; | ||||||
|  |  | ||||||
| import de.greenrobot.event.EventBus; |  | ||||||
|  |  | ||||||
| // TODO: Listen to BookInstall events? | // TODO: Listen to BookInstall events? | ||||||
| @Singleton | @Singleton | ||||||
| public class DownloadManager { | public class DownloadManager { | ||||||
|  |  | ||||||
| 	private final String TAG = "DownloadManager"; | 	private final String TAG = "DownloadManager"; | ||||||
|  |  | ||||||
|     @Inject |  | ||||||
|     protected EventBus downloadBus; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	public static final BookCategory[] VALID_CATEGORIES = { BookCategory.BIBLE, | 	public static final BookCategory[] VALID_CATEGORIES = { BookCategory.BIBLE, | ||||||
| 			BookCategory.COMMENTARY, BookCategory.DICTIONARY, | 			BookCategory.COMMENTARY, BookCategory.DICTIONARY, | ||||||
| 			BookCategory.MAPS }; | 			BookCategory.MAPS }; | ||||||
| @ -34,8 +27,8 @@ public class DownloadManager { | |||||||
|     /** |     /** | ||||||
|      * Set up the DownloadManager, and notify jSword of where it should store files at |      * Set up the DownloadManager, and notify jSword of where it should store files at | ||||||
|      */ |      */ | ||||||
|  |     @Inject | ||||||
| 	public DownloadManager() { | 	public DownloadManager() { | ||||||
|         MinimalBible.getApplication().inject(this); |  | ||||||
| 		setDownloadDir(); | 		setDownloadDir(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -47,15 +40,6 @@ public class DownloadManager { | |||||||
| 		return new InstallManager().getInstallers(); | 		return new InstallManager().getInstallers(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Helper method to transform the installers map to an array |  | ||||||
|      * @return Array with all available {@link org.crosswire.jsword.book.install.Installer} objects |  | ||||||
|      */ |  | ||||||
| 	public Installer[] getInstallersArray() { |  | ||||||
| 		Map<String, Installer> installers = getInstallers(); |  | ||||||
| 		return installers.values().toArray(new Installer[installers.size()]); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Notify jSword that it needs to store files in the Android internal directory |      * Notify jSword that it needs to store files in the Android internal directory | ||||||
|      * NOTE: Android will uninstall these files if you uninstall MinimalBible. |      * NOTE: Android will uninstall these files if you uninstall MinimalBible. | ||||||
| @ -71,14 +55,4 @@ public class DownloadManager { | |||||||
|         SwordBookPath.setDownloadDir(new File(home)); |         SwordBookPath.setDownloadDir(new File(home)); | ||||||
|         Log.d(TAG, "Sword download path: " + SwordBookPath.getSwordDownloadDir()); |         Log.d(TAG, "Sword download path: " + SwordBookPath.getSwordDownloadDir()); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Get the current download bus |  | ||||||
|      * Used to broker refresh events, and ongoing download events |  | ||||||
|      */ |  | ||||||
| 	public EventBus getDownloadBus() { |  | ||||||
| 		return this.downloadBus; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,33 +0,0 @@ | |||||||
| package org.bspeice.minimalbible.activities.downloader.manager; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Map; |  | ||||||
|  |  | ||||||
| import org.crosswire.jsword.book.Book; |  | ||||||
| import org.crosswire.jsword.book.install.Installer; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * POJO class for {@link de.greenrobot.event.EventBus} to broadcast whenever |  | ||||||
|  * we've finished updating the book list. |  | ||||||
|  */ |  | ||||||
| public class EventBookList { |  | ||||||
| 	 |  | ||||||
| 	private Map<Installer, List<Book>> bookMapping; |  | ||||||
| 	 |  | ||||||
| 	public EventBookList(Map<Installer, List<Book>> bookList) { |  | ||||||
| 		this.bookMapping = bookList; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	public Map<Installer, List<Book>> getInstallerMapping() { |  | ||||||
| 		return bookMapping; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|     public List<Book> getBookList() { |  | ||||||
|         List<Book> bookList = new ArrayList<Book>(); |  | ||||||
|         for (Installer i: bookMapping.keySet()) { |  | ||||||
|             bookList.addAll(bookMapping.get(i)); |  | ||||||
|         } |  | ||||||
|         return bookList; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -19,10 +19,11 @@ import javax.inject.Singleton; | |||||||
| @Singleton | @Singleton | ||||||
| public class InstalledManager implements BooksListener { | public class InstalledManager implements BooksListener { | ||||||
|  |  | ||||||
|     @Inject DownloadManager downloadManager; |  | ||||||
|  |  | ||||||
|     private Books installedBooks; |     private Books installedBooks; | ||||||
|     private List<Book> installedBooksList; |     private List<Book> installedBooksList; | ||||||
|  |     private String TAG = "InstalledManager"; | ||||||
|  |  | ||||||
|  |     @Inject InstalledManager() {} | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Register our manager to receive events on Book install |      * Register our manager to receive events on Book install | ||||||
| @ -30,6 +31,7 @@ public class InstalledManager implements BooksListener { | |||||||
|      * so we don't put it in the constructor. |      * so we don't put it in the constructor. | ||||||
|      */ |      */ | ||||||
|     public void initialize() { |     public void initialize() { | ||||||
|  |         //TODO: Move this to a true async, rather than separate initialize() function | ||||||
|         installedBooks = Books.installed(); |         installedBooks = Books.installed(); | ||||||
|         installedBooksList = installedBooks.getBooks(); |         installedBooksList = installedBooks.getBooks(); | ||||||
|         installedBooks.addBooksListener(this); |         installedBooks.addBooksListener(this); | ||||||
| @ -44,6 +46,7 @@ public class InstalledManager implements BooksListener { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void bookAdded(BooksEvent booksEvent) { |     public void bookAdded(BooksEvent booksEvent) { | ||||||
|  |         Log.d(TAG, "Book added: " + booksEvent.getBook().toString()); | ||||||
|         Book b = booksEvent.getBook(); |         Book b = booksEvent.getBook(); | ||||||
|         if (!installedBooksList.contains(b)) { |         if (!installedBooksList.contains(b)) { | ||||||
|             installedBooksList.add(b); |             installedBooksList.add(b); | ||||||
| @ -52,6 +55,7 @@ public class InstalledManager implements BooksListener { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void bookRemoved(BooksEvent booksEvent) { |     public void bookRemoved(BooksEvent booksEvent) { | ||||||
|  |         Log.d(TAG, "Book removed: " + booksEvent.getBook().toString()); | ||||||
|         Book b = booksEvent.getBook(); |         Book b = booksEvent.getBook(); | ||||||
|         if (installedBooksList.contains(b)) { |         if (installedBooksList.contains(b)) { | ||||||
|             installedBooksList.remove(b); |             installedBooksList.remove(b); | ||||||
| @ -59,10 +63,19 @@ public class InstalledManager implements BooksListener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void removeBook(Book b) { |     public void removeBook(Book b) { | ||||||
|         try { |         if (installedBooks == null) { | ||||||
|             installedBooks.removeBook(b); |             initialize(); | ||||||
|         } catch (BookException e) { |         } | ||||||
|             Log.e("InstalledManager", "Unable to remove book (already uninstalled?): " + e.getLocalizedMessage()); |         // Not sure why we need to call this multiple times, but... | ||||||
|  |         while (Books.installed().getBooks().contains(b)) { | ||||||
|  |             try { | ||||||
|  |                 // This worked in the past, but isn't now... | ||||||
|  |                 // installedBooks.remove(b); | ||||||
|  |                 Book realBook = installedBooks.getBook(b.getInitials()); | ||||||
|  |                 b.getDriver().delete(realBook); | ||||||
|  |             } catch (BookException e) { | ||||||
|  |                 Log.e("InstalledManager", "Unable to remove book (already uninstalled?): " + e.getLocalizedMessage()); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -8,11 +8,17 @@ import java.util.ArrayList; | |||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  | import java.util.concurrent.atomic.AtomicBoolean; | ||||||
|  |  | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| import javax.inject.Singleton; | import javax.inject.Singleton; | ||||||
|  |  | ||||||
| import de.greenrobot.event.EventBus; | import rx.Observable; | ||||||
|  | import rx.functions.Action0; | ||||||
|  | import rx.functions.Action1; | ||||||
|  | import rx.functions.Func1; | ||||||
|  | import rx.functions.Func2; | ||||||
|  | import rx.schedulers.Schedulers; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Handle refreshing the list of books available as needed |  * Handle refreshing the list of books available as needed | ||||||
| @ -21,35 +27,74 @@ import de.greenrobot.event.EventBus; | |||||||
| public class RefreshManager { | public class RefreshManager { | ||||||
|  |  | ||||||
|     @Inject DownloadManager downloadManager; |     @Inject DownloadManager downloadManager; | ||||||
|  |     @Inject InstalledManager installedManager; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Cached copy of modules that are available so we don't refresh for everyone who requests it. |      * Cached copy of modules that are available so we don't refresh for everyone who requests it. | ||||||
|      */ |      */ | ||||||
|     private Map<Installer, List<Book>> availableModules; |     private Observable<Map<Installer, List<Book>>> availableModules; | ||||||
|  |     private final AtomicBoolean refreshComplete = new AtomicBoolean(); | ||||||
|  |  | ||||||
|     public RefreshManager() { |     public RefreshManager() { | ||||||
|         MinimalBible.getApplication().inject(this); |         MinimalBible.getApplication().inject(this); | ||||||
|         availableModules = new HashMap<Installer, List<Book>>(); |  | ||||||
|         refreshModules(); |         refreshModules(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Do the work of kicking off the AsyncTask to refresh books, and make sure we know |      * Do the work of kicking off the AsyncTask to refresh books, and make sure we know | ||||||
|      * when it's done. |      * when it's done. | ||||||
|  |      * TODO: Should I have a better way of scheduling than Schedulers.io()? | ||||||
|      */ |      */ | ||||||
|     private void refreshModules() { |     private void refreshModules() { | ||||||
|         EventBus refreshBus = downloadManager.getDownloadBus(); |         if (availableModules == null) { | ||||||
|         refreshBus.register(this); |             availableModules = Observable.from(downloadManager.getInstallers().values()) | ||||||
|         new BookRefreshTask().execute(downloadManager.getInstallersArray()); |                     .map(new Func1<Installer, Map<Installer, List<Book>>>() { | ||||||
|  |                         @Override | ||||||
|  |                         public Map<Installer, List<Book>> call(Installer installer) { | ||||||
|  |                             Map<Installer, List<Book>> map = new HashMap<Installer, List<Book>>(); | ||||||
|  |                             map.put(installer, installer.getBooks()); | ||||||
|  |                             return map; | ||||||
|  |                         } | ||||||
|  |                     }).subscribeOn(Schedulers.io()) | ||||||
|  |                     .cache(); | ||||||
|  |  | ||||||
|  |             // Set refresh complete when it is. | ||||||
|  |             availableModules.observeOn(Schedulers.io()) | ||||||
|  |                     .subscribe(new Action1<Map<Installer, List<Book>>>() { | ||||||
|  |                         @Override | ||||||
|  |                         public void call(Map<Installer, List<Book>> onNext) {} | ||||||
|  |                     }, new Action1<Throwable>() { | ||||||
|  |                         @Override | ||||||
|  |                         public void call(Throwable onError) {} | ||||||
|  |                     }, new Action0() { | ||||||
|  |                         @Override | ||||||
|  |                         public void call() { | ||||||
|  |                             refreshComplete.set(true); | ||||||
|  |                         } | ||||||
|  |                     }); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public Observable<Map<Installer, List<Book>>> getAvailableModules() { | ||||||
|      * When book refresh is done, cache the list so we can give that to someone else |         return availableModules; | ||||||
|      * @param event A POJO wrapper around the Book list |     } | ||||||
|      */ |  | ||||||
|     @SuppressWarnings("unused") |     public Observable<Book> getAvailableModulesFlattened() { | ||||||
|     public void onEvent(EventBookList event) { |         return availableModules | ||||||
|         this.availableModules = event.getInstallerMapping(); |                 // First flatten the Map to its lists | ||||||
|  |                 .flatMap(new Func1<Map<Installer, List<Book>>, Observable<? extends List<Book>>>() { | ||||||
|  |                     @Override | ||||||
|  |                     public Observable<? extends List<Book>> call(Map<Installer, List<Book>> books) { | ||||||
|  |                         return Observable.from(books.values()); | ||||||
|  |                     } | ||||||
|  |                 }) | ||||||
|  |                 // Then flatten the lists | ||||||
|  |                 .flatMap(new Func1<List<Book>, Observable<? extends Book>>() { | ||||||
|  |                     @Override | ||||||
|  |                     public Observable<? extends Book> call(List<Book> t1) { | ||||||
|  |                         return Observable.from(t1); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @ -57,15 +102,18 @@ public class RefreshManager { | |||||||
|      * @return The cached book list, or null |      * @return The cached book list, or null | ||||||
|      */ |      */ | ||||||
|     public List<Book> getBookList() { |     public List<Book> getBookList() { | ||||||
|         if (availableModules.values().size() == 0) { |         List<Book> availableList = new ArrayList<Book>(); | ||||||
|             return null; |         availableModules.reduce(availableList, | ||||||
|         } else { |                 new Func2<List<Book>, Map<Installer, List<Book>>, List<Book>>() { | ||||||
|             List<Book> bookList = new ArrayList<Book>(); |             @Override | ||||||
|             for (List<Book> l : availableModules.values()) { |             public List<Book> call(List<Book> books, Map<Installer, List<Book>> installerListMap) { | ||||||
|                 bookList.addAll(l); |                 for (List<Book> l : installerListMap.values()) { | ||||||
|  |                     books.addAll(l); | ||||||
|  |                 } | ||||||
|  |                 return books; | ||||||
|             } |             } | ||||||
|             return bookList; |         }); | ||||||
|         } |         return availableList; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @ -73,12 +121,28 @@ public class RefreshManager { | |||||||
|      * @param b The book to search for |      * @param b The book to search for | ||||||
|      * @return The Installer that should be used for this book. |      * @return The Installer that should be used for this book. | ||||||
|      */ |      */ | ||||||
|     public Installer installerFromBook(Book b) { |     public Observable<Installer> installerFromBook(final Book b) { | ||||||
|         for (Map.Entry<Installer, List<Book>> entry : availableModules.entrySet()) { |         return availableModules.filter(new Func1<Map<Installer, List<Book>>, Boolean>() { | ||||||
|             if (entry.getValue().contains(b)) { |             @Override | ||||||
|                 return entry.getKey(); |             public Boolean call(Map<Installer, List<Book>> installerListMap) { | ||||||
|  |                 for (List<Book> element : installerListMap.values()) { | ||||||
|  |                     if (element.contains(b)) { | ||||||
|  |                         return true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|             } |             } | ||||||
|         } |         }) | ||||||
|         return null; |         .first() | ||||||
|  |         .map(new Func1<Map<Installer, List<Book>>, Installer>() { | ||||||
|  |             @Override | ||||||
|  |             public Installer call(Map<Installer, List<Book>> element) { | ||||||
|  |                 return element.entrySet().iterator().next().getKey(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean isRefreshComplete() { | ||||||
|  |         return refreshComplete.get(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,10 +1,11 @@ | |||||||
| package org.bspeice.minimalbible.test; | package org.bspeice.minimalbible.test; | ||||||
|  |  | ||||||
| import android.test.InstrumentationTestCase; | import android.test.InstrumentationTestCase; | ||||||
|  | import android.util.Log; | ||||||
|  |  | ||||||
| import org.bspeice.minimalbible.MinimalBible; | import org.bspeice.minimalbible.MinimalBible; | ||||||
| import org.bspeice.minimalbible.MinimalBibleModules; | import org.bspeice.minimalbible.MinimalBibleModules; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadThread; | import org.bspeice.minimalbible.activities.downloader.manager.BookDownloadManager; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.DLProgressEvent; | import org.bspeice.minimalbible.activities.downloader.manager.DLProgressEvent; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; | import org.bspeice.minimalbible.activities.downloader.manager.DownloadManager; | ||||||
| import org.bspeice.minimalbible.activities.downloader.manager.InstalledManager; | import org.bspeice.minimalbible.activities.downloader.manager.InstalledManager; | ||||||
| @ -12,20 +13,25 @@ import org.bspeice.minimalbible.activities.downloader.manager.RefreshManager; | |||||||
| import org.crosswire.jsword.book.Book; | import org.crosswire.jsword.book.Book; | ||||||
| import org.crosswire.jsword.book.BookException; | import org.crosswire.jsword.book.BookException; | ||||||
| import org.crosswire.jsword.book.Books; | import org.crosswire.jsword.book.Books; | ||||||
|  | import org.crosswire.jsword.book.install.InstallException; | ||||||
| import org.crosswire.jsword.book.install.Installer; | import org.crosswire.jsword.book.install.Installer; | ||||||
| import org.crosswire.jsword.passage.NoSuchKeyException; | import org.crosswire.jsword.passage.NoSuchKeyException; | ||||||
|  |  | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
| import java.util.concurrent.Callable; | import java.util.concurrent.Callable; | ||||||
| import java.util.concurrent.CountDownLatch; | import java.util.concurrent.CountDownLatch; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  | import java.util.concurrent.atomic.AtomicBoolean; | ||||||
|  |  | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| import javax.inject.Provider; |  | ||||||
|  |  | ||||||
| import dagger.Module; | import dagger.Module; | ||||||
| import dagger.ObjectGraph; | import dagger.ObjectGraph; | ||||||
|  | import rx.Observable; | ||||||
|  |  | ||||||
| import static com.jayway.awaitility.Awaitility.*; | import static com.jayway.awaitility.Awaitility.await; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Tests for the Download activity |  * Tests for the Download activity | ||||||
| @ -38,8 +44,8 @@ public class DownloadActivityTest extends InstrumentationTestCase { | |||||||
|  |  | ||||||
|     @Inject DownloadManager dm; |     @Inject DownloadManager dm; | ||||||
|     @Inject InstalledManager im; |     @Inject InstalledManager im; | ||||||
|     @Inject Provider<BookDownloadThread> bookDownloadThreadProvider; |  | ||||||
|     @Inject RefreshManager rm; |     @Inject RefreshManager rm; | ||||||
|  |     @Inject BookDownloadManager bdm; | ||||||
|  |  | ||||||
|     public void setUp() { |     public void setUp() { | ||||||
|         MinimalBible application = MinimalBible.getApplication(); |         MinimalBible application = MinimalBible.getApplication(); | ||||||
| @ -52,40 +58,6 @@ public class DownloadActivityTest extends InstrumentationTestCase { | |||||||
|         assertEquals(true, true); |         assertEquals(true, true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * When we start a download, make sure a progress event of 0 is triggered. |  | ||||||
|      */ |  | ||||||
|     public void testInitialProgressEventOnDownload() throws InterruptedException { |  | ||||||
|         final CountDownLatch signal = new CountDownLatch(1); |  | ||||||
|  |  | ||||||
|         // Need to make sure we've refreshed the refreshmanager first |  | ||||||
|         Installer i = (Installer) dm.getInstallers().values().toArray()[0]; |  | ||||||
|         final Book testBook = i.getBooks().get(0); |  | ||||||
|         await().atMost(30, TimeUnit.SECONDS).until(new Callable<Boolean>() { |  | ||||||
|             @Override |  | ||||||
|             public Boolean call() throws Exception { |  | ||||||
|                 return rm.installerFromBook(testBook) != null; |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         // And wait for the actual download |  | ||||||
|         dm.getDownloadBus().register(new Object() { |  | ||||||
|             public void onEvent(DLProgressEvent event) { |  | ||||||
|                 if (event.getProgress() == 0) { |  | ||||||
|                     signal.countDown(); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         BookDownloadThread thread = bookDownloadThreadProvider.get(); |  | ||||||
|         thread.downloadBook(testBook); |  | ||||||
|  |  | ||||||
|         signal.await(10, TimeUnit.SECONDS); |  | ||||||
|         if (signal.getCount() != 0) { |  | ||||||
|             fail("Event did not trigger!"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Test that we can successfully download and remove a book |      * Test that we can successfully download and remove a book | ||||||
|      */ |      */ | ||||||
| @ -93,12 +65,14 @@ public class DownloadActivityTest extends InstrumentationTestCase { | |||||||
|         // Install a book |         // Install a book | ||||||
|         Installer i = (Installer) dm.getInstallers().values().toArray()[0]; |         Installer i = (Installer) dm.getInstallers().values().toArray()[0]; | ||||||
|         final Book testBook = i.getBooks().get(0); |         final Book testBook = i.getBooks().get(0); | ||||||
|         await().atMost(30, TimeUnit.SECONDS).until(new Callable<Boolean>() { |         bdm.installBook(testBook); | ||||||
|             @Override |         await().atMost(30, TimeUnit.SECONDS) | ||||||
|             public Boolean call() throws Exception { |                 .until(new Callable<Boolean>() { | ||||||
|                 return Books.installed().getBooks().contains(testBook); |                     @Override | ||||||
|             } |                     public Boolean call() throws Exception { | ||||||
|         }); |                         return Books.installed().getBooks().contains(testBook); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|         // Validate that we can actually do something with the book |         // Validate that we can actually do something with the book | ||||||
|         // TODO: Validate that the book exists on the filesystem too |         // TODO: Validate that the book exists on the filesystem too | ||||||
| @ -113,7 +87,13 @@ public class DownloadActivityTest extends InstrumentationTestCase { | |||||||
|         // Remove the book and make sure it's gone |         // Remove the book and make sure it's gone | ||||||
|         // TODO: Validate that the book is off the filesystem |         // TODO: Validate that the book is off the filesystem | ||||||
|         im.removeBook(testBook); |         im.removeBook(testBook); | ||||||
|         assertFalse(Books.installed().getBooks().contains(testBook)); |         await().atMost(10, TimeUnit.SECONDS) | ||||||
|  |                 .until(new Callable<Boolean>() { | ||||||
|  |                     @Override | ||||||
|  |                     public Boolean call() throws Exception { | ||||||
|  |                         return !Books.installed().getBooks().contains(testBook); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ dependencies { | |||||||
|  |  | ||||||
| android { | android { | ||||||
|     compileSdkVersion 19 |     compileSdkVersion 19 | ||||||
|     buildToolsVersion "19.0.3" |     buildToolsVersion "19.1.0" | ||||||
|  |  | ||||||
|     sourceSets { |     sourceSets { | ||||||
|         main { |         main { | ||||||
|  | |||||||
| @ -4,6 +4,6 @@ buildscript { | |||||||
|         mavenCentral() |         mavenCentral() | ||||||
|     } |     } | ||||||
|     dependencies { |     dependencies { | ||||||
|         classpath 'com.android.tools.build:gradle:0.9.+' |         classpath 'com.android.tools.build:gradle:0.11.+' | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| #Mon May 05 23:06:48 EDT 2014 | #Tue Jun 10 19:26:46 EDT 2014 | ||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
| distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.zip | distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Bradlee Speice
					Bradlee Speice