├── settings.gradle ├── .idea ├── copyright │ └── profiles_settings.xml ├── vcs.xml ├── modules.xml ├── runConfigurations.xml ├── compiler.xml ├── gradle.xml └── misc.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── comicViewer ├── lint.xml ├── src │ └── main │ │ ├── res │ │ ├── drawable │ │ │ ├── icon.png │ │ │ ├── ic_menu_dice.png │ │ │ ├── ic_menu_star.png │ │ │ ├── icon_512x512.png │ │ │ ├── ic_menu_heart.png │ │ │ ├── ic_menu_archive.png │ │ │ └── ic_menu_refresh.png │ │ ├── values │ │ │ ├── archivemenu_strings.xml │ │ │ └── mainmenu_strings.xml │ │ ├── menu │ │ │ ├── archive.xml │ │ │ └── mainmenu.xml │ │ ├── layout │ │ │ ├── about.xml │ │ │ ├── search_dlg.xml │ │ │ ├── archive_item_layout.xml │ │ │ └── main.xml │ │ └── xml │ │ │ └── prefs.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── net │ │ └── bytten │ │ └── comicviewer │ │ ├── IComicInfo.java │ │ ├── IComicDefinition.java │ │ ├── IComicProvider.java │ │ ├── SettingsActivity.java │ │ ├── VersionHacks.java │ │ ├── ArchiveData.java │ │ ├── BookmarksHelper.java │ │ ├── HackedWebView.java │ │ ├── Utility.java │ │ ├── ArchiveActivity.java │ │ └── ComicViewerActivity.java └── build.gradle ├── xkcdViewer ├── src │ └── main │ │ ├── res │ │ ├── drawable │ │ │ ├── icon.png │ │ │ └── icon_512x512.png │ │ └── values │ │ │ └── strings.xml │ │ ├── java │ │ └── net │ │ │ └── bytten │ │ │ └── xkcdviewer │ │ │ ├── XkcdArchiveActivity.java │ │ │ ├── XkcdComicInfo.java │ │ │ ├── XkcdViewerActivity.java │ │ │ ├── XkcdComicDefinition.java │ │ │ └── XkcdComicProvider.java │ │ └── AndroidManifest.xml ├── build.gradle └── lint.xml ├── .gitignore ├── gradlew.bat └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':comicViewer' 2 | include ':xkcdViewer' 3 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /comicViewer/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/comicViewer/src/main/res/drawable/icon.png -------------------------------------------------------------------------------- /xkcdViewer/src/main/res/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/xkcdViewer/src/main/res/drawable/icon.png -------------------------------------------------------------------------------- /comicViewer/src/main/res/drawable/ic_menu_dice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/comicViewer/src/main/res/drawable/ic_menu_dice.png -------------------------------------------------------------------------------- /comicViewer/src/main/res/drawable/ic_menu_star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/comicViewer/src/main/res/drawable/ic_menu_star.png -------------------------------------------------------------------------------- /comicViewer/src/main/res/drawable/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/comicViewer/src/main/res/drawable/icon_512x512.png -------------------------------------------------------------------------------- /xkcdViewer/src/main/res/drawable/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/xkcdViewer/src/main/res/drawable/icon_512x512.png -------------------------------------------------------------------------------- /comicViewer/src/main/res/drawable/ic_menu_heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/comicViewer/src/main/res/drawable/ic_menu_heart.png -------------------------------------------------------------------------------- /comicViewer/src/main/res/drawable/ic_menu_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/comicViewer/src/main/res/drawable/ic_menu_archive.png -------------------------------------------------------------------------------- /comicViewer/src/main/res/drawable/ic_menu_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcoxon/XkcdViewer/HEAD/comicViewer/src/main/res/drawable/ic_menu_refresh.png -------------------------------------------------------------------------------- /comicViewer/src/main/res/values/archivemenu_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Refresh 4 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.apk 2 | *.ap_ 3 | *.dex 4 | *.class 5 | bin/ 6 | gen/ 7 | local.properties 8 | Thumbs.db 9 | .DS_Store 10 | *.sw* 11 | .classpath 12 | .project 13 | *.iml 14 | .idea/workspace.xml 15 | .idea/tasks.xml 16 | .gradle 17 | build/ 18 | obj/ 19 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/menu/archive.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /comicViewer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /comicViewer/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 12 5 | buildToolsVersion "25.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 3 9 | targetSdkVersion 11 10 | } 11 | 12 | buildTypes { 13 | release { 14 | minifyEnabled false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/layout/about.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /comicViewer/src/main/java/net/bytten/comicviewer/IComicInfo.java: -------------------------------------------------------------------------------- 1 | package net.bytten.comicviewer; 2 | 3 | import android.net.Uri; 4 | 5 | public interface IComicInfo { 6 | public Uri getImage(); 7 | public String getTitle(); 8 | public String getAlt(); 9 | public Uri getLink(); 10 | public String getId(); 11 | public boolean isBookmarked(); 12 | public void setBookmarked(boolean b); 13 | public String getNextId(); 14 | public String getPrevId(); 15 | public String getUrl(); 16 | } -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/layout/search_dlg.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /xkcdViewer/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 10 5 | buildToolsVersion "25.0.2" 6 | 7 | defaultConfig { 8 | applicationId "net.bytten.xkcdviewer" 9 | minSdkVersion 3 10 | targetSdkVersion 11 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 17 | } 18 | } 19 | compileOptions { 20 | targetCompatibility JavaVersion.VERSION_1_6 21 | } 22 | } 23 | 24 | dependencies { 25 | compile project(':comicViewer') 26 | } 27 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/layout/archive_item_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 19 | 20 | -------------------------------------------------------------------------------- /comicViewer/src/main/java/net/bytten/comicviewer/IComicDefinition.java: -------------------------------------------------------------------------------- 1 | package net.bytten.comicviewer; 2 | 3 | import android.net.Uri; 4 | 5 | public interface IComicDefinition { 6 | 7 | public String getComicTitle(); 8 | public String getAuthorName(); 9 | public Uri getArchiveUrl(); 10 | public String getPackageName(); 11 | public boolean hasAltText(); 12 | public boolean isComicUrl(Uri url); 13 | public boolean isArchiveUrl(Uri url); 14 | public boolean isHomeUrl(Uri url); 15 | public String getAuthorLinkText(); 16 | public Uri getAuthorLinkUrl(); 17 | public String getComicTitleAbbrev(); 18 | public boolean idsAreNumbers(); 19 | public IComicProvider getProvider(); 20 | public Uri getDonateUrl(); 21 | public Uri getDeveloperUrl(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /comicViewer/src/main/java/net/bytten/comicviewer/IComicProvider.java: -------------------------------------------------------------------------------- 1 | package net.bytten.comicviewer; 2 | 3 | import java.util.List; 4 | 5 | import net.bytten.comicviewer.ArchiveData.ArchiveItem; 6 | import android.net.Uri; 7 | 8 | public interface IComicProvider { 9 | 10 | public Uri comicDataUrlForUrl(Uri url); 11 | public Uri createComicUrl(String comicId); 12 | public String getFirstId(); 13 | public Uri getFinalComicUrl(); 14 | public Uri fetchRandomComicUrl() throws Exception; 15 | public IComicInfo fetchComicInfo(Uri url) throws Exception; 16 | public IComicInfo createEmptyComicInfo(); 17 | public List fetchArchive() throws Exception; 18 | 19 | // Return null if the comic has no explanation 20 | public Uri getExplainUrl(IComicInfo comic); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /xkcdViewer/src/main/java/net/bytten/xkcdviewer/XkcdArchiveActivity.java: -------------------------------------------------------------------------------- 1 | package net.bytten.xkcdviewer; 2 | 3 | import net.bytten.comicviewer.ArchiveActivity; 4 | import net.bytten.comicviewer.IComicDefinition; 5 | 6 | public class XkcdArchiveActivity extends ArchiveActivity { 7 | 8 | @Override 9 | protected IComicDefinition makeComicDef() { 10 | return new XkcdComicDefinition(); 11 | } 12 | 13 | @Override 14 | protected String getStringArchive() { 15 | return getResources().getString(R.string.app_archive_label); 16 | } 17 | 18 | @Override 19 | protected String getStringBookmarks() { 20 | return getResources().getString(R.string.app_bookmarks_label); 21 | } 22 | 23 | @Override 24 | protected String getStringSearchByTitle() { 25 | return getResources().getString(R.string.app_search_title_label); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /comicViewer/src/main/java/net/bytten/comicviewer/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package net.bytten.comicviewer; 2 | 3 | import android.content.SharedPreferences; 4 | import android.os.Bundle; 5 | import android.preference.CheckBoxPreference; 6 | import android.preference.PreferenceActivity; 7 | import android.preference.PreferenceManager; 8 | 9 | public class SettingsActivity extends PreferenceActivity { 10 | 11 | @Override 12 | public void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | addPreferencesFromResource(R.xml.prefs); 15 | 16 | final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 17 | final boolean value = prefs.getBoolean("useZoomControls", 18 | !VersionHacks.isIncredible() && VersionHacks.getSdkInt() >= 5); 19 | ((CheckBoxPreference)findPreference("useZoomControls")) 20 | .setChecked(value); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/xml/prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 17 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /comicViewer/src/main/java/net/bytten/comicviewer/VersionHacks.java: -------------------------------------------------------------------------------- 1 | package net.bytten.comicviewer; 2 | 3 | import android.os.Build; 4 | 5 | public class VersionHacks { 6 | // 7 | // Because Android 1.5 does not have android.os.Build.SDK_INT, we have to simulate 8 | // for 1.5 devices, but string parsing is annoying, so we will use SDK_INT if it is 9 | // available. 10 | // CREDIT: These two methods are from 11 | // http://sagistech.blogspot.com/2011/01/buildversionsdkint-on-android-15.html 12 | // 13 | public static int getSdkInt() { 14 | if (Build.VERSION.RELEASE.startsWith("1.5")) 15 | return 3; 16 | 17 | return HelperInternal.getSdkIntInternal(); 18 | } 19 | 20 | private static class HelperInternal { 21 | private static int getSdkIntInternal() { 22 | return Build.VERSION.SDK_INT; 23 | } 24 | } 25 | // 26 | // !CREDIT: 27 | // 28 | 29 | public static boolean isIncredible() { 30 | return Build.MODEL.toLowerCase().contains("incredible") || 31 | Build.MODEL.toLowerCase().contains("adr6300"); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/values/mainmenu_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Go To... 3 | Final 4 | Next 5 | First 6 | Previous 7 | Archive 8 | Random 9 | Website 10 | Alt Text 11 | Open Link... 12 | Archive 13 | Share... 14 | Link... 15 | Image... 16 | Favorites 17 | Search by Title... 18 | Refresh 19 | Preferences 20 | Support Comic Author 21 | Donate 22 | About 23 | Debug 24 | Explain 25 | 26 | -------------------------------------------------------------------------------- /xkcdViewer/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | xkcdViewer 4 | xkcd Archive - xkcdViewer 5 | Favorites - xkcdViewer 6 | Search by Title - xkcdViewer 7 | Preferences - xkcdViewer 8 | 9 | xkcdViewer v%s. Application for viewing xkcd comics with hover text.\n\n 10 | xkcdViewer Copyright (C) 2009-2017, Tom Coxon, Tyler Breisacher, David 11 | McCullough, Kristian Lundkvist.\n\n 12 | xkcd is Copyright (C) 2006 - 2017, Randall Munroe (http://xkcd.com)\n\n 13 | Contains some menu icons from www.androidicons.com, licensed under a 14 | Creative Commons Attribution - Share Alike license.\n\n 15 | Application icon kindly donated by Johan Larsson.\n\n 16 | You can fork this project on github:\n 17 | \thttp://github.com/tcoxon/XkcdViewer/\n\n 18 | This program is distributed in the hope that it will be useful, but WITHOUT 19 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 21 | more details.\n\n 22 | Developed by Bytten Studio\n 23 | \thttp://bytten-studio.com\n\n 24 | If you like this app, please consider donating, or buying one of my games. Thanks. 25 | 26 | 27 | -------------------------------------------------------------------------------- /xkcdViewer/src/main/java/net/bytten/xkcdviewer/XkcdComicInfo.java: -------------------------------------------------------------------------------- 1 | package net.bytten.xkcdviewer; 2 | 3 | import net.bytten.comicviewer.IComicInfo; 4 | import android.net.Uri; 5 | 6 | public class XkcdComicInfo implements IComicInfo { 7 | 8 | public Uri img, link; 9 | public int num; 10 | public String title = "", alt = ""; 11 | public boolean bookmarked; 12 | 13 | @Override 14 | public String getAlt() { 15 | return alt; 16 | } 17 | 18 | @Override 19 | public String getId() { 20 | return Integer.toString(num); 21 | } 22 | 23 | @Override 24 | public Uri getImage() { 25 | return img; 26 | } 27 | 28 | @Override 29 | public String getNextId() { 30 | int n = num + 1; 31 | // #404 is xkcd's error page! 32 | if (n == 404) ++n; 33 | return Integer.toString(n); 34 | } 35 | 36 | @Override 37 | public String getPrevId() { 38 | int n = num - 1; 39 | // #404 is xkcd's error page! 40 | if (n == 404) --n; 41 | return Integer.toString(n); 42 | } 43 | 44 | @Override 45 | public String getTitle() { 46 | return title; 47 | } 48 | 49 | @Override 50 | public String getUrl() { 51 | return "http://xkcd.com/"+getId()+"/"; 52 | } 53 | 54 | @Override 55 | public boolean isBookmarked() { 56 | return bookmarked; 57 | } 58 | 59 | @Override 60 | public void setBookmarked(boolean b) { 61 | bookmarked = b; 62 | } 63 | 64 | @Override 65 | public Uri getLink() { 66 | return link; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /xkcdViewer/src/main/java/net/bytten/xkcdviewer/XkcdViewerActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * xkcdViewer - Android app to view xkcd comics with hover text 3 | * Copyright (C) 2009-2014 Tom Coxon, Tyler Breisacher, David McCullough, 4 | * Kristian Lundkvist, Ivan Vasiljević. 5 | * 6 | * xkcd is Copyright (C) Randall Munroe. 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License along 19 | * with this program; if not, write to the Free Software Foundation, Inc., 20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | */ 22 | package net.bytten.xkcdviewer; 23 | 24 | import net.bytten.comicviewer.ArchiveActivity; 25 | import net.bytten.comicviewer.ComicViewerActivity; 26 | import net.bytten.comicviewer.IComicDefinition; 27 | 28 | public class XkcdViewerActivity extends ComicViewerActivity { 29 | 30 | @Override 31 | protected IComicDefinition makeComicDef() { 32 | return new XkcdComicDefinition(); 33 | } 34 | 35 | @Override 36 | protected Class getArchiveActivityClass() { 37 | return XkcdArchiveActivity.class; 38 | } 39 | 40 | @Override 41 | protected String getStringAboutText() { 42 | return getResources().getString(R.string.aboutText); 43 | } 44 | 45 | @Override 46 | protected String getStringAppName() { 47 | return getResources().getString(R.string.app_name); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /xkcdViewer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /xkcdViewer/src/main/java/net/bytten/xkcdviewer/XkcdComicDefinition.java: -------------------------------------------------------------------------------- 1 | package net.bytten.xkcdviewer; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | import net.bytten.comicviewer.IComicDefinition; 6 | import net.bytten.comicviewer.IComicProvider; 7 | 8 | import android.net.Uri; 9 | 10 | public class XkcdComicDefinition implements IComicDefinition { 11 | 12 | static public final Pattern 13 | xkcdHomePattern = Pattern.compile( 14 | "http(s?)://(www\\.)?xkcd\\.com(/)?"), 15 | comicUrlPattern = Pattern.compile( 16 | "http(s?)://(www\\.)?xkcd\\.com/([0-9]+)(/)?"), 17 | archiveUrlPattern = Pattern.compile( 18 | "http(s?)://(www\\.)?xkcd\\.com/archive(/)?"); 19 | 20 | private XkcdComicProvider provider; 21 | 22 | public XkcdComicDefinition() { 23 | provider = new XkcdComicProvider(this); 24 | } 25 | 26 | @Override 27 | public Uri getArchiveUrl() { 28 | return Uri.parse("http://xkcd.com/archive/"); 29 | } 30 | 31 | @Override 32 | public String getAuthorLinkText() { 33 | return "xkcd Store"; 34 | } 35 | 36 | @Override 37 | public Uri getAuthorLinkUrl() { 38 | return Uri.parse("http://store.xkcd.com/"); 39 | } 40 | 41 | @Override 42 | public String getAuthorName() { 43 | return "Randall Munroe"; 44 | } 45 | 46 | @Override 47 | public String getComicTitle() { 48 | return "xkcd"; 49 | } 50 | 51 | @Override 52 | public String getComicTitleAbbrev() { 53 | return "xkcd"; 54 | } 55 | 56 | @Override 57 | public String getPackageName() { 58 | return "net.bytten.xkcdviewer"; 59 | } 60 | 61 | @Override 62 | public boolean hasAltText() { 63 | return true; 64 | } 65 | 66 | @Override 67 | public boolean idsAreNumbers() { 68 | return true; 69 | } 70 | 71 | @Override 72 | public boolean isArchiveUrl(Uri url) { 73 | return archiveUrlPattern.matcher(url.toString()).matches(); 74 | } 75 | 76 | @Override 77 | public boolean isComicUrl(Uri url) { 78 | return comicUrlPattern.matcher(url.toString()).matches(); 79 | } 80 | 81 | @Override 82 | public boolean isHomeUrl(Uri url) { 83 | return xkcdHomePattern.matcher(url.toString()).matches(); 84 | } 85 | 86 | @Override 87 | public IComicProvider getProvider() { 88 | return provider; 89 | } 90 | 91 | @Override 92 | public Uri getDonateUrl() { 93 | return Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=C9JRVA3NTULSL&lc=US&item_name=XkcdViewer%20donation&item_number=xkcdviewer¤cy_code=USD"); 94 | } 95 | 96 | @Override 97 | public Uri getDeveloperUrl() { 98 | return Uri.parse("http://bytten-studio.com"); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /comicViewer/src/main/java/net/bytten/comicviewer/ArchiveData.java: -------------------------------------------------------------------------------- 1 | package net.bytten.comicviewer; 2 | 3 | import java.lang.ref.SoftReference; 4 | import java.util.Date; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import android.content.Context; 10 | 11 | public class ArchiveData { 12 | 13 | private static final Map> archives 14 | = new HashMap>(); 15 | 16 | /* The maximum age the cache is allowed to reach in milliseconds */ 17 | private static final long CACHE_AGE_LIMIT = 60*60*1000; // = 1 hour 18 | 19 | public static class ArchiveItem { 20 | public boolean bookmarked = false; 21 | public String title, comicId; 22 | 23 | @Override 24 | public String toString() { 25 | return title; 26 | } 27 | } 28 | 29 | /* Putting the cache in a SoftReference means the system can still 30 | * garbage collect it if low on memory. */ 31 | private SoftReference> cache = null; 32 | private Date cacheModDate = null; 33 | private IComicDefinition comicDef; 34 | 35 | private ArchiveData(IComicDefinition comicDef) { 36 | this.comicDef = comicDef; 37 | } 38 | 39 | public static ArchiveData getArchive(IComicDefinition def) { 40 | SoftReference archRef = archives.get(def.getClass().getName()); 41 | if (archRef == null || archRef.get() == null) { 42 | archRef = new SoftReference(new ArchiveData(def)); 43 | archives.put(def.getClass().getName(), archRef); 44 | } 45 | archRef.get().comicDef = def; 46 | return archRef.get(); 47 | } 48 | 49 | public boolean isCacheValid() { 50 | return cache != null && cache.get() != null && cacheModDate != null && 51 | cacheModDate.before(new Date(cacheModDate.getTime() + 52 | CACHE_AGE_LIMIT)); 53 | } 54 | 55 | /* Do NOT call in a UI thread. May block until data has been fetched. 56 | * Do NOT add or remove elements from the returned list (but bookmarking 57 | * may be altered). */ 58 | public List getData(Context cxt) throws Exception { 59 | List cacheVal = cache == null ? null : cache.get(); 60 | if (!isCacheValid()) 61 | return fetchData(cxt); 62 | return cacheVal; 63 | } 64 | 65 | public void refresh(Context cxt) throws Exception { 66 | fetchData(cxt); 67 | } 68 | 69 | private List fetchData(Context cxt) throws Exception { 70 | List archiveItems = comicDef.getProvider().fetchArchive(); 71 | 72 | for (ArchiveItem item: archiveItems) { 73 | if (BookmarksHelper.isBookmarked(cxt, item)) { 74 | item.bookmarked = true; 75 | } 76 | } 77 | 78 | if (cache != null) 79 | cache.clear(); 80 | cache = new SoftReference>(archiveItems); 81 | cacheModDate = new Date(); 82 | return archiveItems; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/menu/mainmenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /comicViewer/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 20 | 26 | 32 |