From e642fd72bcf507bb2258c8224e207b55061db08a Mon Sep 17 00:00:00 2001
From: Camil Staps
Date: Mon, 6 Apr 2015 21:41:41 +0200
Subject: initial commit
---
.gitignore | 6 +
.idea/.name | 1 +
.idea/compiler.xml | 23 ++
.idea/copyright/profiles_settings.xml | 3 +
.idea/encodings.xml | 5 +
.idea/gradle.xml | 18 ++
.idea/misc.xml | 26 ++
.idea/modules.xml | 10 +
.idea/scopes/scope_settings.xml | 5 +
.idea/vcs.xml | 8 +
"Taiz\303\251.iml" | 19 ++
app/.gitignore | 1 +
app/app.iml | 94 ++++++
app/build.gradle | 26 ++
app/libs/volley.jar | Bin 0 -> 85763 bytes
app/proguard-rules.pro | 17 ++
.../java/com/camilstaps/taize/ApplicationTest.java | 13 +
app/src/main/AndroidManifest.xml | 32 +++
.../main/java/com/camilstaps/common/Listener.java | 20 ++
.../java/com/camilstaps/common/NullListener.java | 14 +
.../java/com/camilstaps/rss/RetrieveFeedTask.java | 37 +++
.../main/java/com/camilstaps/rss/RssParser.java | 293 +++++++++++++++++++
app/src/main/java/com/camilstaps/taize/Bible.java | 86 ++++++
.../main/java/com/camilstaps/taize/BibleText.java | 73 +++++
.../java/com/camilstaps/taize/MainActivity.java | 165 +++++++++++
.../camilstaps/taize/NavigationDrawerFragment.java | 317 +++++++++++++++++++++
.../com/camilstaps/taize/SettingsActivity.java | 66 +++++
app/src/main/java/com/camilstaps/taize/Taize.java | 224 +++++++++++++++
app/src/main/res/drawable-hdpi/drawer_shadow.9.png | Bin 0 -> 161 bytes
app/src/main/res/drawable-hdpi/ic_drawer.png | Bin 0 -> 2829 bytes
app/src/main/res/drawable-mdpi/drawer_shadow.9.png | Bin 0 -> 142 bytes
app/src/main/res/drawable-mdpi/ic_drawer.png | Bin 0 -> 2820 bytes
.../main/res/drawable-xhdpi/drawer_shadow.9.png | Bin 0 -> 174 bytes
app/src/main/res/drawable-xhdpi/ic_drawer.png | Bin 0 -> 2836 bytes
.../main/res/drawable-xxhdpi/drawer_shadow.9.png | Bin 0 -> 208 bytes
app/src/main/res/drawable-xxhdpi/ic_drawer.png | Bin 0 -> 202 bytes
app/src/main/res/layout/activity_main.xml | 40 +++
app/src/main/res/layout/fragment_main.xml | 12 +
.../main/res/layout/fragment_navigation_drawer.xml | 5 +
app/src/main/res/menu/global.xml | 5 +
app/src/main/res/menu/main.xml | 8 +
app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes
app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes
app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes
app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes
app/src/main/res/values-w820dp/dimens.xml | 6 +
app/src/main/res/values/dimens.xml | 9 +
app/src/main/res/values/preference_values.xml | 152 ++++++++++
app/src/main/res/values/strings.xml | 13 +
app/src/main/res/values/styles.xml | 8 +
app/src/main/res/xml/preferences.xml | 27 ++
build.gradle | 19 ++
gradle.properties | 18 ++
gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 49896 bytes
gradle/wrapper/gradle-wrapper.properties | 6 +
gradlew | 164 +++++++++++
gradlew.bat | 90 ++++++
settings.gradle | 1 +
58 files changed, 2185 insertions(+)
create mode 100644 .gitignore
create mode 100644 .idea/.name
create mode 100644 .idea/compiler.xml
create mode 100644 .idea/copyright/profiles_settings.xml
create mode 100644 .idea/encodings.xml
create mode 100644 .idea/gradle.xml
create mode 100644 .idea/misc.xml
create mode 100644 .idea/modules.xml
create mode 100644 .idea/scopes/scope_settings.xml
create mode 100644 .idea/vcs.xml
create mode 100644 "Taiz\303\251.iml"
create mode 100644 app/.gitignore
create mode 100644 app/app.iml
create mode 100644 app/build.gradle
create mode 100644 app/libs/volley.jar
create mode 100644 app/proguard-rules.pro
create mode 100644 app/src/androidTest/java/com/camilstaps/taize/ApplicationTest.java
create mode 100644 app/src/main/AndroidManifest.xml
create mode 100644 app/src/main/java/com/camilstaps/common/Listener.java
create mode 100644 app/src/main/java/com/camilstaps/common/NullListener.java
create mode 100644 app/src/main/java/com/camilstaps/rss/RetrieveFeedTask.java
create mode 100644 app/src/main/java/com/camilstaps/rss/RssParser.java
create mode 100644 app/src/main/java/com/camilstaps/taize/Bible.java
create mode 100644 app/src/main/java/com/camilstaps/taize/BibleText.java
create mode 100644 app/src/main/java/com/camilstaps/taize/MainActivity.java
create mode 100644 app/src/main/java/com/camilstaps/taize/NavigationDrawerFragment.java
create mode 100644 app/src/main/java/com/camilstaps/taize/SettingsActivity.java
create mode 100644 app/src/main/java/com/camilstaps/taize/Taize.java
create mode 100644 app/src/main/res/drawable-hdpi/drawer_shadow.9.png
create mode 100644 app/src/main/res/drawable-hdpi/ic_drawer.png
create mode 100644 app/src/main/res/drawable-mdpi/drawer_shadow.9.png
create mode 100644 app/src/main/res/drawable-mdpi/ic_drawer.png
create mode 100644 app/src/main/res/drawable-xhdpi/drawer_shadow.9.png
create mode 100644 app/src/main/res/drawable-xhdpi/ic_drawer.png
create mode 100644 app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png
create mode 100644 app/src/main/res/drawable-xxhdpi/ic_drawer.png
create mode 100644 app/src/main/res/layout/activity_main.xml
create mode 100644 app/src/main/res/layout/fragment_main.xml
create mode 100644 app/src/main/res/layout/fragment_navigation_drawer.xml
create mode 100644 app/src/main/res/menu/global.xml
create mode 100644 app/src/main/res/menu/main.xml
create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png
create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png
create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png
create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png
create mode 100644 app/src/main/res/values-w820dp/dimens.xml
create mode 100644 app/src/main/res/values/dimens.xml
create mode 100644 app/src/main/res/values/preference_values.xml
create mode 100644 app/src/main/res/values/strings.xml
create mode 100644 app/src/main/res/values/styles.xml
create mode 100644 app/src/main/res/xml/preferences.xml
create mode 100644 build.gradle
create mode 100644 gradle.properties
create mode 100644 gradle/wrapper/gradle-wrapper.jar
create mode 100644 gradle/wrapper/gradle-wrapper.properties
create mode 100755 gradlew
create mode 100644 gradlew.bat
create mode 100644 settings.gradle
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..afbdab3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..ea9cb82
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Taizé
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..e7bedf3
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..736c7b5
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..58ff01f
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.7
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..b7d3f25
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..9d32e50
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git "a/Taiz\303\251.iml" "b/Taiz\303\251.iml"
new file mode 100644
index 0000000..0bb6048
--- /dev/null
+++ "b/Taiz\303\251.iml"
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/app.iml b/app/app.iml
new file mode 100644
index 0000000..2192b64
--- /dev/null
+++ b/app/app.iml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..bd597c4
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.2"
+
+ defaultConfig {
+ applicationId "com.camilstaps.taize"
+ minSdkVersion 11
+ targetSdkVersion 21
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.0.0'
+ compile files('libs/volley.jar')
+}
diff --git a/app/libs/volley.jar b/app/libs/volley.jar
new file mode 100644
index 0000000..d9279b4
Binary files /dev/null and b/app/libs/volley.jar differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..966ccb1
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/camilstaps/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/app/src/androidTest/java/com/camilstaps/taize/ApplicationTest.java b/app/src/androidTest/java/com/camilstaps/taize/ApplicationTest.java
new file mode 100644
index 0000000..215c930
--- /dev/null
+++ b/app/src/androidTest/java/com/camilstaps/taize/ApplicationTest.java
@@ -0,0 +1,13 @@
+package com.camilstaps.taize;
+
+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
new file mode 100644
index 0000000..6ae08cb
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/camilstaps/common/Listener.java b/app/src/main/java/com/camilstaps/common/Listener.java
new file mode 100644
index 0000000..36319c6
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/common/Listener.java
@@ -0,0 +1,20 @@
+package com.camilstaps.common;
+
+/**
+ * Abstract class for something listening for some object
+ * @author Camil Staps
+ */
+public abstract class Listener {
+
+ /**
+ * To be called when the data is successfully retrieved
+ * @param data
+ */
+ public abstract void success(T data);
+
+ /**
+ * To be called when the data could not be retrieved
+ */
+ public abstract void failure();
+
+}
diff --git a/app/src/main/java/com/camilstaps/common/NullListener.java b/app/src/main/java/com/camilstaps/common/NullListener.java
new file mode 100644
index 0000000..c22e76d
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/common/NullListener.java
@@ -0,0 +1,14 @@
+package com.camilstaps.common;
+
+/**
+ * Listener that discards all data and errors.
+ * @author Camil Staps
+ */
+public class NullListener extends Listener {
+
+ @Override
+ public void success(T data) { }
+
+ @Override
+ public void failure() { }
+}
diff --git a/app/src/main/java/com/camilstaps/rss/RetrieveFeedTask.java b/app/src/main/java/com/camilstaps/rss/RetrieveFeedTask.java
new file mode 100644
index 0000000..543c9d6
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/rss/RetrieveFeedTask.java
@@ -0,0 +1,37 @@
+package com.camilstaps.rss;
+
+import android.os.AsyncTask;
+
+import com.camilstaps.common.Listener;
+
+/**
+ * Asynchronously retrieve an RSS feed
+ * @author Camil Staps
+ */
+public class RetrieveFeedTask extends AsyncTask {
+
+ Listener listener;
+
+ public void setRssDownloadListener(Listener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ protected RssParser doInBackground(String... params) {
+ try {
+ RssParser parser = new RssParser(params[0]);
+ return parser;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(RssParser results) {
+ if (results != null) {
+ listener.success(results);
+ } else {
+ listener.failure();
+ }
+ }
+}
diff --git a/app/src/main/java/com/camilstaps/rss/RssParser.java b/app/src/main/java/com/camilstaps/rss/RssParser.java
new file mode 100644
index 0000000..2c32abd
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/rss/RssParser.java
@@ -0,0 +1,293 @@
+package com.camilstaps.rss;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+import android.util.Log;
+
+/**
+ * RSS parser
+ *
+ * See: http://stackoverflow.com/a/24985128/1544337
+ *
+ * Usage:
+ * RssParser parser = new RssParser(feedUrl);
+ * Log.i("LOG", "Description: " + parser.getItem(3).description); //4th item's description
+ *
+ * @author Camil Staps
+ */
+public class RssParser extends DefaultHandler {
+
+ private StringBuilder content;
+ private boolean inChannel;
+ private boolean inImage;
+ private boolean inItem;
+
+ private ArrayList- items = new ArrayList
- ();
+ private Channel channel = new Channel();
+
+ private Item lastItem;
+
+
+ public RssParser(String url) {
+ try {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+ URL sourceUrl = new URL(url);
+ xr.setContentHandler(this);
+ xr.parse(new InputSource(sourceUrl.openStream()));
+ }
+ catch (ParserConfigurationException e) {
+ e.printStackTrace();
+ }
+ catch (SAXException e) {
+ e.printStackTrace();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public class Item {
+
+ public String title;
+ public String description;
+ public String link;
+ public String category;
+ public String pubDate;
+ public String guid;
+ }
+
+
+ public class Channel {
+
+ public String title;
+ public String description;
+ public String link;
+ public String lastBuildDate;
+ public String generator;
+ public String imageUrl;
+ public String imageTitle;
+ public String imageLink;
+ public String imageWidth;
+ public String imageHeight;
+ public String imageDescription;
+ public String language;
+ public String copyright;
+ public String pubDate;
+ public String category;
+ public String ttl;
+ }
+
+
+ @Override
+ public void startDocument() throws SAXException {
+ Log.i("LOG", "StartDocument");
+ }
+
+
+ @Override
+ public void endDocument() throws SAXException {
+ Log.i("LOG", "EndDocument");
+ }
+
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+ if (localName.equalsIgnoreCase("image")) {
+ inImage = true;
+ }
+
+ if (localName.equalsIgnoreCase("channel")) {
+ inChannel = true;
+ }
+
+ if (localName.equalsIgnoreCase("item")) {
+ lastItem = new Item();
+ items.add(lastItem);
+ inItem = true;
+ }
+
+ content = new StringBuilder();
+ }
+
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (localName.equalsIgnoreCase("image")) {
+ inImage = false;
+ }
+
+ if (localName.equalsIgnoreCase("channel")) {
+ inChannel = false;
+ }
+
+ if (localName.equalsIgnoreCase("item")) {
+ inItem = false;
+ }
+
+ if (localName.equalsIgnoreCase("title")) {
+ if (content == null) {
+ return;
+ }
+
+ if (inItem) {
+ lastItem.title = content.toString();
+ } else if (inImage) {
+ channel.imageTitle = content.toString();
+ } else if (inChannel) {
+ channel.title = content.toString();
+ }
+
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("description")) {
+ if (content == null) {
+ return;
+ }
+
+ if (inItem) {
+ lastItem.description = content.toString();
+ } else if (inImage) {
+ channel.imageDescription = content.toString();
+ } else if (inChannel) {
+ channel.description = content.toString();
+ }
+
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("link")) {
+ if (content == null) {
+ return;
+ }
+
+ if (inItem) {
+ lastItem.link = content.toString();
+ } else if (inImage) {
+ channel.imageLink = content.toString();
+ } else if (inChannel) {
+ channel.link = content.toString();
+ }
+
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("category")) {
+ if (content == null) {
+ return;
+ }
+
+ if (inItem) {
+ lastItem.category = content.toString();
+ } else if (inChannel) {
+ channel.category = content.toString();
+ }
+
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("pubDate")) {
+ if (content == null) {
+ return;
+ }
+
+ if (inItem) {
+ lastItem.pubDate = content.toString();
+ } else if (inChannel) {
+ channel.pubDate = content.toString();
+ }
+
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("guid")) {
+ if (content == null) {
+ return;
+ }
+
+ lastItem.guid = content.toString();
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("url")) {
+ if (content == null) {
+ return;
+ }
+
+ channel.imageUrl = content.toString();
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("width")) {
+ if (content == null) {
+ return;
+ }
+
+ channel.imageWidth = content.toString();
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("height")) {
+ if (content == null) {
+ return;
+ }
+
+ channel.imageHeight = content.toString();
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("language")) {
+ if (content == null) {
+ return;
+ }
+
+ channel.language = content.toString();
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("copyright")) {
+ if (content == null) {
+ return;
+ }
+
+ channel.copyright = content.toString();
+ content = null;
+ }
+
+ if (localName.equalsIgnoreCase("ttl")) {
+ if (content == null) {
+ return;
+ }
+
+ channel.ttl = content.toString();
+ content = null;
+ }
+ }
+
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (content == null) {
+ return;
+ }
+
+ content.append(ch, start, length);
+ }
+
+
+ public Item getItem(int index) {
+ return items.get(index);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/camilstaps/taize/Bible.java b/app/src/main/java/com/camilstaps/taize/Bible.java
new file mode 100644
index 0000000..451c7cb
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/taize/Bible.java
@@ -0,0 +1,86 @@
+package com.camilstaps.taize;
+
+import android.content.Context;
+import android.preference.PreferenceManager;
+
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response;
+import com.android.volley.toolbox.StringRequest;
+import com.android.volley.toolbox.Volley;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.net.URLEncoder;
+import java.util.Iterator;
+
+/**
+ * Use the Bible API of getbible.net
+ *
+ * @author Camil Staps
+ */
+public class Bible {
+
+ /**
+ * Base URL of the API
+ */
+ private static final String BASE_URL = "https://getbible.net/json?";
+
+ /**
+ * Request data from the API
+ * @param context context to handle from
+ * @param query_string Query string with parameters for the API
+ * @param listener listener; passed on to Volley, for processing the result
+ * @param errorListener errorListener for when some error occurs
+ */
+ private static void request(Context context, String query_string, Response.Listener listener, Response.ErrorListener errorListener) {
+ RequestQueue queue = Volley.newRequestQueue(context);
+ StringRequest request = new StringRequest(Request.Method.GET, BASE_URL + "v=" + getVersion(context) + "&" + query_string, listener, errorListener);
+ queue.add(request);
+ }
+
+ /**
+ * Get the Bible version (i.e., the translation) from the preferences of the user
+ * @param context context to handle from
+ * @return the version from the preferences
+ */
+ public static String getVersion(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context).getString(SettingsActivity.SettingsFragment.PREF_VERSION_BIBLE, context.getResources().getString(R.string.pref_version_bible_default));
+ }
+
+ /**
+ * Get a passage from the API
+ * @param context context to handle from
+ * @param passage indicator for the passage, using English full book names (i.e. "Mark 7:13-18")
+ * @param listener listener; passed on to Volley, for processing the result
+ * @param errorListener errorListener for when some error occurs
+ */
+ public static void getPassage(Context context, String passage, final Response.Listener listener, final Response.ErrorListener errorListener) {
+ request(context, "p=" + URLEncoder.encode(passage), new Response.Listener() {
+ @Override
+ public void onResponse(String s) {
+ StringBuilder passage = new StringBuilder();
+ try {
+ JSONObject response = new JSONObject(s.substring( 1, s.length() - 2));
+ JSONArray books = response.getJSONArray("book");
+ for (int b = 0; b < books.length(); b++) {
+ JSONObject chapter = books.getJSONObject(b).getJSONObject("chapter");
+ Iterator> verses = chapter.keys();
+ while (verses.hasNext()) {
+ String verse_number = (String) verses.next();
+ JSONObject verse = chapter.getJSONObject(verse_number);
+ passage.append(verse.getString("verse")).append(" ");
+ }
+ }
+ } catch (JSONException e) {
+ passage.append("No Bible text found.");
+ }
+
+ listener.onResponse(passage.toString());
+ }
+ }, errorListener);
+ }
+
+}
diff --git a/app/src/main/java/com/camilstaps/taize/BibleText.java b/app/src/main/java/com/camilstaps/taize/BibleText.java
new file mode 100644
index 0000000..db73a78
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/taize/BibleText.java
@@ -0,0 +1,73 @@
+package com.camilstaps.taize;
+
+import android.content.Context;
+
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+
+/**
+ * Class for holding some text in the Bible
+ *
+ * @author Camil Staps
+ */
+public class BibleText {
+
+ private String book;
+ private int start_chap, end_chap, start_verse, end_verse;
+
+ /**
+ * Constructor for a bible text consisting of a single verse
+ * @param book
+ * @param chapter
+ * @param verse
+ */
+ public BibleText(String book, int chapter, int verse) {
+ this.book = book;
+ start_chap = end_chap = chapter;
+ start_verse = end_verse = verse;
+ }
+
+ /**
+ * Constructor for a bible text consisting of a "verse range"
+ * @param book
+ * @param start_chap
+ * @param start_verse
+ * @param end_chap
+ * @param end_verse
+ */
+ public BibleText(String book, int start_chap, int start_verse, int end_chap, int end_verse) {
+ this.book = book;
+ this.start_chap = start_chap;
+ this.end_chap = end_chap;
+ this.start_verse = start_verse;
+ this.end_verse = end_verse;
+ }
+
+ /**
+ * Get the text (without verse numbers, line breaks, etc.) of this passage
+ * @param context
+ * @param listener
+ * @param errorListener
+ */
+ public void getText(Context context, Response.Listener listener, Response.ErrorListener errorListener) {
+ String passage = "";
+
+ if (start_chap == end_chap) {
+ if (start_verse == end_verse) {
+ passage = book + " " + start_chap + ":" + start_verse;
+ } else {
+ passage = book + " " + start_chap + ":" + start_verse + "-" + end_verse;
+ }
+ } else {
+ StringBuilder passageBuilder = new StringBuilder();
+ passageBuilder.append(book + " " + start_chap + ":" + start_verse);
+ for (int i = start_chap + 1; i <= end_chap; i++)
+ passageBuilder.append(";" + i);
+ passageBuilder.append("-" + end_verse);
+ passage = passageBuilder.toString();
+ }
+
+ Bible.getPassage(context, passage, listener, errorListener);
+ }
+
+}
diff --git a/app/src/main/java/com/camilstaps/taize/MainActivity.java b/app/src/main/java/com/camilstaps/taize/MainActivity.java
new file mode 100644
index 0000000..b3bf748
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/taize/MainActivity.java
@@ -0,0 +1,165 @@
+package com.camilstaps.taize;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.app.ActionBar;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.support.v4.widget.DrawerLayout;
+import android.widget.TextView;
+
+
+public class MainActivity extends ActionBarActivity
+ implements NavigationDrawerFragment.NavigationDrawerCallbacks {
+
+ /**
+ * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
+ */
+ private NavigationDrawerFragment mNavigationDrawerFragment;
+
+ /**
+ * Used to store the last screen title. For use in {@link #restoreActionBar()}.
+ */
+ private CharSequence mTitle;
+
+ private String reading;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ mNavigationDrawerFragment = (NavigationDrawerFragment)
+ getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
+ mTitle = getTitle();
+
+ // Set up the drawer.
+ mNavigationDrawerFragment.setUp(
+ R.id.navigation_drawer,
+ (DrawerLayout) findViewById(R.id.drawer_layout));
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle savedInstanceState) {
+ super.onSaveInstanceState(savedInstanceState);
+ savedInstanceState.putString("textview_dailyreading", ((TextView) findViewById(R.id.textDailyReading)).getText().toString());
+ }
+
+ @Override
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ ((TextView) findViewById(R.id.textDailyReading)).setText(savedInstanceState.getString("textview_dailyreading"));
+ }
+
+ @Override
+ public void onNavigationDrawerItemSelected(int position) {
+ // update the main content by replacing fragments
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ fragmentManager.beginTransaction()
+ .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
+ .commit();
+ }
+
+ public void onSectionAttached(int number) {
+ switch (number) {
+ case 1:
+ mTitle = getString(R.string.title_section1);
+ break;
+ case 2:
+ mTitle = getString(R.string.title_section2);
+ break;
+ }
+ }
+
+ public void restoreActionBar() {
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setTitle(mTitle);
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ if (!mNavigationDrawerFragment.isDrawerOpen()) {
+ // Only show items in the action bar relevant to this screen
+ // if the drawer is not showing. Otherwise, let the drawer
+ // decide what to show in the action bar.
+ getMenuInflater().inflate(R.menu.main, menu);
+ restoreActionBar();
+ return true;
+ }
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_settings) {
+ Intent intent = new Intent(this, SettingsActivity.class);
+ startActivity(intent);
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * A placeholder fragment containing a simple view.
+ */
+ public static class PlaceholderFragment extends Fragment {
+ /**
+ * The fragment argument representing the section number for this
+ * fragment.
+ */
+ private static final String ARG_SECTION_NUMBER = "section_number";
+
+ /**
+ * Returns a new instance of this fragment for the given section
+ * number.
+ */
+ public static PlaceholderFragment newInstance(int sectionNumber) {
+ PlaceholderFragment fragment = new PlaceholderFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARG_SECTION_NUMBER, sectionNumber);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ public PlaceholderFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_main, container, false);
+
+ return rootView;
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ ((MainActivity) activity).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/camilstaps/taize/NavigationDrawerFragment.java b/app/src/main/java/com/camilstaps/taize/NavigationDrawerFragment.java
new file mode 100644
index 0000000..3bb1556
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/taize/NavigationDrawerFragment.java
@@ -0,0 +1,317 @@
+package com.camilstaps.taize;
+
+import android.support.v7.app.ActionBarActivity;
+import android.app.Activity;
+import android.support.v7.app.ActionBar;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.text.Html;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.volley.VolleyError;
+import com.camilstaps.common.Listener;
+
+/**
+ * Fragment used for managing interactions for and presentation of a navigation drawer.
+ * See the
+ * design guidelines for a complete explanation of the behaviors implemented here.
+ */
+public class NavigationDrawerFragment extends Fragment {
+
+ /**
+ * Remember the position of the selected item.
+ */
+ private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
+
+ /**
+ * Per the design guidelines, you should show the drawer on launch until the user manually
+ * expands it. This shared preference tracks this.
+ */
+ private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
+
+ /**
+ * A pointer to the current callbacks instance (the Activity).
+ */
+ private NavigationDrawerCallbacks mCallbacks;
+
+ /**
+ * Helper component that ties the action bar to the navigation drawer.
+ */
+ private ActionBarDrawerToggle mDrawerToggle;
+
+ private DrawerLayout mDrawerLayout;
+ private ListView mDrawerListView;
+ private View mFragmentContainerView;
+
+ private int mCurrentSelectedPosition = 0;
+ private boolean mFromSavedInstanceState;
+ private boolean mUserLearnedDrawer;
+
+ public NavigationDrawerFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Read in the flag indicating whether or not the user has demonstrated awareness of the
+ // drawer. See PREF_USER_LEARNED_DRAWER for details.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
+
+ if (savedInstanceState != null) {
+ mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
+ mFromSavedInstanceState = true;
+ }
+
+ // Select either the default item (0) or the last selected item.
+ selectItem(mCurrentSelectedPosition);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ // Indicate that this fragment would like to influence the set of actions in the action bar.
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mDrawerListView = (ListView) inflater.inflate(
+ R.layout.fragment_navigation_drawer, container, false);
+ mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ selectItem(position);
+ }
+ });
+ mDrawerListView.setAdapter(new ArrayAdapter(
+ getActionBar().getThemedContext(),
+ android.R.layout.simple_list_item_1,
+ android.R.id.text1,
+ new String[]{
+ getString(R.string.title_section1),
+ getString(R.string.title_section2),
+ }));
+ mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
+ return mDrawerListView;
+ }
+
+ public boolean isDrawerOpen() {
+ return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
+ }
+
+ /**
+ * Users of this fragment must call this method to set up the navigation drawer interactions.
+ *
+ * @param fragmentId The android:id of this fragment in its activity's layout.
+ * @param drawerLayout The DrawerLayout containing this fragment's UI.
+ */
+ public void setUp(int fragmentId, DrawerLayout drawerLayout) {
+ mFragmentContainerView = getActivity().findViewById(fragmentId);
+ mDrawerLayout = drawerLayout;
+
+ // set a custom shadow that overlays the main content when the drawer opens
+ mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
+ // set up the drawer's list view with items and click listener
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeButtonEnabled(true);
+
+ // ActionBarDrawerToggle ties together the the proper interactions
+ // between the navigation drawer and the action bar app icon.
+ mDrawerToggle = new ActionBarDrawerToggle(
+ getActivity(), /* host Activity */
+ mDrawerLayout, /* DrawerLayout object */
+ R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
+ R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
+ R.string.navigation_drawer_close /* "close drawer" description for accessibility */
+ ) {
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ super.onDrawerClosed(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+
+ getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
+ }
+
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ super.onDrawerOpened(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+
+ if (!mUserLearnedDrawer) {
+ // The user manually opened the drawer; store this flag to prevent auto-showing
+ // the navigation drawer automatically in the future.
+ mUserLearnedDrawer = true;
+ SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(getActivity());
+ sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
+ }
+
+ getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
+ }
+ };
+
+ // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
+ // per the navigation drawer design guidelines.
+ if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
+ mDrawerLayout.openDrawer(mFragmentContainerView);
+ }
+
+ // Defer code dependent on restoration of previous instance state.
+ mDrawerLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ mDrawerToggle.syncState();
+ }
+ });
+
+ mDrawerLayout.setDrawerListener(mDrawerToggle);
+ }
+
+ private void selectItem(int position) {
+ mCurrentSelectedPosition = position;
+ if (mDrawerListView != null) {
+ mDrawerListView.setItemChecked(position, true);
+ }
+ if (mDrawerLayout != null) {
+ mDrawerLayout.closeDrawer(mFragmentContainerView);
+ }
+ if (mCallbacks != null) {
+ mCallbacks.onNavigationDrawerItemSelected(position);
+ }
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ mCallbacks = (NavigationDrawerCallbacks) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mCallbacks = null;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ // Forward the new configuration the drawer toggle component.
+ mDrawerToggle.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ // If the drawer is open, show the global app actions in the action bar. See also
+ // showGlobalContextActionBar, which controls the top-left area of the action bar.
+ if (mDrawerLayout != null && isDrawerOpen()) {
+ inflater.inflate(R.menu.global, menu);
+ showGlobalContextActionBar();
+ }
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (mDrawerToggle.onOptionsItemSelected(item)) {
+ return true;
+ }
+
+ if (item.getItemId() == R.id.action_update) {
+ //Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
+
+ final TextView reading = (TextView) getActivity().findViewById(R.id.textDailyReading);
+
+ Taize.getDailyReading(getActivity(), new Listener() {
+ @Override
+ public void success(String data) {
+ reading.setText(Html.fromHtml(data));
+ }
+
+ @Override
+ public void failure() {
+ reading.setText("Error fetching reading.");
+ }
+ });
+
+ reading.append("\n\n");
+
+ Taize.getDailyReadingBibleText(getActivity(), new Listener() {
+ @Override
+ public void success(String data) {
+ Log.i("LOG", "Success.");
+ Log.i("LOG", data);
+ reading.append(Html.fromHtml(data));
+ }
+
+ @Override
+ public void failure() {
+ Log.i("LOG", "Failure.");
+ }
+ });
+
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * Per the navigation drawer design guidelines, updates the action bar to show the global app
+ * 'context', rather than just what's in the current screen.
+ */
+ private void showGlobalContextActionBar() {
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+ actionBar.setTitle(R.string.app_name);
+ }
+
+ private ActionBar getActionBar() {
+ return ((ActionBarActivity) getActivity()).getSupportActionBar();
+ }
+
+ /**
+ * Callbacks interface that all activities using this fragment must implement.
+ */
+ public static interface NavigationDrawerCallbacks {
+ /**
+ * Called when an item in the navigation drawer is selected.
+ */
+ void onNavigationDrawerItemSelected(int position);
+ }
+}
diff --git a/app/src/main/java/com/camilstaps/taize/SettingsActivity.java b/app/src/main/java/com/camilstaps/taize/SettingsActivity.java
new file mode 100644
index 0000000..c8f3b3d
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/taize/SettingsActivity.java
@@ -0,0 +1,66 @@
+package com.camilstaps.taize;
+
+
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+
+import com.camilstaps.common.NullListener;
+
+public class SettingsActivity extends PreferenceActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
+ }
+
+ private static Preference.OnPreferenceChangeListener onPreferenceChangeListener = new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ String stringValue = newValue.toString();
+
+ if (pref instanceof ListPreference) {
+ ListPreference listPref = (ListPreference) pref;
+ int index = listPref.findIndexOfValue(stringValue);
+ pref.setSummary(index >= 0 ? listPref.getEntries()[index] : null); // .getEntry() seems to cause problems
+ } else {
+ pref.setSummary(stringValue);
+ }
+
+ // If the preference actually changed ...
+ if (!PreferenceManager.getDefaultSharedPreferences(pref.getContext()).getString(pref.getKey(), "").equals(stringValue)) {
+ if (pref.getKey().equals(SettingsFragment.PREF_LANGUAGE_READINGS)) { // If we select a new language, set the fetch time to 0 to refetch on next request
+ Taize.forceNewDailyReading(pref.getContext(), new NullListener());
+ } else if (pref.getKey().equals(SettingsFragment.PREF_VERSION_BIBLE)) { // If we select a new bible, set the fetch time to 0 to refetch on next request
+ Taize.forceNewDailyReadingBibleText(pref.getContext(), new NullListener());
+ }
+ }
+
+ return true;
+ }
+ };
+
+ private static void bindSummaryToValue(Preference pref) {
+ pref.setOnPreferenceChangeListener(onPreferenceChangeListener);
+ onPreferenceChangeListener.onPreferenceChange(pref, PreferenceManager.getDefaultSharedPreferences(pref.getContext()).getString(pref.getKey(), pref.getSummary().toString()));
+ }
+
+ public static class SettingsFragment extends PreferenceFragment {
+ public static final String PREF_LANGUAGE_READINGS = "pref_language_reading";
+ public static final String PREF_VERSION_BIBLE = "pref_version_bible";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+
+ bindSummaryToValue(findPreference(PREF_LANGUAGE_READINGS));
+ bindSummaryToValue(findPreference(PREF_VERSION_BIBLE));
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/camilstaps/taize/Taize.java b/app/src/main/java/com/camilstaps/taize/Taize.java
new file mode 100644
index 0000000..edfe9e7
--- /dev/null
+++ b/app/src/main/java/com/camilstaps/taize/Taize.java
@@ -0,0 +1,224 @@
+package com.camilstaps.taize;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.camilstaps.common.Listener;
+import com.camilstaps.common.NullListener;
+import com.camilstaps.rss.RetrieveFeedTask;
+import com.camilstaps.rss.RssParser;
+
+import java.util.concurrent.ExecutionException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Class specific to methods for Taize
+ * @author Camil Staps
+ */
+public class Taize {
+
+ private static final String url_reading_feed = "http://www.taize.fr/readingrss.php";
+ private static final String url_reading_feed_en = "http://www.taize.fr/readingrss.php?lang=en";
+
+ /**
+ * Force fetching a new bible text for the daily reading
+ * @see this#getDailyReadingBibleText
+ * @param context
+ * @param listener
+ */
+ public static void forceNewDailyReadingBibleText(final Context context, final Listener listener) {
+ SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
+ editor.putLong("dailyreadingbiblefetch", 0);
+ editor.putLong("englishdailyreadingfetch", 0);
+ editor.commit();
+ getDailyReadingBibleText(context, listener);
+ }
+
+ /**
+ * Fetch the bible text corresponding to the daily reading
+ * @see this#forceNewDailyReadingBibleText
+ * @param context
+ * @param listener
+ */
+ public static void getDailyReadingBibleText(final Context context, final Listener listener) {
+ if (System.currentTimeMillis() - PreferenceManager.getDefaultSharedPreferences(context).getLong("dailyreadingbiblefetch", 0) > 3600000) {
+
+ getEnglishDailyReading(context, new Listener() {
+ @Override
+ public void success(String reading) {
+
+ Log.i("LOG", "Matching: " + reading);
+
+ Pattern bible_ref = Pattern.compile("\\((\\d? ?[a-zA-Z]+) (\\d{1,2}):(\\d+)-?(\\d+?)\\)");
+ Matcher bible_ref_m = bible_ref.matcher(reading);
+
+ if (!bible_ref_m.find()) {
+ failure();
+ return;
+ }
+
+ BibleText text = new BibleText(bible_ref_m.group(1), Integer.parseInt(bible_ref_m.group(2)), Integer.parseInt(bible_ref_m.group(3)), Integer.parseInt(bible_ref_m.group(2)), Integer.parseInt(bible_ref_m.group(4)));
+
+ text.getText(context, new Response.Listener() {
+ @Override
+ public void onResponse(String s) {
+ Log.i("LOG", "Bible text: " + s);
+ PreferenceManager.getDefaultSharedPreferences(context).edit().putString("dailyreadingbible", s).apply();
+ listener.success(s);
+ }
+ }, new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError volleyError) {
+ Log.e("NET", "Failed to fetch bible text.");
+ }
+ });
+
+ }
+
+ @Override
+ public void failure() {
+ listener.failure();
+ }
+ });
+
+ PreferenceManager.getDefaultSharedPreferences(context).edit().putLong("dailyreadingbiblefetch", System.currentTimeMillis()).apply();
+
+ } else {
+
+ listener.success(PreferenceManager.getDefaultSharedPreferences(context).getString("dailyreadingbible", "No bible text found."));
+
+ }
+ }
+
+ /**
+ * Force fetching a new English daily reading
+ * @see this#getEnglishDailyReading
+ * @param context
+ * @param listener
+ */
+ private static void forceNewEnglishDailyReading(final Context context, final Listener listener) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit().putLong("englishdailyreadingfetch", 0).commit();
+ getEnglishDailyReading(context, listener);
+ }
+
+ /**
+ * Get the English daily reading (needed for the English Bible reference)
+ * @see this#forceNewEnglishDailyReading
+ * @param context
+ * @param listener
+ */
+ private static void getEnglishDailyReading(final Context context, final Listener listener) {
+ if (System.currentTimeMillis() - PreferenceManager.getDefaultSharedPreferences(context).getLong("englishdailyreadingfetch", 0) > 3600000) {
+
+ RetrieveFeedTask retrieve = new RetrieveFeedTask();
+ retrieve.setRssDownloadListener(new Listener() {
+ @Override
+ public void success(RssParser parser) {
+ try {
+ String reading = parser.getItem(0).description.trim();
+
+ SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
+ editor.putString("englishdailyreading", reading);
+ editor.putLong("englishdailyreadingfetch", System.currentTimeMillis());
+ editor.apply();
+
+ listener.success(reading);
+ } catch (Exception e) {
+ failure();
+ }
+ }
+
+ @Override
+ public void failure() {
+ Log.i("LOG", "Failed to update.");
+ listener.failure();
+ }
+ });
+
+ try {
+ retrieve.execute(url_reading_feed_en).get();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+
+ } else {
+
+ listener.success(PreferenceManager.getDefaultSharedPreferences(context).getString("englishdailyreading", "No daily reading found."));
+
+ }
+ }
+
+ /**
+ * Force fetching a new daily reading
+ * @see this#getDailyReading
+ * @param context
+ * @param listener
+ */
+ public static void forceNewDailyReading(final Context context, final Listener listener) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit().putLong("dailyreadingfetch", 0).commit();
+ getDailyReading(context, listener);
+ }
+
+ /**
+ * Fetch the daily reading
+ * @see this#forceNewDailyReading
+ * @param context
+ * @param listener
+ */
+ public static void getDailyReading(final Context context, final Listener listener) {
+ if (System.currentTimeMillis() - PreferenceManager.getDefaultSharedPreferences(context).getLong("dailyreadingfetch", 0) > 3600000) {
+
+ RetrieveFeedTask retrieve = new RetrieveFeedTask();
+ retrieve.setRssDownloadListener(new Listener() {
+ @Override
+ public void success(RssParser parser) {
+ try {
+ String reading = parser.getItem(0).description.trim();
+
+ if (!reading.equals(PreferenceManager.getDefaultSharedPreferences(context).getString("dailyreading", ""))) {
+ forceNewDailyReadingBibleText(context, new NullListener());
+ }
+
+ SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
+ editor.putString("dailyreading", reading);
+ editor.putLong("dailyreadingfetch", System.currentTimeMillis());
+ editor.apply();
+
+ listener.success(reading);
+ } catch (Exception e) {
+ failure();
+ }
+ }
+
+ @Override
+ public void failure() {
+ Log.i("LOG", "Failed to update.");
+ listener.failure();
+ }
+ });
+
+ try {
+ retrieve.execute(url_reading_feed + "?lang=" + PreferenceManager.getDefaultSharedPreferences(context).getString(SettingsActivity.SettingsFragment.PREF_LANGUAGE_READINGS, "en")).get();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+
+ } else {
+
+ listener.success(PreferenceManager.getDefaultSharedPreferences(context).getString("dailyreading", "No daily reading found."));
+
+ }
+ }
+
+ //http://www.taize.fr/pdcrss.xml
+
+}
diff --git a/app/src/main/res/drawable-hdpi/drawer_shadow.9.png b/app/src/main/res/drawable-hdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..236bff5
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_drawer.png b/app/src/main/res/drawable-hdpi/ic_drawer.png
new file mode 100644
index 0000000..c59f601
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_drawer.png differ
diff --git a/app/src/main/res/drawable-mdpi/drawer_shadow.9.png b/app/src/main/res/drawable-mdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..ffe3a28
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_drawer.png b/app/src/main/res/drawable-mdpi/ic_drawer.png
new file mode 100644
index 0000000..1ed2c56
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_drawer.png differ
diff --git a/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png b/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..fabe9d9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_drawer.png b/app/src/main/res/drawable-xhdpi/ic_drawer.png
new file mode 100644
index 0000000..a5fa74d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_drawer.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png b/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..b91e9d7
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_drawer.png b/app/src/main/res/drawable-xxhdpi/ic_drawer.png
new file mode 100644
index 0000000..9c4685d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_drawer.png differ
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..17ea429
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
new file mode 100644
index 0000000..ef0bd84
--- /dev/null
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_navigation_drawer.xml b/app/src/main/res/layout/fragment_navigation_drawer.xml
new file mode 100644
index 0000000..c05742d
--- /dev/null
+++ b/app/src/main/res/layout/fragment_navigation_drawer.xml
@@ -0,0 +1,5 @@
+
diff --git a/app/src/main/res/menu/global.xml b/app/src/main/res/menu/global.xml
new file mode 100644
index 0000000..326a6a7
--- /dev/null
+++ b/app/src/main/res/menu/global.xml
@@ -0,0 +1,5 @@
+
diff --git a/app/src/main/res/menu/main.xml b/app/src/main/res/menu/main.xml
new file mode 100644
index 0000000..1ee42b7
--- /dev/null
+++ b/app/src/main/res/menu/main.xml
@@ -0,0 +1,8 @@
+
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..63fc816
--- /dev/null
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..074e7a0
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+
+ 240dp
+
diff --git a/app/src/main/res/values/preference_values.xml b/app/src/main/res/values/preference_values.xml
new file mode 100644
index 0000000..754ec9e
--- /dev/null
+++ b/app/src/main/res/values/preference_values.xml
@@ -0,0 +1,152 @@
+
+
+ Settings
+
+
+ Language of the readings
+ en
+ English
+
+
- English
+ - čeština
+ - dansk
+ - Deutsch
+ - Español
+ - eesti
+ - suomi
+ - français
+ - hrvatski
+ - magyar
+ - Indonesia
+ - italiano
+ - 日本語
+ - 한국어
+ - lietuvių
+ - Nederlands
+ - norsk
+ - polski
+ - Português
+ - русский
+ - slovenčina
+ - slovenščina
+ - svenska
+ - 中文
+
+
+ - en
+ - cs
+ - da
+ - de
+ - es
+ - et
+ - fi
+ - fr
+ - hr
+ - hu
+ - id
+ - it
+ - ja
+ - ko
+ - lt
+ - nl
+ - no
+ - pl
+ - pt
+ - ru
+ - sk
+ - sl
+ - sv
+ - zh
+
+
+ Bible
+ kjv
+ King James Version
+
+ - Afrikaans: Ou Vertaling
+ - Albanian: Albanian
+ - Amharic: Haile Selassie Amharic Bible
+ - Arabic: Smith and Van Dyke
+ - Chinese: NCV Traditional
+ - Chinese: Union Simplified
+ - Chinese: NCV Simplified
+ - Chinese: Union Traditional
+ - Croatian: Croatian
+ - Danish: Danish
+ - Dutch: Dutch Staten Vertaling
+ - English: King James Version
+ - English: KJV Easy Read
+ - English: American Standard Version
+ - English: Amplified Version
+ - English: Basic English Bible
+ - English: Darby
+ - English: New American Standard
+ - English: Young\'s Literal Translation
+ - English: World English Bible
+ - English: Webster\'s Bible
+ - Esperanto: Esperanto
+ - Estonian: Estonian
+ - Finnish: Finnish Bible
+ - French: Martin
+ - German: Luther
+ - Greek: Greek Modern
+ - Greek: Textus Receptus
+ - Hebrew: Aleppo Codex
+ - Hungarian: Hungarian Karoli
+ - Italian: Giovanni Diodati Bible
+ - Korean: Korean
+ - Norwegian: Bibelselskap
+ - Portuguese: Almeida Atualizada
+ - Russian: Synodal Translation
+ - Spanish: Reina Valera
+ - Swahili: Swahili
+ - Swedish: Swedish
+ - Turkish: Turkish
+ - Vietnamese: Vietnamese
+ - Xhosa: Xhosa
+
+
+ - aov
+ - albanian
+ - hsab
+ - arabicsv
+ - cnt
+ - cus
+ - cns
+ - cut
+ - croatia
+ - danish
+ - statenvertaling
+ - kjv
+ - akjv
+ - asv
+ - amp
+ - basicenglish
+ - darby
+ - nasb
+ - ylt
+ - web
+ - wb
+ - esperanto
+ - estonian
+ - finnish1776
+ - martin
+ - luther1912
+ - moderngreek
+ - text
+ - aleppo
+ - karoli
+ - giovanni
+ - korean
+ - bibelselskap
+ - almeida
+ - synodal
+ - valera
+ - swahili
+ - swedish
+ - turkish
+ - vietnamese
+ - xhosa
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..32383f1
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,13 @@
+
+ Taizé
+
+ Daily Reading
+ Daily Meditation
+
+ Open navigation drawer
+ Close navigation drawer
+
+ Update
+
+ Settings
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..766ab99
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
new file mode 100644
index 0000000..1525761
--- /dev/null
+++ b/app/src/main/res/xml/preferences.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..d3ff69d
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.1.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..1d3591c
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0c71e76
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'
--
cgit v1.2.3