Skip to content

Commit

Permalink
Created android module. See release notes for more details.
Browse files Browse the repository at this point in the history
  • Loading branch information
little-fish committed Nov 23, 2018
1 parent f1c1c76 commit 0d3e710
Show file tree
Hide file tree
Showing 94 changed files with 4,571 additions and 132 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# IntelliJ IDEA
.idea
*.iml
out
captures

# Gradle
.gradle
build
out
local.properties
keystore.properties

# GitHub
.github
Expand Down
99 changes: 89 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
gcUnicorn
=========
gcUnicorn is an opensource tool for [geocaching.com](https://www.geocaching.com/) platform. It is a web application requiring nothing more but [Java JRE](https://www.oracle.com/technetwork/java/javase/downloads/index.html) installed on your machine.
gcUnicorn is an opensource tool for [geocaching.com](https://www.geocaching.com/) platform. You can use it either as a web application requiring nothing more but [Java JRE](https://www.oracle.com/technetwork/java/javase/downloads/index.html) installed on your machine or as an Android application.

The web application allows you to search for caches of selected types within given coordinates and radius. Its output contains not only exhaustive cache details, but links to spoiler images, detailed log entries including links to uploaded pictures as well. The output is served as GPX file with following schemas applied to it:
The tool allows you to search for caches of selected types within given coordinates and radius. Its output contains not only exhaustive cache details, but links to spoiler images, detailed log entries including links to uploaded pictures as well. The output is served as GPX file with following schemas applied to it:
* GPX v1.1
* Groundspeak v1.0.1
* Gsak v1.6
Expand All @@ -19,11 +19,18 @@ Be sure to read [Groundspeak's terms of use](https://www.geocaching.com/account/
Author of the application is not responsible for any damage caused by using it.

## Screenshots
### Web application
![Login page](https://goo.gl/ZKYxwF) ![Search page](https://goo.gl/6nx6C5) ![Queue page](https://goo.gl/Kf31cL)

See [gcUnicorn album](https://photos.app.goo.gl/vA4nyUmZSjE3HxUQ8) for full resolution screenshots.
See [gcUnicorn-webapp album](https://photos.app.goo.gl/vA4nyUmZSjE3HxUQ8) for full resolution screenshots.

### Android application
![Main activity](https://goo.gl/A1jLmC) ![Settings activity](https://goo.gl/oGEHA4) ![About activity](https://goo.gl/xvvdJB)

See [gcUnicorn-android album](https://photos.app.goo.gl/rkFMoohCSW3YfsYc8) for full resolution screenshots.

## How to run
### Web application
For Windows OS there is an executable file created. This approach always enables tray icon.

If you want to run the application from within command line, run the following command:
Expand Down Expand Up @@ -61,8 +68,7 @@ Coordinates field supports following standards:
#### Queue page
Here you can see all your search jobs. If a job is still running, spinning circle is shown. Once the job is done, download icon is shown.


## How to configure
#### How to configure
The application uses [Spring Boot](https://spring.io/projects/spring-boot) so basic configuration can be done by creating `application.properties` file next to the `gcUnicorn-webapp-<version>.jar` with properties specified inside it.

The list of all available properties (not all of them are applicable to the application) can be found on [Spring Boot reference page](https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html).
Expand All @@ -71,7 +77,7 @@ If the application will be exposed on the internet it is recommended to enable S

You can find examples of configuration files inside [webapp](https://github.com/little-fish/gcUnicorn/tree/master/webapp/resources/configuration-examples) module.

#### Application port
##### Application port
You have two options how to configure application port:
* Add `-Dserver.port=<port-number>` argument to the executing command:
```bash
Expand All @@ -82,7 +88,7 @@ java -jar -Dserver.port=<port-number> gcUnicorn-webapp-<version>.jar
server.port=<port-number>
```

#### Logging configuration
##### Logging configuration
The application uses Logback implementation. You can read about its configuration on its [homepage](https://logback.qos.ch/manual/configuration.html).

You can specify logging configuration with following options:
Expand All @@ -96,7 +102,7 @@ java -jar -Dlogging.config=file:<path-to-logging-config> gcUnicorn-webapp-<versi
logging.config=file:<path-to-logging-config>
```

#### Displaying tray icon
##### Displaying tray icon
If you want to shut down the application quickly, tray icon can be handy. To display the tray icon, you have two options here as well:
* Add `-Dtray` argument to the executing command:
```bash
Expand All @@ -107,11 +113,19 @@ java -jar -Dtray gcUnicorn-webapp-<version>.jar
tray
```

### Android application
To install the application, you have to enable _Unknown Sources_ first.

Android version of the tool supports all Android version since Jelly Bean (API 16) onwards.

As a bonus, the application interacts with popular Android map application called [Locus Map](http://www.locusmap.eu/). You can find shortcuts to gcUnicorn within main _Geocaching functions_ menu and within _Point view_'s share option. If you open the application from later option, latitude and longitude will be transferred from Locus directly into the gcUnicorn.

## Modules
The application contains two modules:

* __core__ - Core functionality.
* __webapp__ - Web application. UI has been created with simplicity and perfect readability in mind so it works on your desktop and mobile devices with no issues.
* __android__ - Android application. It allows you to the the very same operations like _webapp_ module.

## How to build
Clone the repository:
Expand All @@ -122,14 +136,79 @@ Navigate to the cloned folder:
```bash
cd gcUnicorn
```
Build the application:
Build the applications:
```bash
./gradlew build
```
Created artifacts are located within `<module>/build/libs` folder.
Created artifacts for _core_ and _webapp_ modules are located within `<module>/build/libs` folder. For _android_ module the artifact is located within `<module>/build/outputs/apk`.

### core
__Core__ module is now shared with an __android__ module and because its minimal API is 16, core module doesn't have tu use any Java 8 fancy features which are not available in Android SDK 18. To catch the exception earlier, the module should be compiled with Java 7 compiler.

To compile the module with proper JDK, you should create `local.properties` file directly within _core_ module and specify `java.home` property pointing to proper JDK. Once the property is set, all Kotlin compile tasks will use this JDK.

Possible content of _local.properties_:
```bash
java.home=/path/to/proper/jdk
```

### android
To enable location picking from Google Maps, Google Places API key has to be provided during build time.

To obtain your key, follow the instruction: [Get API Key](https://developers.google.com/places/web-service/get-api-key).

Once you obtain your key, you have to specify it within `/android/src/main/res/values/google_api_key.xml` file. Otherwise location picking won't work properly.

## Signing
### core & webapp
_Core_ and _webapp_ modules could use two different signing mechanisms. It is up to you which one you choose.
* __Gradle Signing plugin__ - You can read about it on its [homepage](https://docs.gradle.org/current/userguide/signing_plugin.html).
* __jarsigner__ - Read more [here](https://docs.oracle.com/javase/tutorial/deployment/jar/signing.html).

If you want to use any of the methods mentioned above, you have to create `keystore.properties` file within _module_ directory and specify additional (self-explanatory) properties:
* Gradle Signing plugin:
* `signing.keyId`
* `signing.password`
* `signing.secretKeyRingFile`

Once all the properties are provided, all output artifacts will be signed automatically.

* jarsigner:
* `jarsigning.keystore`
* `jarsigning.keystoreType`
* `jarsigning.keystorePassword`
* `jarsigning.keyPassword`
* `jarsigning.alias`

Once all the properties are provided, `signedJar` (`signedBoorJar` respectively) Gradle task will be created and hooked into the build process.

### android
_Android_ module uses standard signing described on Android [publishing](https://developer.android.com/studio/publish/app-signing) page.
To enable signing, simply create `keystore.properties` within the module directory and and specify additional (self-explanatory) properties:
* `keyAlias`
* `keyPassword`
* `storeFile`
* `storePassword`

Once the properties are provided, signing will be enabled automatically.

## Additional notes
* __Skip premium caches__ - If enabled the tool will simply skip premium caches __earlier__. If you are a _basic member_ and disable this option, the tool will try to load cache's details anyway and once it discovers that it can not load the cache (because you are a _basic member_), it skips it. (The tool has no idea whether you are a _basic member_ or a _premium_ one.)

## How to contribute
Any kind of contribution is welcome. If you have any ideas, bug-fxies or improvements, just create a pull request or contact me via email. Thank you.

## Acknowledgment
Special thanks to [c:geo](https://github.com/cgeo/cgeo) team for inspiring me to create the application.

## Release notes
##### 2018-11-23: core v2.0.0 & webapp v1.0.3 & android v1.0.0
* __core__
* Removed Java 8 features not available at Android SDK 16. (See [How to build](#core).)
* Updated exception handling.
* __webapp__
* Changed default cache count from `50` to `100`.
* __android__
* First release.
* Added signing options to all modules.
* Updated dependencies to newer versions.
169 changes: 169 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* gcUnicorn
* Copyright (C) 2018 Martin Misiarz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

buildscript {
ext {
versionAndroidTools = '3.2.1'
}

repositories {
jcenter()
google()
}

dependencies {
classpath "com.android.tools.build:gradle:$versionAndroidTools"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versionKotlin"
}
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

ext {
versionLocusApi = '0.3.0'
versionDagger = '2.19'
// https://dl.google.com/dl/android/maven2/index.html
versionAndroidSupport = '28.0.0'
// https://issuetracker.google.com/issues/37060038
// https://github.com/Gericop/Android-Support-Preference-V7-Fix
versionFixSupport = '28.0.0.0'
// Android constraint library.
versionAndroidConstraint = '1.1.3'
// Version Google play services Places.
// https://developers.google.com/android/guides/setup
versionPlayServicesPlaces = '16.0.0'
// Version Multidex.
versionMultidex = '1.0.3'
}

dependencies {
implementation project(':gcUnicorn-core')
implementation(
"org.jetbrains.kotlinx:kotlinx-coroutines-android:$versionKotlinCoroutines",
"com.android.support:support-core-ui:$versionAndroidSupport",
"com.android.support:design:$versionAndroidSupport",
"com.android.support:appcompat-v7:$versionAndroidSupport",
"com.android.support:preference-v7:$versionAndroidSupport",
"com.android.support.constraint:constraint-layout:$versionAndroidConstraint",
"com.google.dagger:dagger:$versionDagger",
"com.asamm:locus-api-android:$versionLocusApi",
"com.takisoft.fix:preference-v7:$versionFixSupport",
"com.google.android.gms:play-services-places:$versionPlayServicesPlaces",
"com.android.support:multidex:$versionMultidex"
)
runtimeOnly(
"org.slf4j:slf4j-android:$versionSlf4J"
)
kapt(
"com.google.dagger:dagger-compiler:$versionDagger"
)
}

configurations.all {
resolutionStrategy {
eachDependency { dependencyDetail ->
if (dependencyDetail.requested.group == 'org.jetbrains.kotlin' && dependencyDetail.requested.name.startsWith('kotlin-stdlib')) {
dependencyDetail.useVersion versionKotlin
}
}
}
}

android {
compileSdkVersion 28
buildToolsVersion '28.0.3'

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

defaultConfig {
applicationId 'cz.babi.gcunicorn.android'

minSdkVersion 16
targetSdkVersion 28

multiDexEnabled true

versionCode 1
versionName project.version

vectorDrawables.useSupportLibrary = true

resConfigs 'en', 'cs'
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

buildTypes {
release {
minifyEnabled true
shrinkResources true
crunchPngs false

proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
proguardFiles fileTree(dir: 'proguard-rules', include: '*.pro') as File[]
}

dev {
debuggable true

crunchPngs false
}
}

lintOptions {
// Lint doesn't take extension function into consideration..
abortOnError false

checkReleaseBuilds true
}
}

// Load keystore properties.
def keystoreProperties = new Properties()
def keystorePropertiesFile = file(keystoreFile)

if (keystorePropertiesFile.exists()) {
keystoreProperties.load(keystorePropertiesFile.newDataInputStream())

if (keystoreProperties['keyAlias'] && keystoreProperties['keyPassword'] && keystoreProperties['storeFile'] && keystoreProperties['storePassword']) {
android {
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}

buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
}
}
19 changes: 19 additions & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# gcUnicorn
# Copyright (C) 2018 Martin Misiarz
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

version=1.0.0
2 changes: 2 additions & 0 deletions android/proguard-rules/proguard-dagger2.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Dagger2
-dontwarn com.google.errorprone.annotations.**
11 changes: 11 additions & 0 deletions android/proguard-rules/proguard-kotlin.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Kotlin
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}

-keep interface kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoader
-keep class kotlin.reflect.jvm.internal.impl.serialization.deserialization.builtins.BuiltInsLoaderImpl

-keepclassmembers class kotlin.Metadata {
public <methods>;
}

0 comments on commit 0d3e710

Please sign in to comment.