diff --git a/app/build.gradle b/app/build.gradle index b1ac16f..3d1d625 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,41 +1,65 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 - buildToolsVersion "23.0.1" + compileSdkVersion 28 + buildToolsVersion = '28.0.3' defaultConfig { applicationId "info.adavis.adeptandroid" - minSdkVersion 15 - targetSdkVersion 23 + minSdkVersion 21 + targetSdkVersion 28 versionCode 1 versionName "1.0" } + buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + + lintOptions { + abortOnError false + } + + compileOptions { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' + } } ext { - supportLibraryVersion = '23.0.1' - okhttpVersion = '2.4.0' + supportLibraryVersion = '28.0.0' + retrofitVersion = '2.5.0' } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' - compile "com.android.support:appcompat-v7:$supportLibraryVersion" - compile "com.android.support:recyclerview-v7:$supportLibraryVersion" - compile "com.android.support:design:$supportLibraryVersion" - compile "com.squareup.okhttp:okhttp:$okhttpVersion" - compile "com.squareup.okhttp:okhttp-urlconnection:$okhttpVersion" - compile 'com.jakewharton:butterknife:7.0.1' - compile 'com.jakewharton.timber:timber:3.1.0' - compile 'de.greenrobot:eventbus:2.4.0' - compile 'com.mcxiaoke.volley:library:1.0.18' - compile 'com.squareup.picasso:picasso:2.5.2' - compile 'org.immutables:gson:2.1.0.alpha' + // Support Libraries + implementation "com.android.support:appcompat-v7:$supportLibraryVersion" + implementation "com.android.support:recyclerview-v7:$supportLibraryVersion" + implementation "com.android.support:design:$supportLibraryVersion" + + // REST Interactions + implementation ("com.squareup.retrofit2:retrofit:$retrofitVersion") + + // JSON Parsing + implementation 'com.google.code.gson:gson:2.8.5' + implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion" + + // View Injection + implementation 'com.jakewharton:butterknife:9.0.0' + annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0' + + // Logging + implementation 'com.jakewharton.timber:timber:4.7.1' + + // Events + implementation 'de.greenrobot:eventbus:2.4.0' + + // Image Loading + implementation 'com.squareup.picasso:picasso:2.71828@aar' + + // Testing + testImplementation 'junit:junit:4.12' } diff --git a/app/src/androidTest/java/info/adavis/adeptandroid/ApplicationTest.java b/app/src/androidTest/java/info/adavis/adeptandroid/ApplicationTest.java deleted file mode 100644 index f31ce30..0000000 --- a/app/src/androidTest/java/info/adavis/adeptandroid/ApplicationTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package info.adavis.adeptandroid; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8f444ee..89a0ef1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,8 +10,9 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > + @@ -20,6 +21,12 @@ + + + + diff --git a/app/src/main/java/info/adavis/adeptandroid/Constants.java b/app/src/main/java/info/adavis/adeptandroid/Constants.java new file mode 100644 index 0000000..5523ffa --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/Constants.java @@ -0,0 +1,9 @@ +package info.adavis.adeptandroid; + +/** + * @author Annyce Davis + */ +public class Constants +{ + public static final String BASE_URL = "http://10.0.2.2:8080"; +} diff --git a/app/src/main/java/info/adavis/adeptandroid/activities/MainActivity.java b/app/src/main/java/info/adavis/adeptandroid/activities/MainActivity.java deleted file mode 100644 index ef9657f..0000000 --- a/app/src/main/java/info/adavis/adeptandroid/activities/MainActivity.java +++ /dev/null @@ -1,89 +0,0 @@ -package info.adavis.adeptandroid.activities; - -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.Toolbar; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.List; - -import butterknife.Bind; -import butterknife.ButterKnife; -import info.adavis.adeptandroid.models.Book; -import info.adavis.adeptandroid.R; -import info.adavis.adeptandroid.adapters.BooksAdapter; -import timber.log.Timber; - -public class MainActivity extends AppCompatActivity { - - private static final String CHARSET_NAME = "UTF-8"; - - private List books; - - @Bind(R.id.recyclerView) RecyclerView recyclerView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - ButterKnife.bind(this); - - initDataSet(); - configureLayout(); - } - - private void configureLayout() { - setSupportActionBar((Toolbar) ButterKnife.findById(this, R.id.toolbar)); - - RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); - recyclerView.setLayoutManager(layoutManager); - recyclerView.setAdapter(new BooksAdapter(this, books)); - } - - private void initDataSet() { - String json = null; - - try { - json = getJsonData(); - } - catch (Exception e) { - Timber.e("an exception occurred", e); - } - - if (json != null) { - books = new Gson().fromJson(new StringReader(json), new TypeToken>() { }.getType()); - } - } - - private String getJsonData() throws Exception { - Writer writer = new StringWriter(); - InputStream is = null; - try { - is = getResources().openRawResource(R.raw.sample_data); - Reader reader = new BufferedReader(new InputStreamReader(is, CHARSET_NAME)); - int n; - char[] buffer = new char[1024]; - while ((n = reader.read(buffer)) != -1) { - writer.write(buffer, 0, n); - } - } finally { - if (is != null) { - is.close(); - } - } - - return writer.toString(); - } -} diff --git a/app/src/main/java/info/adavis/adeptandroid/book/BookActivity.java b/app/src/main/java/info/adavis/adeptandroid/book/BookActivity.java new file mode 100644 index 0000000..39d5278 --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/book/BookActivity.java @@ -0,0 +1,52 @@ +package info.adavis.adeptandroid.book; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.widget.TextView; +import android.widget.Toast; + +import butterknife.BindView; +import butterknife.ButterKnife; +import info.adavis.adeptandroid.R; +import info.adavis.adeptandroid.di.Injector; +import info.adavis.adeptandroid.models.Book; + +public class BookActivity extends AppCompatActivity implements BookContract.View +{ + public static final String EXTRA_BOOK_ID = "EXTRA_BOOK_ID"; + + @BindView(R.id.titleText) TextView titleText; + @BindView(R.id.authorText) TextView authorText; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_book); + + ButterKnife.bind(this); + + BookPresenter bookPresenter = new BookPresenter(this, Injector.provideBookService()); + bookPresenter.retrieveBook(getIntent().getLongExtra(EXTRA_BOOK_ID, 1)); + + configureLayout(); + } + + @Override + public void showBook(Book book) + { + titleText.setText(book.getTitle()); + authorText.setText(book.getAuthor()); + } + + @Override + public void showErrorMessage() + { + Toast.makeText(this, R.string.book_loading_unsuccessful, Toast.LENGTH_SHORT).show(); + } + + private void configureLayout() { + setSupportActionBar(findViewById(R.id.toolbar)); + } + +} diff --git a/app/src/main/java/info/adavis/adeptandroid/book/BookContract.java b/app/src/main/java/info/adavis/adeptandroid/book/BookContract.java new file mode 100644 index 0000000..95822e6 --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/book/BookContract.java @@ -0,0 +1,17 @@ +package info.adavis.adeptandroid.book; + +import info.adavis.adeptandroid.models.Book; + +/** + * The contract between the view and presenter + */ +public interface BookContract +{ + interface View + { + void showErrorMessage(); + + void showBook(Book book); + } + +} diff --git a/app/src/main/java/info/adavis/adeptandroid/book/BookPresenter.java b/app/src/main/java/info/adavis/adeptandroid/book/BookPresenter.java new file mode 100644 index 0000000..ed98322 --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/book/BookPresenter.java @@ -0,0 +1,44 @@ +package info.adavis.adeptandroid.book; + +import info.adavis.adeptandroid.data.BookService; +import info.adavis.adeptandroid.models.Book; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import timber.log.Timber; + +class BookPresenter +{ + private final BookContract.View bookView; + private final BookService service; + + BookPresenter (BookContract.View bookView, BookService service) + { + this.bookView = bookView; + this.service = service; + } + + void retrieveBook (long id) + { + service.getBook(id).enqueue(new Callback() + { + @Override + public void onResponse (Call call, Response response) + { + if (response.isSuccessful()) + { + bookView.showBook(response.body()); + Timber.i("Book data was loaded from API."); + } + } + + @Override + public void onFailure(Call call, Throwable t) + { + bookView.showErrorMessage(); + Timber.e(t, "Unable to load the book data from API."); + } + }); + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/adavis/adeptandroid/books/BooksActivity.java b/app/src/main/java/info/adavis/adeptandroid/books/BooksActivity.java new file mode 100644 index 0000000..48e5526 --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/books/BooksActivity.java @@ -0,0 +1,73 @@ +package info.adavis.adeptandroid.books; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import info.adavis.adeptandroid.R; +import info.adavis.adeptandroid.book.BookActivity; +import info.adavis.adeptandroid.di.Injector; +import info.adavis.adeptandroid.models.Book; +import timber.log.Timber; + +public class BooksActivity extends AppCompatActivity implements BooksContract.View +{ + + private BooksAdapter booksAdapter; + + @BindView(R.id.recyclerView) RecyclerView recyclerView; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + ButterKnife.bind(this); + + BooksPresenter booksPresenter = new BooksPresenter(this, Injector.provideBookService()); + booksAdapter = new BooksAdapter(this, new ArrayList<>(0), itemListener); + + booksPresenter.initDataSet(); + + configureLayout(); + } + + @Override + public void showBooks(List books) + { + booksAdapter.updateBooks(books); + } + + @Override + public void showErrorMessage() + { + Toast.makeText(this, R.string.books_loading_unsuccessful, Toast.LENGTH_SHORT).show(); + } + + private void configureLayout() + { + setSupportActionBar(findViewById(R.id.toolbar)); + + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); + recyclerView.setLayoutManager(layoutManager); + recyclerView.setAdapter(booksAdapter); + recyclerView.setHasFixedSize(true); + } + + private BooksAdapter.BookItemListener itemListener = id -> { + Timber.d("book clicked id: %d", id); + Intent intent = new Intent(BooksActivity.this, BookActivity.class); + intent.putExtra(BookActivity.EXTRA_BOOK_ID, id); + startActivity(intent); + }; + +} diff --git a/app/src/main/java/info/adavis/adeptandroid/adapters/BooksAdapter.java b/app/src/main/java/info/adavis/adeptandroid/books/BooksAdapter.java similarity index 57% rename from app/src/main/java/info/adavis/adeptandroid/adapters/BooksAdapter.java rename to app/src/main/java/info/adavis/adeptandroid/books/BooksAdapter.java index b594257..c71c277 100644 --- a/app/src/main/java/info/adavis/adeptandroid/adapters/BooksAdapter.java +++ b/app/src/main/java/info/adavis/adeptandroid/books/BooksAdapter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package info.adavis.adeptandroid.adapters; +package info.adavis.adeptandroid.books; import android.content.Context; import android.support.v7.widget.RecyclerView; @@ -26,49 +26,72 @@ import com.squareup.picasso.Picasso; +import org.jetbrains.annotations.NotNull; + import java.lang.ref.WeakReference; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; -import info.adavis.adeptandroid.models.Book; import info.adavis.adeptandroid.R; +import info.adavis.adeptandroid.models.Book; import timber.log.Timber; -public class BooksAdapter extends RecyclerView.Adapter { +public class BooksAdapter extends RecyclerView.Adapter +{ private WeakReference context; private List books; + private BookItemListener itemListener; + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener + { - public static class ViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.titleTextView) TextView titleTextView; + @BindView(R.id.authorTextView) TextView authorTextView; + @BindView(R.id.publishedTextView) TextView publishedTextView; + @BindView(R.id.pagesTextView) TextView pagesTextView; + @BindView(R.id.imageView) ImageView imageView; - @Bind(R.id.titleTextView) TextView titleTextView; - @Bind(R.id.authorTextView) TextView authorTextView; - @Bind(R.id.publishedTextView) TextView publishedTextView; - @Bind(R.id.pagesTextView) TextView pagesTextView; - @Bind(R.id.imageView) ImageView imageView; + BookItemListener itemListener; - public ViewHolder(View v) { + ViewHolder(View v, BookItemListener itemListener) + { super(v); ButterKnife.bind(this, v); + + this.itemListener = itemListener; + v.setOnClickListener(this); + } + + @Override + public void onClick (View v) + { + Book book = getItem(getAdapterPosition()); + this.itemListener.onBookClick( book.getId() ); } } - public BooksAdapter(Context context, List books) { + BooksAdapter(Context context, List books, BookItemListener itemListener) + { this.context = new WeakReference<>(context); this.books = books; + this.itemListener = itemListener; } + @NotNull @Override - public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { + public ViewHolder onCreateViewHolder(@NotNull ViewGroup viewGroup, int viewType) + { View v = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.book_row_item, viewGroup, false); - return new ViewHolder(v); + return new ViewHolder(v, this.itemListener); } @Override - public void onBindViewHolder(ViewHolder viewHolder, final int position) { + public void onBindViewHolder(@NotNull ViewHolder viewHolder, final int position) + { Timber.d("Element " + position + " set."); Book book = books.get(position); @@ -82,7 +105,7 @@ public void onBindViewHolder(ViewHolder viewHolder, final int position) { viewHolder.pagesTextView.setText( String.format(contextLocal.getString(R.string.pages_label), book.getNumberOfPages())); - Picasso.with(contextLocal) + Picasso.get() .load(book.getImageUrl()) .resize(80, 108) .centerInside() @@ -91,7 +114,24 @@ public void onBindViewHolder(ViewHolder viewHolder, final int position) { } @Override - public int getItemCount() { + public int getItemCount() + { return books.size(); } + + void updateBooks(List books) + { + this.books = books; + notifyDataSetChanged(); + } + + private Book getItem(int adapterPosition) + { + return books.get(adapterPosition); + } + + public interface BookItemListener + { + void onBookClick(long id); + } } diff --git a/app/src/main/java/info/adavis/adeptandroid/books/BooksContract.java b/app/src/main/java/info/adavis/adeptandroid/books/BooksContract.java new file mode 100644 index 0000000..6759fe3 --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/books/BooksContract.java @@ -0,0 +1,21 @@ +package info.adavis.adeptandroid.books; + +import java.util.List; + +import info.adavis.adeptandroid.models.Book; + +/** + * The contract between the view and presenter + */ +public interface BooksContract +{ + + interface View + { + + void showBooks(List books); + + void showErrorMessage(); + } + +} diff --git a/app/src/main/java/info/adavis/adeptandroid/books/BooksPresenter.java b/app/src/main/java/info/adavis/adeptandroid/books/BooksPresenter.java new file mode 100644 index 0000000..4915e75 --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/books/BooksPresenter.java @@ -0,0 +1,46 @@ +package info.adavis.adeptandroid.books; + +import java.util.List; + +import info.adavis.adeptandroid.data.BookService; +import info.adavis.adeptandroid.models.Book; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import timber.log.Timber; + +class BooksPresenter +{ + private final BooksContract.View booksView; + private final BookService service; + + BooksPresenter(BooksContract.View booksView, BookService service) + { + this.booksView = booksView; + this.service = service; + } + + void initDataSet() + { + service.getBooks().enqueue(new Callback>() + { + @Override + public void onResponse(Call> call, Response> response) + { + if (response.isSuccessful()) + { + booksView.showBooks(response.body()); + Timber.i("Books data was loaded from API."); + } + } + + @Override + public void onFailure(Call> call, Throwable t) + { + booksView.showErrorMessage(); + Timber.e(t, "Unable to load the books data from API."); + } + }); + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/adavis/adeptandroid/data/BookService.java b/app/src/main/java/info/adavis/adeptandroid/data/BookService.java new file mode 100644 index 0000000..71bfc82 --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/data/BookService.java @@ -0,0 +1,25 @@ +package info.adavis.adeptandroid.data; + +import java.util.List; + +import info.adavis.adeptandroid.models.Book; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Path; +import retrofit2.http.Query; + +/** + * @author Annyce Davis + */ +public interface BookService +{ + + @GET("books") + Call> getBooks(); + + @GET("books") + Call> search(@Query("q") String query); + + @GET("books/{id}") + Call getBook(@Path("id") Long id); +} diff --git a/app/src/main/java/info/adavis/adeptandroid/di/Injector.java b/app/src/main/java/info/adavis/adeptandroid/di/Injector.java new file mode 100644 index 0000000..b97740b --- /dev/null +++ b/app/src/main/java/info/adavis/adeptandroid/di/Injector.java @@ -0,0 +1,27 @@ +package info.adavis.adeptandroid.di; + +import info.adavis.adeptandroid.Constants; +import info.adavis.adeptandroid.data.BookService; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * @author Annyce Davis + */ +public class Injector +{ + + public static Retrofit provideRetrofit(String baseUrl) + { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + } + + public static BookService provideBookService() + { + return provideRetrofit(Constants.BASE_URL).create(BookService.class); + } + +} diff --git a/app/src/main/java/info/adavis/adeptandroid/models/Book.java b/app/src/main/java/info/adavis/adeptandroid/models/Book.java index cb64c89..e395b20 100644 --- a/app/src/main/java/info/adavis/adeptandroid/models/Book.java +++ b/app/src/main/java/info/adavis/adeptandroid/models/Book.java @@ -1,8 +1,10 @@ package info.adavis.adeptandroid.models; +import org.jetbrains.annotations.NotNull; public class Book { + long id; String title; String author; String bookUrl; @@ -10,6 +12,10 @@ public class Book { String displayDate; int numberOfPages; + public long getId() { + return id; + } + public String getTitle() { return title; } @@ -34,6 +40,7 @@ public int getNumberOfPages() { return numberOfPages; } + @NotNull @Override public String toString() { return "Book{" + diff --git a/app/src/main/res/layout/activity_book.xml b/app/src/main/res/layout/activity_book.xml new file mode 100644 index 0000000..19bdbff --- /dev/null +++ b/app/src/main/res/layout/activity_book.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 7b1bb4e..a9e8da2 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,27 +1,11 @@ + android:fitsSystemWindows="true"> - - - - - + diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index a8b39be..98a3279 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -12,7 +12,7 @@ android:background="@color/indigo_100" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_main" - tools:context=".MainActivity"> + tools:context=".books.BooksActivity"> + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index be8f6e1..759aee7 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -8,4 +8,5 @@ 4dp 80dp 108dp + 16dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 46bf308..cb8cd8b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,4 +2,12 @@ Adept Android thumbnail %d pages + Unable to load the books. + Unable to load the book + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ut enim et augue interdum pellentesque. + Maecenas elementum nibh nulla, sit amet egestas dui tristique efficitur. Sed vitae feugiat magna. Nunc sed eros nulla. + In molestie et neque fringilla egestas. Ut elementum scelerisque ligula in pulvinar.\n\nUt in neque at + leo rutrum vestibulum ac vel lectus. Duis in lobortis erat, a rhoncus mauris. + Curabitur a aliquet massa. Quisque aliquam mauris id molestie egestas. + Vivamus vitae massa cursus, aliquam urna sit amet, placerat nibh. diff --git a/app/src/test/java/info/adavis/adeptandroid/ExampleUnitTest.java b/app/src/test/java/info/adavis/adeptandroid/ExampleUnitTest.java deleted file mode 100644 index c5dafff..0000000 --- a/app/src/test/java/info/adavis/adeptandroid/ExampleUnitTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package info.adavis.adeptandroid; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/build.gradle b/build.gradle index be515a8..9d4c52c 100644 --- a/build.gradle +++ b/build.gradle @@ -2,10 +2,12 @@ buildscript { repositories { + google() + mavenCentral() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.0' + classpath 'com.android.tools.build:gradle:3.4.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -14,6 +16,8 @@ buildscript { allprojects { repositories { + google() + mavenCentral() jcenter() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9d079bb..1757b9a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Sep 23 12:38:38 EDT 2015 +#Sun Apr 17 17:50:31 EDT 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip