Added Basic Pic Of the Day App Widget (#1523)

* Added Basic Pic Of the Day App Widget

* Added Java Lib for XML to JSON

* Added missing json library from xml to json

* Undone formatting

* Consolidate the networking libraries - drop volley in favor of OkHttp

* Extracted a few networking related items into a new Dagger module and finished the process of mocking the main component for tests.

* Refactoring to extract GpsCategoryModel and ensure single-responsibility-principle is maintained in CategoryApi.

* Updated PicOfDayAppWidget class to parse HTML

* fixed featured image back bug

* Localisation updates from https://translatewiki.net.

* Javadocs added

* Add option to set image as wallpaper (#1535)

* Add option to set image as wallpaper

* Added java docs

* Toast message on setting the wallpaper successfully

* Localisation updates from https://translatewiki.net.

* Add dependencies to com.android.support.test.rules and runner

Needed for ActivityTestRule used in SettingsActivityTest

* Added Basic Pic Of the Day App Widget

* Added Java Lib for XML to JSON

* Added missing json library from xml to json

* Undone formatting

* Updated PicOfDayAppWidget class to parse HTML
This commit is contained in:
Madhur Gupta 2018-06-14 14:40:52 +05:30 committed by Josephine Lim
parent a0fe8b0745
commit 2cfbb67f1c
10 changed files with 192 additions and 53 deletions

View file

@ -7,6 +7,8 @@ apply from: 'quality.gradle'
apply plugin: 'com.getkeepsafe.dexcount'
dependencies {
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.prof.rssparser:rssparser:1.1'
implementation 'com.github.nicolas-raoul:Quadtree:ac16ea8035bf07'
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
implementation 'in.yuvi:http.fluent:1.3'
@ -19,48 +21,37 @@ dependencies {
implementation 'com.jakewharton.timber:timber:4.5.1'
implementation 'info.debatty:java-string-similarity:0.24'
implementation 'com.borjabravo:readmoretextview:2.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation ('com.mapbox.mapboxsdk:mapbox-android-sdk:5.4.1@aar'){
transitive=true
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation('com.mapbox.mapboxsdk:mapbox-android-sdk:5.4.1@aar') {
transitive = true
}
implementation "com.github.deano2390:MaterialShowcaseView:1.2.0"
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION"
implementation "com.android.support:appcompat-v7:$SUPPORT_LIB_VERSION"
implementation "com.android.support:design:$SUPPORT_LIB_VERSION"
implementation "com.android.support:customtabs:$SUPPORT_LIB_VERSION"
implementation "com.android.support:cardview-v7:$SUPPORT_LIB_VERSION"
implementation "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
kapt "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
implementation 'com.squareup.okio:okio:1.13.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.
implementation 'com.android.support:multidex:1.0.3'
implementation 'io.reactivex.rxjava2:rxjava:2.1.2'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
implementation 'org.jsoup:jsoup:1.11.3'
implementation 'com.facebook.fresco:fresco:1.5.0'
implementation 'com.facebook.stetho:stetho:1.5.0'
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
testImplementation "org.robolectric:multidex:3.4.2"
testImplementation 'org.robolectric:multidex:3.4.2'
testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
testImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
testImplementation 'junit:junit:4.12'
@ -134,6 +125,7 @@ android {
flavorDimensions 'tier'
productFlavors {
prod {
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.org/w/api.php\""
buildConfigField "String", "WIKIDATA_API_HOST", "\"https://www.wikidata.org/w/api.php\""
buildConfigField "String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\""
@ -151,6 +143,7 @@ android {
beta {
// What values do we need to hit the BETA versions of the site / api ?
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.beta.wmflabs.org/w/api.php\""
buildConfigField "String", "WIKIDATA_API_HOST", "\"https://www.wikidata.org/w/api.php\""
buildConfigField "String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\""

BIN
app/libs/java-json.jar Normal file

Binary file not shown.

View file

@ -165,6 +165,16 @@
android:label="@string/provider_categories"
android:syncable="false" />
<receiver android:name=".widget.PicOfDayAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/pic_of_day_app_widget_info" />
</receiver>
</application>
</manifest>

View file

@ -0,0 +1,80 @@
package fr.free.nrw.commons.widget;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
import com.prof.rssparser.Article;
import com.prof.rssparser.Parser;
import com.squareup.picasso.Picasso;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.R;
/**
* Implementation of App Widget functionality.
*/
public class PicOfDayAppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.pic_of_day_app_widget);
String urlString = BuildConfig.WIKIMEDIA_API_POTD;
Parser parser = new Parser();
parser.execute(urlString);
parser.onFinish(new Parser.OnTaskCompleted() {
@Override
public void onTaskCompleted(ArrayList<Article> list) {
String desc = list.get(list.size() - 1).getDescription();
if (desc != null) {
Document document = Jsoup.parse(desc);
Elements elements = document.select("img");
String imageUrl = elements.get(0).attr("src");
if (imageUrl != null && imageUrl.length() > 0) {
Picasso.get().load(imageUrl).into(views, R.id.appwidget_image, new int[]{appWidgetId});
}
}
}
@Override
public void onError() {
}
});
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}

View file

@ -0,0 +1,25 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:padding="@dimen/widget_margin"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="20sp"
android:gravity="center"
android:layout_marginTop="10dp"
android:text="@string/app_widget_heading"/>
<ImageView
android:padding="15dp"
android:id="@+id/appwidget_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/appwidget_img" />
</LinearLayout>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
Refer to App Widget Documentation for margin information
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
-->
<dimen name="widget_margin">0dp</dimen>
</resources>

View file

@ -52,4 +52,6 @@
<color name="bottom_bar_dark">#424242</color>
<color name="opak_middle_grey">#757575</color>
<color name="white">#FFFFFF</color>
<color name="black">#000000</color>
</resources>

View file

@ -25,4 +25,10 @@
<dimen name="description_text_size">14sp</dimen>
<dimen name="first_fab">15dp</dimen>
<dimen name="second_fab">25dp</dimen>
<!--
Refer to App Widget Documentation for margin information
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
-->
<dimen name="widget_margin">8dp</dimen>
</resources>

View file

@ -241,47 +241,49 @@
<string name="nominated_see_more"><u>See webpage for details</u></string>
<string name="view_browser">View in Browser</string>
<string name="nearby_location_has_not_changed">Location has not changed.</string>
<string name="nearby_location_not_available">Location not available.</string>
<string name="location_permission_rationale_nearby">Permission required to display a list of nearby places</string>
<string name="get_directions">GET DIRECTIONS</string>
<string name="read_article">READ ARTICLE</string>
<string name="nearby_location_has_not_changed">Location has not changed.</string>
<string name="nearby_location_not_available">Location not available.</string>
<string name="location_permission_rationale_nearby">Permission required to display a list of nearby places</string>
<string name="get_directions">GET DIRECTIONS</string>
<string name="read_article">READ ARTICLE</string>
<string name="notifications_welcome" formatted="false">Welcome to Wikimedia Commons, %1$s! We\'re glad you\'re here.</string>
<string name="notifications_talk_page_message">%1$s left a message on your talk page</string>
<string name="notifications_thank_you_edit">Thank you for making an edit</string>
<string name="notifications_mention">%1$s mentioned you on %2$s.</string>
<string name="toggle_view_button">Toggle view</string>
<string name="nearby_directions">DIRECTIONS</string>
<string name="nearby_wikidata">WIKIDATA</string>
<string name="nearby_wikipedia">WIKIPEDIA</string>
<string name="nearby_commons">COMMONS</string>
<string name="about_rate_us"><![CDATA[<u>Rate us</u>]]></string>
<string name="about_faq"><![CDATA[<u>FAQ</u>]]></string>
<string name="welcome_skip_button">Skip Tutorial</string>
<string name="no_internet">Internet unavailable</string>
<string name="internet_established">Internet available</string>
<string name="error_notifications">Error fetching notifications</string>
<string name="no_notifications">No notifications found</string>
<string name="about_translate"><![CDATA[<u>Translate</u>]]></string>
<string name="about_translate_title">Languages</string>
<string name="about_translate_message">Select the language that you would like to submit translations for</string>
<string name="about_translate_proceed">Proceed</string>
<string name="about_translate_cancel">Cancel</string>
<string name="retry">Retry</string>
<string name="notifications_welcome" formatted="false">Welcome to Wikimedia Commons, %1$s! We\'re glad you\'re here.</string>
<string name="notifications_talk_page_message">%1$s left a message on your talk page</string>
<string name="notifications_thank_you_edit">Thank you for making an edit</string>
<string name="notifications_mention">%1$s mentioned you on %2$s.</string>
<string name="toggle_view_button">Toggle view</string>
<string name="nearby_directions">DIRECTIONS</string>
<string name="nearby_wikidata">WIKIDATA</string>
<string name="nearby_wikipedia">WIKIPEDIA</string>
<string name="nearby_commons">COMMONS</string>
<string name="about_rate_us"><![CDATA[<u>Rate us</u>]]></string>
<string name="about_faq"><![CDATA[<u>FAQ</u>]]></string>
<string name="welcome_skip_button">Skip Tutorial</string>
<string name="no_internet">Internet unavailable</string>
<string name="internet_established">Internet available</string>
<string name="error_notifications">Error fetching notifications</string>
<string name="no_notifications">No notifications found</string>
<string name="about_translate"><![CDATA[<u>Translate</u>]]></string>
<string name="about_translate_title">Languages</string>
<string name="about_translate_message">Select the language that you would like to submit translations for</string>
<string name="about_translate_proceed">Proceed</string>
<string name="about_translate_cancel">Cancel</string>
<string name="retry">Retry</string>
<string name="showcase_view_got_it_button">Got it!</string>
<string name="showcase_view_whole_nearby_activity">These are the places near you that need pictures to illustrate their Wikipedia articles</string>
<string name="showcase_view_list_icon">Tapping this button brings up a list of these places</string>
<string name="showcase_view_plus_fab">You can upload a picture for any place from your gallery or camera</string>
<string name="showcase_view_got_it_button">Got it!</string>
<string name="showcase_view_whole_nearby_activity">These are the places near you that need pictures to illustrate their Wikipedia articles</string>
<string name="showcase_view_list_icon">Tapping this button brings up a list of these places</string>
<string name="showcase_view_plus_fab">You can upload a picture for any place from your gallery or camera</string>
<string name="no_images_found">No images found!</string>
<string name="error_loading_images">Error occurred while loading images.</string>
<string name="image_uploaded_by">Uploaded by: %1$s</string>
<string name="no_images_found">No images found!</string>
<string name="error_loading_images">Error occurred while loading images.</string>
<string name="image_uploaded_by">Uploaded by: %1$s</string>
<string name="share_app_title">Share App</string>
<string name="share_coordinates_not_present">Coordinates were not specified during image selection</string>
<string name="error_fetching_nearby_places">Error fetching nearby places.</string>
<string name="share_app_title">Share App</string>
<string name="share_coordinates_not_present">Coordinates were not specified during image selection</string>
<string name="error_fetching_nearby_places">Error fetching nearby places.</string>
<string name="appwidget_img">Pic of the Day</string>
<string name="app_widget_heading">Pic of the Day</string>
<string name="successful_wikidata_edit">Image successfully added to %1$s on Wikidata!</string>
<string name="wikidata_edit_failure">Failed to update corresponding Wikidata entity!</string>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/pic_of_day_app_widget"
android:initialLayout="@layout/pic_of_day_app_widget"
android:minHeight="250dp"
android:minWidth="250dp"
android:previewImage="@drawable/ic_launcher"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen"></appwidget-provider>