mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-11-29 15:51:17 +00:00
Merge branch 'develop'
This commit is contained in:
commit
d9a48de886
447 changed files with 912 additions and 736 deletions
23
.gitignore
vendored
23
.gitignore
vendored
|
@ -12,7 +12,6 @@
|
||||||
bin/
|
bin/
|
||||||
build/
|
build/
|
||||||
gen/
|
gen/
|
||||||
src/main/jniLibs/
|
|
||||||
obj/
|
obj/
|
||||||
.gradle/
|
.gradle/
|
||||||
|
|
||||||
|
@ -20,14 +19,6 @@ obj/
|
||||||
local.properties
|
local.properties
|
||||||
project.properties
|
project.properties
|
||||||
|
|
||||||
# Eclipse project files
|
|
||||||
.settings/
|
|
||||||
.classpath
|
|
||||||
.project
|
|
||||||
|
|
||||||
# Proguard folder generated by Eclipse
|
|
||||||
proguard/
|
|
||||||
|
|
||||||
# Intellij project files
|
# Intellij project files
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
|
@ -37,17 +28,3 @@ proguard/
|
||||||
# Gradle wrapper
|
# Gradle wrapper
|
||||||
gradle/wrapper/gradle/
|
gradle/wrapper/gradle/
|
||||||
gradle/wrapper/gradlew*
|
gradle/wrapper/gradlew*
|
||||||
|
|
||||||
# Go native dependencies
|
|
||||||
ext/golang/dist
|
|
||||||
|
|
||||||
# Syncthing native dependencies
|
|
||||||
ext/syncthing/pkg/
|
|
||||||
ext/syncthing/src/code.google.com/
|
|
||||||
ext/syncthing/src/github.com/kr/
|
|
||||||
ext/syncthing/src/github.com/mattn/
|
|
||||||
ext/syncthing/src/github.com/tools/
|
|
||||||
ext/syncthing/src/golang.org/
|
|
||||||
|
|
||||||
# gradle-play-publisher
|
|
||||||
keys.json
|
|
||||||
|
|
13
.gitmodules
vendored
13
.gitmodules
vendored
|
@ -1,12 +1,3 @@
|
||||||
[submodule "ext/syncthing/src/github.com/syncthing/syncthing"]
|
[submodule "syncthing"]
|
||||||
path = ext/syncthing/src/github.com/syncthing/syncthing
|
path = syncthing/src/github.com/syncthing/syncthing
|
||||||
url = https://github.com/syncthing/syncthing.git
|
url = https://github.com/syncthing/syncthing.git
|
||||||
ignore = dirty
|
|
||||||
[submodule "ext/golang/go"]
|
|
||||||
path = ext/golang/go
|
|
||||||
url = https://github.com/golang/go.git
|
|
||||||
ignore = dirty
|
|
||||||
[submodule "ext/golang/go1.4"]
|
|
||||||
path = ext/golang/go1.4
|
|
||||||
url = https://github.com/golang/go.git
|
|
||||||
ignore = dirty
|
|
||||||
|
|
13
.travis.yml
13
.travis.yml
|
@ -1,6 +1,7 @@
|
||||||
sudo: required
|
sudo: required
|
||||||
language: android
|
language: android
|
||||||
jdk: oraclejdk8
|
jdk: oraclejdk8
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
# Install Android SDK
|
# Install Android SDK
|
||||||
android:
|
android:
|
||||||
|
@ -13,10 +14,18 @@ android:
|
||||||
- android-26
|
- android-26
|
||||||
- extra-android-m2repository
|
- extra-android-m2repository
|
||||||
|
|
||||||
|
# Install Android NDK (apparently there is no easier way to do this)
|
||||||
|
# https://github.com/travis-ci/travis-ci/issues/5395
|
||||||
|
before_script:
|
||||||
|
- curl -L https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip -O
|
||||||
|
- unzip -q android-ndk-r15c-linux-x86_64.zip
|
||||||
|
- export ANDROID_NDK_HOME=`pwd`/android-ndk-r15c
|
||||||
|
|
||||||
# Install Golang
|
# Install Golang
|
||||||
before_install:
|
before_install:
|
||||||
|
- sudo add-apt-repository ppa:gophers/archive -y
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install golang -y
|
- sudo apt-get install golang-1.9-go -y
|
||||||
|
|
||||||
# Cache gradle dependencies
|
# Cache gradle dependencies
|
||||||
# https://docs.travis-ci.com/user/languages/android/#Caching
|
# https://docs.travis-ci.com/user/languages/android/#Caching
|
||||||
|
@ -29,5 +38,5 @@ cache:
|
||||||
- $HOME/.gradle/wrapper/
|
- $HOME/.gradle/wrapper/
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- ./gradlew clean lint
|
- ./gradlew lintVitalRelease
|
||||||
- ./gradlew buildNative assembleDebug
|
- ./gradlew buildNative assembleDebug
|
||||||
|
|
16
.tx/config
16
.tx/config
|
@ -2,29 +2,29 @@
|
||||||
host = https://www.transifex.com
|
host = https://www.transifex.com
|
||||||
|
|
||||||
[syncthing-android.stringsxml]
|
[syncthing-android.stringsxml]
|
||||||
file_filter = src/main/res/values-<lang>/strings.xml
|
file_filter = app/src/main/res/values-<lang>/strings.xml
|
||||||
source_file = src/main/res/values/strings.xml
|
source_file = app/src/main/res/values/strings.xml
|
||||||
source_lang = en
|
source_lang = en
|
||||||
type = ANDROID
|
type = ANDROID
|
||||||
lang_map = af_ZA: af-rZA, am_ET: am-rET, ar_AE: ar-rAE, ar_BH: ar-rBH, ar_DZ: ar-rDZ, ar_EG: ar-rEG, ar_IQ: ar-rIQ, ar_JO: ar-rJO, ar_KW: ar-rKW, ar_LB: ar-rLB, ar_LY: ar-rLY, ar_MA: ar-rMA, ar_OM: ar-rOM, ar_QA: ar-rQA, ar_SA: ar-rSA, ar_SY: ar-rSY, ar_TN: ar-rTN, ar_YE: ar-rYE, arn_CL: arn-rCL, as_IN: as-rIN, az_AZ: az-rAZ, ba_RU: ba-rRU, be_BY: be-rBY, bg_BG: bg-rBG, bn_BD: bn-rBD, bn_IN: bn-rIN, bo_CN: bo-rCN, br_FR: br-rFR, bs_BA: bs-rBA, ca_ES: ca-rES, co_FR: co-rFR, cs_CZ: cs-rCZ, cy_GB: cy-rGB, da_DK: da-rDK, de_AT: de-rAT, de_CH: de-rCH, de_DE: de-rDE, de_LI: de-rLI, de_LU: de-rLU, dsb_DE: dsb-rDE, dv_MV: dv-rMV, el_GR: el-rGR, en_AU: en-rAU, en_BZ: en-rBZ, en_CA: en-rCA, en_GB: en-rGB, en_IE: en-rIE, en_IN: en-rIN, en_JM: en-rJM, en_MY: en-rMY, en_NZ: en-rNZ, en_PH: en-rPH, en_SG: en-rSG, en_TT: en-rTT, en_US: en-rUS, en_ZA: en-rZA, en_ZW: en-rZW, es_AR: es-rAR, es_BO: es-rBO, es_CL: es-rCL, es_CO: es-rCO, es_CR: es-rCR, es_DO: es-rDO, es_EC: es-rEC, es_ES: es-rES, es_GT: es-rGT, es_HN: es-rHN, es_MX: es-rMX, es_NI: es-rNI, es_PA: es-rPA, es_PE: es-rPE, es_PR: es-rPR, es_PY: es-rPY, es_SV: es-rSV, es_US: es-rUS, es_UY: es-rUY, es_VE: es-rVE, et_EE: et-rEE, eu_ES: eu-rES, fa_IR: fa-rIR, fi_FI: fi-rFI, fil_PH: fil-rPH, fo_FO: fo-rFO, fr_BE: fr-rBE, fr_CA: fr-rCA, fr_CH: fr-rCH, fr_FR: fr-rFR, fr_LU: fr-rLU, fr_MC: fr-rMC, fy_NL: fy-rNL, ga_IE: ga-rIE, gd_GB: gd-rGB, gl_ES: gl-rES, gsw_FR: gsw-rFR, gu_IN: gu-rIN, ha_NG: ha-rNG, hi_IN: hi-rIN, hr_BA: hr-rBA, hr_HR: hr-rHR, hsb_DE: hsb-rDE, hu_HU: hu-rHU, hy_AM: hy-rAM, id_ID: id-rID, ig_NG: ig-rNG, ii_CN: ii-rCN, is_IS: is-rIS, it_CH: it-rCH, it_IT: it-rIT, iu_CA: iu-rCA, ja_JP: ja-rJP, ka_GE: ka-rGE, kk_KZ: kk-rKZ, kl_GL: kl-rGL, km_KH: km-rKH, kn_IN: kn-rIN, ko_KR: ko-rKR, kok_IN: kok-rIN, ky_KG: ky-rKG, lb_LU: lb-rLU, lo_LA: lo-rLA, lt_LT: lt-rLT, lv_LV: lv-rLV, mi_NZ: mi-rNZ, mk_MK: mk-rMK, ml_IN: ml-rIN, mn_CN: mn-rCN, mn_MN: mn-rMN, moh_CA: moh-rCA, mr_IN: mr-rIN, ms_BN: ms-rBN, ms_MY: ms-rMY, mt_MT: mt-rMT, nb_NO: nb-rNO, ne_NP: ne-rNP, nl_BE: nl-rBE, nl_NL: nl-rNL, nn_NO: nn-rNO, nso_ZA: nso-rZA, oc_FR: oc-rFR, or_IN: or-rIN, pa_IN: pa-rIN, pl_PL: pl-rPL, prs_AF: prs-rAF, ps_AF: ps-rAF, pt_BR: pt-rBR, pt_PT: pt-rPT, qut_GT: qut-rGT, quz_BO: quz-rBO, quz_EC: quz-rEC, quz_PE: quz-rPE, rm_CH: rm-rCH, ro_RO: ro-rRO, ru_RU: ru-rRU, rw_RW: rw-rRW, sa_IN: sa-rIN, sah_RU: sah-rRU, se_FI: se-rFI, se_NO: se-rNO, se_SE: se-rSE, si_LK: si-rLK, sk_SK: sk-rSK, sl_SI: sl-rSI, sma_NO: sma-rNO, sma_SE: sma-rSE, smj_NO: smj-rNO, smj_SE: smj-rSE, smn_FI: smn-rFI, sms_FI: sms-rFI, sq_AL: sq-rAL, sr_BA: sr-rBA, sr_CS: sr-rCS, sr_ME: sr-rME, sr_RS: sr-rRS, sv_FI: sv-rFI, sv_SE: sv-rSE, sw_KE: sw-rKE, syr_SY: syr-rSY, ta_IN: ta-rIN, te_IN: te-rIN, tg_TJ: tg-rTJ, th_TH: th-rTH, tk_TM: tk-rTM, tn_ZA: tn-rZA, tr_TR: tr-rTR, tt_RU: tt-rRU, tzm_DZ: tzm-rDZ, ug_CN: ug-rCN, uk_UA: uk-rUA, ur_PK: ur-rPK, uz_UZ: uz-rUZ, vi_VN: vi-rVN, wo_SN: wo-rSN, xh_ZA: xh-rZA, yo_NG: yo-rNG, zh_CN: zh-rCN, zh_HK: zh-rHK, zh_MO: zh-rMO, zh_SG: zh-rSG, zh_TW: zh-rTW, zu_ZA: zu-rZA, no_NO: no-rNO, he_IL: iw-rIL, he: iw, id:in
|
lang_map = af_ZA: af-rZA, am_ET: am-rET, ar_AE: ar-rAE, ar_BH: ar-rBH, ar_DZ: ar-rDZ, ar_EG: ar-rEG, ar_IQ: ar-rIQ, ar_JO: ar-rJO, ar_KW: ar-rKW, ar_LB: ar-rLB, ar_LY: ar-rLY, ar_MA: ar-rMA, ar_OM: ar-rOM, ar_QA: ar-rQA, ar_SA: ar-rSA, ar_SY: ar-rSY, ar_TN: ar-rTN, ar_YE: ar-rYE, arn_CL: arn-rCL, as_IN: as-rIN, az_AZ: az-rAZ, ba_RU: ba-rRU, be_BY: be-rBY, bg_BG: bg-rBG, bn_BD: bn-rBD, bn_IN: bn-rIN, bo_CN: bo-rCN, br_FR: br-rFR, bs_BA: bs-rBA, ca_ES: ca-rES, co_FR: co-rFR, cs_CZ: cs-rCZ, cy_GB: cy-rGB, da_DK: da-rDK, de_AT: de-rAT, de_CH: de-rCH, de_DE: de-rDE, de_LI: de-rLI, de_LU: de-rLU, dsb_DE: dsb-rDE, dv_MV: dv-rMV, el_GR: el-rGR, en_AU: en-rAU, en_BZ: en-rBZ, en_CA: en-rCA, en_GB: en-rGB, en_IE: en-rIE, en_IN: en-rIN, en_JM: en-rJM, en_MY: en-rMY, en_NZ: en-rNZ, en_PH: en-rPH, en_SG: en-rSG, en_TT: en-rTT, en_US: en-rUS, en_ZA: en-rZA, en_ZW: en-rZW, es_AR: es-rAR, es_BO: es-rBO, es_CL: es-rCL, es_CO: es-rCO, es_CR: es-rCR, es_DO: es-rDO, es_EC: es-rEC, es_ES: es-rES, es_GT: es-rGT, es_HN: es-rHN, es_MX: es-rMX, es_NI: es-rNI, es_PA: es-rPA, es_PE: es-rPE, es_PR: es-rPR, es_PY: es-rPY, es_SV: es-rSV, es_US: es-rUS, es_UY: es-rUY, es_VE: es-rVE, et_EE: et-rEE, eu_ES: eu-rES, fa_IR: fa-rIR, fi_FI: fi-rFI, fil_PH: fil-rPH, fo_FO: fo-rFO, fr_BE: fr-rBE, fr_CA: fr-rCA, fr_CH: fr-rCH, fr_FR: fr-rFR, fr_LU: fr-rLU, fr_MC: fr-rMC, fy_NL: fy-rNL, ga_IE: ga-rIE, gd_GB: gd-rGB, gl_ES: gl-rES, gsw_FR: gsw-rFR, gu_IN: gu-rIN, ha_NG: ha-rNG, hi_IN: hi-rIN, hr_BA: hr-rBA, hr_HR: hr-rHR, hsb_DE: hsb-rDE, hu_HU: hu-rHU, hy_AM: hy-rAM, id_ID: id-rID, ig_NG: ig-rNG, ii_CN: ii-rCN, is_IS: is-rIS, it_CH: it-rCH, it_IT: it-rIT, iu_CA: iu-rCA, ja_JP: ja-rJP, ka_GE: ka-rGE, kk_KZ: kk-rKZ, kl_GL: kl-rGL, km_KH: km-rKH, kn_IN: kn-rIN, ko_KR: ko-rKR, kok_IN: kok-rIN, ky_KG: ky-rKG, lb_LU: lb-rLU, lo_LA: lo-rLA, lt_LT: lt-rLT, lv_LV: lv-rLV, mi_NZ: mi-rNZ, mk_MK: mk-rMK, ml_IN: ml-rIN, mn_CN: mn-rCN, mn_MN: mn-rMN, moh_CA: moh-rCA, mr_IN: mr-rIN, ms_BN: ms-rBN, ms_MY: ms-rMY, mt_MT: mt-rMT, nb_NO: nb-rNO, ne_NP: ne-rNP, nl_BE: nl-rBE, nl_NL: nl-rNL, nn_NO: nn-rNO, nso_ZA: nso-rZA, oc_FR: oc-rFR, or_IN: or-rIN, pa_IN: pa-rIN, pl_PL: pl-rPL, prs_AF: prs-rAF, ps_AF: ps-rAF, pt_BR: pt-rBR, pt_PT: pt-rPT, qut_GT: qut-rGT, quz_BO: quz-rBO, quz_EC: quz-rEC, quz_PE: quz-rPE, rm_CH: rm-rCH, ro_RO: ro-rRO, ru_RU: ru-rRU, rw_RW: rw-rRW, sa_IN: sa-rIN, sah_RU: sah-rRU, se_FI: se-rFI, se_NO: se-rNO, se_SE: se-rSE, si_LK: si-rLK, sk_SK: sk-rSK, sl_SI: sl-rSI, sma_NO: sma-rNO, sma_SE: sma-rSE, smj_NO: smj-rNO, smj_SE: smj-rSE, smn_FI: smn-rFI, sms_FI: sms-rFI, sq_AL: sq-rAL, sr_BA: sr-rBA, sr_CS: sr-rCS, sr_ME: sr-rME, sr_RS: sr-rRS, sv_FI: sv-rFI, sv_SE: sv-rSE, sw_KE: sw-rKE, syr_SY: syr-rSY, ta_IN: ta-rIN, te_IN: te-rIN, tg_TJ: tg-rTJ, th_TH: th-rTH, tk_TM: tk-rTM, tn_ZA: tn-rZA, tr_TR: tr-rTR, tt_RU: tt-rRU, tzm_DZ: tzm-rDZ, ug_CN: ug-rCN, uk_UA: uk-rUA, ur_PK: ur-rPK, uz_UZ: uz-rUZ, vi_VN: vi-rVN, wo_SN: wo-rSN, xh_ZA: xh-rZA, yo_NG: yo-rNG, zh_CN: zh-rCN, zh_HK: zh-rHK, zh_MO: zh-rMO, zh_SG: zh-rSG, zh_TW: zh-rTW, zu_ZA: zu-rZA, no_NO: no-rNO, he_IL: iw-rIL, he: iw, id:in
|
||||||
|
|
||||||
[syncthing-android.description_fulltxt]
|
[syncthing-android.description_fulltxt]
|
||||||
file_filter = src/main/play/<lang>/listing/fulldescription
|
file_filter = app/src/main/play/<lang>/listing/fulldescription
|
||||||
source_file = src/main/play/en-GB/listing/fulldescription
|
source_file = app/src/main/play/en-GB/listing/fulldescription
|
||||||
source_lang = en_GB
|
source_lang = en_GB
|
||||||
type = TXT
|
type = TXT
|
||||||
lang_map = ja: ja-JP, sv: sv-SE, da: da-DK, de: de-DE, el: el-EL, es: es-ES, fi: fi-FI, it: it-IT, pl: pl-PL, nl: nl-NL, ru: ru-RU, no: no-NO, pt: pt-PT, ko: ko-KR, cs: cs-CZ, hu: hu-HU, fr: fr-FR, tr: tr-TR
|
lang_map = ja: ja-JP, sv: sv-SE, da: da-DK, de: de-DE, el: el-EL, es: es-ES, fi: fi-FI, it: it-IT, pl: pl-PL, nl: nl-NL, ru: ru-RU, no: no-NO, pt: pt-PT, ko: ko-KR, cs: cs-CZ, hu: hu-HU, fr: fr-FR, tr: tr-TR
|
||||||
|
|
||||||
[syncthing-android.description_shorttxt]
|
[syncthing-android.description_shorttxt]
|
||||||
file_filter = src/main/play/<lang>/listing/shortdescription
|
file_filter = app/src/main/play/<lang>/listing/shortdescription
|
||||||
source_file = src/main/play/en-GB/listing/shortdescription
|
source_file = app/src/main/play/en-GB/listing/shortdescription
|
||||||
source_lang = en_GB
|
source_lang = en_GB
|
||||||
type = TXT
|
type = TXT
|
||||||
lang_map = ja: ja-JP, sv: sv-SE, da: da-DK, de: de-DE, el: el-EL, es: es-ES, fi: fi-FI, it: it-IT, pl: pl-PL, nl: nl-NL, ru: ru-RU, no: no-NO, pt: pt-PT, ko: ko-KR, cs: cs-CZ, hu: hu-HU, fr: fr-FR, tr: tr-TR
|
lang_map = ja: ja-JP, sv: sv-SE, da: da-DK, de: de-DE, el: el-EL, es: es-ES, fi: fi-FI, it: it-IT, pl: pl-PL, nl: nl-NL, ru: ru-RU, no: no-NO, pt: pt-PT, ko: ko-KR, cs: cs-CZ, hu: hu-HU, fr: fr-FR, tr: tr-TR
|
||||||
|
|
||||||
[syncthing-android.titletxt]
|
[syncthing-android.titletxt]
|
||||||
file_filter = src/main/play/<lang>/listing/title
|
file_filter = app/src/main/play/<lang>/listing/title
|
||||||
source_file = src/main/play/en-GB/listing/title
|
source_file = app/src/main/play/en-GB/listing/title
|
||||||
source_lang = en_GB
|
source_lang = en_GB
|
||||||
type = TXT
|
type = TXT
|
||||||
lang_map = ja: ja-JP, sv: sv-SE, da: da-DK, de: de-DE, el: el-EL, es: es-ES, fi: fi-FI, it: it-IT, pl: pl-PL, nl: nl-NL, ru: ru-RU, no: no-NO, pt: pt-PT, ko: ko-KR, cs: cs-CZ, hu: hu-HU, fr: fr-FR, tr: tr-TR
|
lang_map = ja: ja-JP, sv: sv-SE, da: da-DK, de: de-DE, el: el-EL, es: es-ES, fi: fi-FI, it: it-IT, pl: pl-PL, nl: nl-NL, ru: ru-RU, no: no-NO, pt: pt-PT, ko: ko-KR, cs: cs-CZ, hu: hu-HU, fr: fr-FR, tr: tr-TR
|
||||||
|
|
31
README.md
31
README.md
|
@ -16,37 +16,30 @@ A wrapper of [Syncthing](https://github.com/syncthing/syncthing) for Android.
|
||||||
|
|
||||||
The project is translated on [Transifex](https://www.transifex.com/projects/p/syncthing-android/).
|
The project is translated on [Transifex](https://www.transifex.com/projects/p/syncthing-android/).
|
||||||
|
|
||||||
Translations can be updated using the [Transifex client](http://docs.transifex.com/developer/client/), using commands `tx push -s` and `tx pull -a`.
|
|
||||||
|
|
||||||
# Building
|
# Building
|
||||||
|
|
||||||
### Requirements
|
### Dependencies
|
||||||
- Android SDK Platform (for the `compileSdkVersion` specified in [build.gradle](build.gradle))
|
- Android SDK (you can skip this if you are using Android Studio)
|
||||||
- Android NDK Platform
|
- Android NDK (`$ANDROID_NDK_HOME` should point at the root directory of your NDK)
|
||||||
- Android Support Repository
|
- Go (see [here](https://docs.syncthing.net/dev/building.html#prerequisites) for the required version)
|
||||||
|
|
||||||
### Build instructions
|
### Build instructions
|
||||||
|
|
||||||
This repository is using external dependencies so you have to initialize all submodules with --recursive option first time: `git clone https://github.com/syncthing/syncthing-android.git --recursive`.
|
Make sure you clone the project with
|
||||||
|
`git clone https://github.com/syncthing/syncthing-android.git --recursive`. Alternatively, run
|
||||||
Set the `ANDROID_NDK` environment variable to the Android NDK folder (e.g. `export ANDROID_NDK=/opt/android_ndk`).
|
`git submodule init && git submodule update` in the project folder.
|
||||||
Build Go and Syncthing using `./make-all.bash`.
|
|
||||||
Use `./gradlew assembleDebug` in the project directory to compile the APK.
|
|
||||||
|
|
||||||
To prepare a new release, execute `./prepare-release.bash`, and follow the instructions.
|
|
||||||
|
|
||||||
To check for updated gradle dependencies, run `gradle dependencyUpdates`. Additionally, the git submodule in `ext/syncthing/src/github.com/syncthing/syncthing` may need to be updated.
|
|
||||||
|
|
||||||
|
Build Syncthing using `./syncthing/build-syncthing.bash`. Then use `./gradlew assembleDebug` or
|
||||||
|
Android Studio to build the apk.
|
||||||
|
|
||||||
### Building on Windows
|
### Building on Windows
|
||||||
|
|
||||||
To build the Syncthing app on Windows we need to have cygwin installed.
|
To build the Syncthing app on Windows we need to have cygwin installed.
|
||||||
|
|
||||||
From a cygwin shell in the project directory, build Go using `./make-go.bash [arch]`
|
From a cygwin shell in the project directory, build Syncthing using `./syncthing/build-syncthing.bash`
|
||||||
After Go is built, compile syncthing using `./make-syncthing.bash [arch]`
|
|
||||||
|
|
||||||
Lastly, use `./gradlew assembleDebug` in the project directory to compile the APK,
|
Lastly, use `./gradlew assembleDebug` in the project directory to compile the APK, or use Android
|
||||||
or use Android Studio to build/deploy the APK.
|
Studio to build/deploy the APK.
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
|
|
6
app/.gitignore
vendored
Normal file
6
app/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# generated files
|
||||||
|
/build
|
||||||
|
/src/main/jniLibs
|
||||||
|
|
||||||
|
# gradle-play-publisher
|
||||||
|
keys.json
|
78
app/build.gradle
Normal file
78
app/build.gradle
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'com.github.ben-manes.versions'
|
||||||
|
apply plugin: 'com.github.triplet.play'
|
||||||
|
apply plugin: 'me.tatarka.retrolambda'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile 'eu.chainfire:libsuperuser:1.0.0.201704021214'
|
||||||
|
compile 'com.android.support:design:26.1.0'
|
||||||
|
compile 'com.google.zxing:android-integration:3.3.0'
|
||||||
|
compile 'com.google.code.gson:gson:2.8.2'
|
||||||
|
compile 'org.mindrot:jbcrypt:0.4'
|
||||||
|
compile 'com.google.guava:guava:20.0'
|
||||||
|
compile 'com.annimon:stream:1.1.9'
|
||||||
|
compile 'com.android.volley:volley:1.0.0'
|
||||||
|
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
|
compile "com.google.dagger:dagger:2.11"
|
||||||
|
annotationProcessor "com.google.dagger:dagger-compiler:2.11"
|
||||||
|
androidTestCompile 'com.android.support.test:rules:1.0.1'
|
||||||
|
androidTestCompile 'com.android.support:support-annotations:26.1.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 26
|
||||||
|
buildToolsVersion "26.0.2"
|
||||||
|
buildTypes.debug.applicationIdSuffix ".debug"
|
||||||
|
dataBinding.enabled = true
|
||||||
|
|
||||||
|
playAccountConfigs {
|
||||||
|
defaultAccountConfig {
|
||||||
|
jsonFile = file('keys.json')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.nutomic.syncthingandroid"
|
||||||
|
minSdkVersion 14
|
||||||
|
targetSdkVersion 26
|
||||||
|
versionCode 4132
|
||||||
|
versionName "0.10.0-beta4"
|
||||||
|
testApplicationId 'com.nutomic.syncthingandroid.test'
|
||||||
|
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
|
||||||
|
playAccountConfig = playAccountConfigs.defaultAccountConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
storeFile file(RELEASE_STORE_FILE)
|
||||||
|
storePassword System.getenv("SIGNING_PASSWORD") ?: ""
|
||||||
|
keyAlias RELEASE_KEY_ALIAS
|
||||||
|
keyPassword System.getenv("SIGNING_PASSWORD") ?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
play {
|
||||||
|
jsonFile = file('keys.json')
|
||||||
|
uploadImages = false
|
||||||
|
track = 'production'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some languages are not supported by Google Play, so we ignore them.
|
||||||
|
*/
|
||||||
|
task deleteUnsupportedPlayTranslations(type: Delete) {
|
||||||
|
delete 'src/main/play/nn'
|
||||||
|
delete 'src/main/play/el-EL'
|
||||||
|
delete 'src/main/play/nb'
|
||||||
|
delete 'src/main/play/en/'
|
||||||
|
}
|
|
@ -109,7 +109,7 @@ public class MainActivity extends StateDialogActivity
|
||||||
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
|
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
|
||||||
mDrawerFragment.requestGuiUpdate();
|
mDrawerFragment.requestGuiUpdate();
|
||||||
if (new Date().getTime() > getFirstStartTime() + USAGE_REPORTING_DIALOG_DELAY &&
|
if (new Date().getTime() > getFirstStartTime() + USAGE_REPORTING_DIALOG_DELAY &&
|
||||||
getApi().getOptions().getUsageReportValue() == Options.USAGE_REPORTING_UNDECIDED) {
|
getApi().getOptions().isUsageReportingAccepted()) {
|
||||||
showUsageReportingDialog();
|
showUsageReportingDialog();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -452,7 +452,7 @@ public class MainActivity extends StateDialogActivity
|
||||||
Options options = getApi().getOptions();
|
Options options = getApi().getOptions();
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case DialogInterface.BUTTON_POSITIVE:
|
case DialogInterface.BUTTON_POSITIVE:
|
||||||
options.urAccepted = Options.USAGE_REPORTING_ACCEPTED;
|
options.urAccepted = options.urVersionMax;
|
||||||
break;
|
break;
|
||||||
case DialogInterface.BUTTON_NEGATIVE:
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
options.urAccepted = Options.USAGE_REPORTING_DENIED;
|
options.urAccepted = Options.USAGE_REPORTING_DENIED;
|
|
@ -234,7 +234,7 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
mRelaysEnabled.setChecked(mOptions.relaysEnabled);
|
mRelaysEnabled.setChecked(mOptions.relaysEnabled);
|
||||||
mGlobalAnnounceServers.setText(joiner.join(mOptions.globalAnnounceServers));
|
mGlobalAnnounceServers.setText(joiner.join(mOptions.globalAnnounceServers));
|
||||||
mAddress.setText(mGui.address);
|
mAddress.setText(mGui.address);
|
||||||
mUrAccepted.setChecked(mOptions.getUsageReportValue() == Options.USAGE_REPORTING_ACCEPTED);
|
mUrAccepted.setChecked(mOptions.isUsageReportingAccepted());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -277,7 +277,7 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
case "address": mGui.address = (String) o; break;
|
case "address": mGui.address = (String) o; break;
|
||||||
case "urAccepted":
|
case "urAccepted":
|
||||||
mOptions.urAccepted = ((boolean) o)
|
mOptions.urAccepted = ((boolean) o)
|
||||||
? Options.USAGE_REPORTING_ACCEPTED
|
? mOptions.urVersionMax
|
||||||
: Options.USAGE_REPORTING_DENIED;
|
: Options.USAGE_REPORTING_DENIED;
|
||||||
break;
|
break;
|
||||||
default: throw new InvalidParameterException();
|
default: throw new InvalidParameterException();
|
|
@ -10,6 +10,7 @@ import android.util.Log;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import com.android.volley.AuthFailureError;
|
import com.android.volley.AuthFailureError;
|
||||||
|
import com.android.volley.DefaultRetryPolicy;
|
||||||
import com.android.volley.RequestQueue;
|
import com.android.volley.RequestQueue;
|
||||||
import com.android.volley.VolleyError;
|
import com.android.volley.VolleyError;
|
||||||
import com.android.volley.toolbox.HurlStack;
|
import com.android.volley.toolbox.HurlStack;
|
||||||
|
@ -113,6 +114,11 @@ public abstract class ApiRequest {
|
||||||
return Optional.fromNullable(requestBody).transform(String::getBytes).orNull();
|
return Optional.fromNullable(requestBody).transform(String::getBytes).orNull();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Some requests seem to be slow or fail, make sure this doesn't break the app
|
||||||
|
// (eg if an event request fails, new event requests won't be triggered).
|
||||||
|
request.setRetryPolicy(new DefaultRetryPolicy(5000, 5,
|
||||||
|
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
|
||||||
getVolleyQueue().add(request);
|
getVolleyQueue().add(request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ public class Options {
|
||||||
public int natRenewalMinutes;
|
public int natRenewalMinutes;
|
||||||
public int natTimeoutSeconds;
|
public int natTimeoutSeconds;
|
||||||
public int urAccepted;
|
public int urAccepted;
|
||||||
|
public int urVersionMax;
|
||||||
public String urUniqueId;
|
public String urUniqueId;
|
||||||
public String urURL;
|
public String urURL;
|
||||||
public boolean urPostInsecurely;
|
public boolean urPostInsecurely;
|
||||||
|
@ -36,15 +37,9 @@ public class Options {
|
||||||
public int tempIndexMinBlocks;
|
public int tempIndexMinBlocks;
|
||||||
|
|
||||||
public static final int USAGE_REPORTING_UNDECIDED = 0;
|
public static final int USAGE_REPORTING_UNDECIDED = 0;
|
||||||
public static final int USAGE_REPORTING_ACCEPTED = 2;
|
|
||||||
public static final int USAGE_REPORTING_DENIED = -1;
|
public static final int USAGE_REPORTING_DENIED = -1;
|
||||||
|
|
||||||
public int getUsageReportValue() {
|
public boolean isUsageReportingAccepted() {
|
||||||
if (urAccepted > USAGE_REPORTING_ACCEPTED)
|
return urAccepted == urVersionMax;
|
||||||
throw new RuntimeException("Inalid usage reporting value");
|
|
||||||
|
|
||||||
return (urAccepted == USAGE_REPORTING_ACCEPTED || urAccepted == USAGE_REPORTING_DENIED)
|
|
||||||
? urAccepted
|
|
||||||
: USAGE_REPORTING_UNDECIDED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
package com.nutomic.syncthingandroid.service;
|
package com.nutomic.syncthingandroid.service;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.media.MediaScannerConnection;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.provider.MediaStore;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
@ -144,11 +147,19 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene
|
||||||
folderPath = f.path;
|
folderPath = f.path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File updatedFile = new File(folderPath,
|
File updatedFile = new File(folderPath, (String) event.data.get("item"));
|
||||||
(String) event.data.get("item"));
|
if (!"delete".equals(event.data.get("action"))) {
|
||||||
Log.i(TAG, "Notified media scanner about " + updatedFile.toString());
|
Log.i(TAG, "Rescanned file via MediaScanner: " + updatedFile.toString());
|
||||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
|
MediaScannerConnection.scanFile(mContext, new String[]{updatedFile.getPath()},
|
||||||
Uri.fromFile(updatedFile)));
|
null, null);
|
||||||
|
} else {
|
||||||
|
// https://stackoverflow.com/a/29881556/1837158
|
||||||
|
Log.i(TAG, "Deleted file from MediaStore: " + updatedFile.toString());
|
||||||
|
Uri contentUri = MediaStore.Files.getContentUri("external");
|
||||||
|
ContentResolver resolver = mContext.getContentResolver();
|
||||||
|
resolver.delete(contentUri, MediaStore.Images.ImageColumns.DATA + " LIKE ?",
|
||||||
|
new String[]{updatedFile.getPath()});
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "Ping":
|
case "Ping":
|
||||||
// Ignored.
|
// Ignored.
|
|
@ -142,9 +142,14 @@ public class ConfigXml {
|
||||||
gui.appendChild(password);
|
gui.appendChild(password);
|
||||||
}
|
}
|
||||||
String apikey = getApiKey();
|
String apikey = getApiKey();
|
||||||
boolean passwordOk;
|
|
||||||
String pw = password.getTextContent();
|
String pw = password.getTextContent();
|
||||||
|
boolean passwordOk;
|
||||||
|
try {
|
||||||
passwordOk = !TextUtils.isEmpty(pw) && BCrypt.checkpw(apikey, pw);
|
passwordOk = !TextUtils.isEmpty(pw) && BCrypt.checkpw(apikey, pw);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.w(TAG, "Malformed password", e);
|
||||||
|
passwordOk = false;
|
||||||
|
}
|
||||||
if (!passwordOk) {
|
if (!passwordOk) {
|
||||||
Log.i(TAG, "Updating password");
|
Log.i(TAG, "Updating password");
|
||||||
password.setTextContent(BCrypt.hashpw(apikey, BCrypt.gensalt(4)));
|
password.setTextContent(BCrypt.hashpw(apikey, BCrypt.gensalt(4)));
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue