Compare commits
309 Commits
android-0.
...
i2p-androi
Author | SHA1 | Date | |
---|---|---|---|
59b1da6950 | |||
40894d8d04 | |||
d0f38397cd | |||
17b86fffdd | |||
a06b449bfb | |||
128f1df0ac | |||
ed085194e6 | |||
52a4c2f430 | |||
784918d220 | |||
f129773255 | |||
b304771eca | |||
f87e8d036b | |||
16c1277935 | |||
a6aa76f9dd | |||
a0ced4133d | |||
e024950567 | |||
ea68f116e1 | |||
3cb746594c | |||
27adae63eb | |||
85890d3b68 | |||
96b045eb2a | |||
8d00c5fa31 | |||
fc93a71552 | |||
18e4aef4ca | |||
5315e35adc | |||
9ad9bc07ff | |||
bde92be29d | |||
849150ffa6 | |||
52dad19c7a | |||
e84a51097d | |||
5289f5068a | |||
09c7d9cfd8 | |||
14d293fe6f | |||
7cd08cfd4c | |||
aa22d83a44 | |||
a1fd8d41b2 | |||
9d24e68b57 | |||
d5e2804ea4 | |||
1edabd7252 | |||
52c1901eba | |||
a6f5221975 | |||
caa57bbc3a | |||
b28e5d741e | |||
0f3a61390c | |||
30a1f1d800 | |||
22d5d126f6 | |||
70e4ea810f | |||
b5c6e1489a | |||
333a1a49b1 | |||
2ea93f106e | |||
d99ed0e5da | |||
3881966ddb | |||
9de9f46489 | |||
149881522e | |||
df26d89310 | |||
707dcbbc78 | |||
812aea9873 | |||
aeb7614b62 | |||
9bf9d27c5a | |||
f2cfe4cee5 | |||
45865ff5b9 | |||
96f9905952 | |||
41ca3fe527 | |||
c5468e4829 | |||
174bb7f827 | |||
3d92f32c13 | |||
2fae27a3b3 | |||
71d38c64e0 | |||
ddb651a602 | |||
a8ad1d8d47 | |||
912602bfc0 | |||
24e3358ffa | |||
fcc51c429d | |||
de0ee87db3 | |||
2102d55315 | |||
2f900ebe2d | |||
5c03981a61 | |||
c68f0ff23a | |||
b01f44ae1f | |||
05aeb0cf37 | |||
fd8d596064 | |||
ea3fe136e4 | |||
47f4530f6f | |||
016a7a47fd | |||
f8410deeba | |||
7268132ddd | |||
62545f1247 | |||
99b6992b5c | |||
e8ebb0a569 | |||
3ab2c83b7b | |||
cb46abca82 | |||
63b345e329 | |||
794b8433d8 | |||
a7891a3674 | |||
7076785ec1 | |||
f8eda45409 | |||
8d0f1689c1 | |||
25ef37cddf | |||
c5936858a2 | |||
17d2e2fc93 | |||
a0e41e5171 | |||
2d1244f339 | |||
9eec1d3348 | |||
5824fd4efa | |||
9c87bfcb51 | |||
0c380f2ef5 | |||
dafe3d0002 | |||
255ac60691 | |||
23f681dd7d | |||
d6a55a122a | |||
454937d345 | |||
ec8cf76fc4 | |||
6788f9a663 | |||
dc96c6251f | |||
c2bced68bb | |||
e21b4e5cbd | |||
1f434d8a05 | |||
cd12d84d47 | |||
82b92caa55 | |||
49e4fcc49c | |||
a9abe05325 | |||
ea6705374f | |||
3e28f2bf93 | |||
4c881525f9 | |||
9280c80a53 | |||
e465a6d232 | |||
d7f79e7b0b | |||
68f44b8ec1 | |||
0835a42fbd | |||
78e649dc9b | |||
84e73a693c | |||
c0ad7dfc09 | |||
dec68432bc | |||
f93fc155ef | |||
e348af340a | |||
aa3631ed33 | |||
f2088ad1e5 | |||
008e9b7961 | |||
90a46bcc3f | |||
f69f748064 | |||
640a2e1918 | |||
8aead91700 | |||
b18a2e6241 | |||
09c3e6e12c | |||
74bf0eade2 | |||
2fa6e7f3cb | |||
24b741be1e | |||
ac8ce6f916 | |||
cd7d0ad723 | |||
c5a0c3608d | |||
3863c0e183 | |||
69ea3d8bde | |||
7cafe6da48 | |||
9464b46ad0 | |||
c230a5a101 | |||
3d37f2ae07 | |||
f88aafe292 | |||
aa2dab1d3c | |||
8e85eaa2f0 | |||
6a1848caf6 | |||
aa36b4cb14 | |||
78d4b12142 | |||
c2f3a80dec | |||
a679784aab | |||
835667437b | |||
f016edec7a | |||
1e3b517219 | |||
f4e3b15fcf | |||
fc4154be67 | |||
5bf0b18767 | |||
eb5ef3129b | |||
6e87d248c0 | |||
c9b0aff142 | |||
5acac0dbc4 | |||
0b42a7ee64 | |||
c3a798ee3d | |||
e682369311 | |||
14b953f145 | |||
036c807d6b | |||
a41fca95df | |||
26fdf40f25 | |||
070af6529c | |||
7ba0892351 | |||
5b9cdb9f9f | |||
b79d39a74a | |||
5fc5aed0c9 | |||
aec25ab374 | |||
9d5c495936 | |||
4dc2bb6b01 | |||
373e013911 | |||
83bb7096a7 | |||
cc1c4690a2 | |||
69ad581235 | |||
4be227631d | |||
3f3f1f8e3d | |||
22290da1a4 | |||
7caf21d552 | |||
701860a525 | |||
7615aca89e | |||
cae8ed2ae3 | |||
a523e1cb4a | |||
5e048af9c1 | |||
77b6c4d30f | |||
983a94e1c4 | |||
1f79323d66 | |||
d86d3ad5ae | |||
c41b064045 | |||
4c299ecda3 | |||
761f427366 | |||
f4c4bfe8be | |||
7f15a6f1e1 | |||
5734760d58 | |||
3244adfcd2 | |||
ce62b0fb97 | |||
64673ee185 | |||
a36cabdcc8 | |||
1e8531c731 | |||
0935659d6d | |||
bef5f7e746 | |||
d64e8359c1 | |||
5fd77ea62d | |||
8626ac2913 | |||
1258f18bc3 | |||
8b677abd3c | |||
f3d1e89002 | |||
f39c9a0fc4 | |||
3186caa6bb | |||
fc1259d8a8 | |||
848d07331e | |||
9794d26d0c | |||
76cd9c85ef | |||
d4c7c480fb | |||
00aa80d104 | |||
20086685aa | |||
86a8effd82 | |||
55d6e6d24e | |||
3b05046df3 | |||
b8587cd0ab | |||
61dd550040 | |||
478ff63889 | |||
e747619b85 | |||
f043bb3d72 | |||
98d8106f56 | |||
74eb0ce4f6 | |||
d79813d6d1 | |||
8f60c6ce9e | |||
7e0d017858 | |||
8470435ee2 | |||
5023d69222 | |||
34c7464f5b | |||
2da6fe9c62 | |||
1927c9e5a3 | |||
1ace085d13 | |||
95e6c1f7a6 | |||
03bdd575a7 | |||
98c5313d75 | |||
c047bdf085 | |||
e113ef0002 | |||
3e9b47307d | |||
2d864ad8b1 | |||
5b7f9bd452 | |||
3c89749f94 | |||
edbd5fd7ea | |||
faf8bf74af | |||
851e774e7a | |||
dcea801116 | |||
cb5235e6da | |||
5c7eaf2484 | |||
764cfc91ec | |||
177a2c6dc1 | |||
4dccd1dbae | |||
50141eb24b | |||
4dab632bc8 | |||
350515041a | |||
5ba294c2c2 | |||
a215363206 | |||
4bd647c67c | |||
b951892c05 | |||
16e05e0dd8 | |||
5bdf119b81 | |||
b73b72c9c8 | |||
0bae211da5 | |||
709392e8b6 | |||
80ed1e71da | |||
6c0a60892f | |||
7f13aa26fb | |||
7167a11844 | |||
1f140bf95a | |||
940b2b83a1 | |||
bdbebe11c4 | |||
51ca137102 | |||
f0ff4eeab7 | |||
93d103e5ad | |||
b87d77d5e3 | |||
ffbd8cfb76 | |||
2d1664574d | |||
5d3aa1f625 | |||
3fa53c7654 | |||
84ecf55ff8 | |||
72ad40ecfc | |||
2f48898235 | |||
39758c8cf4 | |||
ecc5509007 | |||
0e75b3e957 | |||
7b4c80216d | |||
70bbc18054 | |||
09fcef23a4 | |||
333f09073a | |||
58cb33aa77 |
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
app/pkg-temp
|
||||
app/build
|
||||
app/pkg-mavencentral
|
73
.github/workflows/ant.yml
vendored
Normal file
73
.github/workflows/ant.yml
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
# Mostly copied from https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-ant
|
||||
# zlatinb
|
||||
|
||||
name: Java CI
|
||||
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: GetText
|
||||
run: sudo apt install gettext git
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
- name : Generate override.properties
|
||||
run: |
|
||||
rm -f override.properties
|
||||
echo "build.built-by=GitHub Actions" >> override.properties
|
||||
echo "noExe=true" >> override.properties
|
||||
- name: build with Gradle
|
||||
run: |
|
||||
echo "i2psrc=$HOME/i2p.i2p" > routerjars/local.properties
|
||||
git clone -b i2p-2.4.0 https://github.com/i2p/i2p.i2p "$HOME/i2p.i2p"
|
||||
./gradlew assembleDebug
|
||||
find . -name '*.apk'
|
||||
- name: Upload i2p-debug-${{ github.sha }}.apk
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2p-debug.apk
|
||||
path: ./app/build/outputs/apk/free/debug/app-free-debug.apk
|
||||
|
||||
trunk:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: GetText
|
||||
run: sudo apt install gettext git
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
- name : Generate override.properties
|
||||
run: |
|
||||
rm -f override.properties
|
||||
echo "build.built-by=GitHub Actions" >> override.properties
|
||||
echo "noExe=true" >> override.properties
|
||||
grep -v I2P_ gradle.properties > gradle.properties.update
|
||||
echo "I2P_VERSION=2.5.0-1" >> gradle.properties.update
|
||||
echo "I2P_ANDROID_VERSION=2.5.0-1" >> gradle.properties.update
|
||||
cp -v gradle.properties.update gradle.properties
|
||||
- name: build with Gradle
|
||||
run: |
|
||||
echo "i2psrc=$HOME/i2p.i2p" > routerjars/local.properties
|
||||
git clone -b master https://github.com/i2p/i2p.i2p "$HOME/i2p.i2p"
|
||||
bash -c "cd $HOME/i2p.i2p && ./installer/resources/maven-dev-release.sh 1"
|
||||
./gradlew assembleDebug
|
||||
find . -name '*.apk'
|
||||
- name: Upload i2p-debug-${{ github.sha }}.apk
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2p-debug-trunk-${{ github.sha }}.apk
|
||||
path: ./app/build/outputs/apk/free/debug/app-free-debug.apk
|
22
.github/workflows/github-sync.yml
vendored
Normal file
22
.github/workflows/github-sync.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# File: .github/workflows/github-sync.yml for i2p-hackers/i2p.android.base
|
||||
on:
|
||||
schedule:
|
||||
- cron: "*/5 * * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
repo-sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: repo-sync
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: repo-sync/github-sync@v2
|
||||
with:
|
||||
source_repo: "https://i2pgit.org/i2p-hackers/i2p.android.base"
|
||||
source_branch: "master"
|
||||
destination_branch: "master"
|
||||
github_token: ${{ secrets.PAT }}
|
62
.github/workflows/release.yml
vendored
Normal file
62
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
name: Release
|
||||
|
||||
#on: [push]
|
||||
|
||||
on:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- 'i2p-android-*.*.*' # Release i2p-firefox-1.2.3
|
||||
- 'i2p-android-*.*.*-*' # Release i2p-firefox-1.2.3
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: |
|
||||
CHANGELOG.md
|
||||
sparse-checkout-cone-mode: false
|
||||
- name: sleep 6 minutes
|
||||
run: |
|
||||
echo "sleeping 6 minutes to wait for artifacts"
|
||||
sleep 1m
|
||||
echo "sleeping 5 minutes to wait for artifacts"
|
||||
sleep 1m
|
||||
echo "sleeping 4 minutes to wait for artifacts"
|
||||
sleep 1m
|
||||
echo "sleeping 3 minutes to wait for artifacts"
|
||||
sleep 1m
|
||||
echo "sleeping 2 minutes to wait for artifacts"
|
||||
sleep 1m
|
||||
echo "sleeping 1 minutes to wait for artifacts"
|
||||
sleep 1m
|
||||
- name: Download artifacts
|
||||
id: download-artifact
|
||||
uses: dawidd6/action-download-artifact@v3
|
||||
with:
|
||||
skip_unpack: true
|
||||
workflow: ant.yml
|
||||
if_no_artifact_found: fail
|
||||
# remove .zip file extension
|
||||
#- run: for f in *.zip; do unzip "$f"; rm "$f"; done
|
||||
- run: unzip i2p-debug.apk.zip
|
||||
- run: echo "" | tee -a RELEASE.md
|
||||
- run: echo "## Checksums" | tee -a RELEASE.md
|
||||
- run: echo "" | tee -a RELEASE.md
|
||||
- run: echo '```' | tee -a RELEASE.md
|
||||
- run: sha256sum * | tee -a RELEASE.md
|
||||
- run: echo '```' | tee -a RELEASE.md
|
||||
- run: echo "" | tee -a RELEASE.md
|
||||
- run: echo '```' | tee -a RELEASE.md
|
||||
- run: file * | tee -a RELEASE.md
|
||||
- run: echo '```' | tee -a RELEASE.md
|
||||
- run: echo "" | tee -a RELEASE.md
|
||||
- name: Upload artifacts
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "*"
|
||||
bodyFile: "RELEASE.md"
|
95
.github/workflows/sign.yml
vendored
Normal file
95
.github/workflows/sign.yml
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
# Mostly copied from https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-ant
|
||||
# zlatinb
|
||||
|
||||
name: Java Signed CI
|
||||
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
build-signed:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: GetText
|
||||
run: sudo apt install gettext git
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
- name: Generate override.properties
|
||||
env:
|
||||
DEV_SIGNING_KEY: ${{ secrets.DEV_SIGNING_KEY }}
|
||||
DEV_PASSWORD: ${{ secrets.DEV_PASSWORD }}
|
||||
run: |
|
||||
rm -f override.properties
|
||||
mv etc/github.gradle.properties gradle.properties
|
||||
mv etc/github.signing.properties signing.properties
|
||||
mkdir -p $HOME/keystores/
|
||||
echo $DEV_SIGNING_KEY | base64 --decode > $HOME/keystores/android-release.keystore
|
||||
echo "KEY_ALIAS=mykey" >> signing.properties
|
||||
echo "KEY_PASSWORD=$DEV_PASSWORD" >> signing.properties
|
||||
echo "build.built-by=GitHub Actions" >> override.properties
|
||||
echo "noExe=true" >> override.properties
|
||||
- name: build with Gradle
|
||||
run: |
|
||||
echo "i2psrc=$HOME/i2p.i2p" > routerjars/local.properties
|
||||
git clone -b i2p-2.4.0 https://github.com/i2p/i2p.i2p "$HOME/i2p.i2p"
|
||||
./gradlew assembleRelease
|
||||
find . -name '*.apk'
|
||||
ls -lah $HOME/keystores/android-release.keystore
|
||||
ls -d $HOME
|
||||
- name: Upload i2p-debug-${{ github.sha }}.apk
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2p-debug.apk
|
||||
path: ./app/build/outputs/apk/free/debug/app-free-debug.apk
|
||||
|
||||
trunk-signed:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: GetText
|
||||
run: sudo apt install gettext git
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
- name: Generate override.properties
|
||||
env:
|
||||
DEV_SIGNING_KEY: ${{ secrets.DEV_SIGNING_KEY }}
|
||||
DEV_PASSWORD: ${{ secrets.DEV_PASSWORD }}
|
||||
run: |
|
||||
rm -f override.properties
|
||||
echo "build.built-by=GitHub Actions" >> override.properties
|
||||
echo "noExe=true" >> override.properties
|
||||
mv etc/github.gradle.properties gradle.properties
|
||||
mv etc/github.signing.properties signing.properties
|
||||
mkdir -p $HOME/keystores/
|
||||
echo $DEV_SIGNING_KEY | base64 --decode > $HOME/keystores/android-release.keystore
|
||||
echo "KEY_ALIAS=mykey" >> signing.properties
|
||||
echo "KEY_PASSWORD=$DEV_PASSWORD" >> signing.properties
|
||||
grep -v I2P_ gradle.properties > gradle.properties.update
|
||||
echo "I2P_VERSION=2.5.0-1" >> gradle.properties.update
|
||||
echo "I2P_ANDROID_VERSION=2.5.0-1" >> gradle.properties.update
|
||||
cp -v gradle.properties.update gradle.properties
|
||||
- name: build with Gradle
|
||||
run: |
|
||||
echo "i2psrc=$HOME/i2p.i2p" > routerjars/local.properties
|
||||
git clone -b master https://github.com/i2p/i2p.i2p "$HOME/i2p.i2p"
|
||||
bash -c "cd $HOME/i2p.i2p && ./installer/resources/maven-dev-release.sh 1"
|
||||
./gradlew assembleRelease
|
||||
find . -name '*.apk'
|
||||
ls -lah $HOME/keystores/android-release.keystore
|
||||
ls -d $HOME
|
||||
- name: Upload i2p-debug-${{ github.sha }}.apk
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: i2p-debug-trunk-${{ github.sha }}.apk
|
||||
path: ./app/build/outputs/apk/free/debug/app-free-debug.apk
|
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
etc/docker.signing.properties
|
||||
signing.properties
|
||||
.idea
|
||||
.idea/
|
||||
.gradle/
|
||||
local.properties
|
||||
override.properties
|
||||
build
|
52
.mtn-ignore
52
.mtn-ignore
@ -1,52 +0,0 @@
|
||||
# Just to try and prevent some noob disasters.
|
||||
# Use mtn add --no-respect-ignore foo.jar to ignore this ignore list
|
||||
_jsp\.java$
|
||||
\.bz2$
|
||||
\.class$
|
||||
\.diff$
|
||||
\.exe$
|
||||
\.fba$
|
||||
\.gz$
|
||||
\.jar$
|
||||
\.out$
|
||||
\.patch$
|
||||
\.sig$
|
||||
\.sud$
|
||||
\.su2$
|
||||
\.tar$
|
||||
\.war$
|
||||
\.zip$
|
||||
^\.
|
||||
^build/
|
||||
^pkg-temp/
|
||||
~$
|
||||
/build/
|
||||
/classes/
|
||||
|
||||
# Android-specific ignores
|
||||
^lib/client/libs
|
||||
^routerjars/libs
|
||||
local.properties
|
||||
signing.properties
|
||||
|
||||
#IntelliJ IDEA
|
||||
^.idea
|
||||
.*.iml
|
||||
.*.ipr
|
||||
.*.iws
|
||||
|
||||
#Gradle
|
||||
build
|
||||
|
||||
# I2P-specific ignores
|
||||
^app/src/main/res/drawable/i2plogo.png
|
||||
^app/src/main/res/raw/blocklist_txt
|
||||
^app/src/main/res/raw/hosts_txt
|
||||
^app/src/main/res/raw/.*_ht
|
||||
^app/src/main/res/raw/license_
|
||||
^app/src/main/res/raw/certificates_zip
|
||||
^app/src/main/assets/themes/console/images
|
||||
^app/src/main/assets/themes/console/light/console.css
|
||||
^app/src/main/assets/themes/console/light/images/header.png
|
||||
^scripts/build.number
|
||||
^scripts/version.properties
|
28
.tx/config
28
.tx/config
@ -1,18 +1,18 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = he: iw, id: in, pt_BR: pt-rBR, ru_RU: ru, sv_SE: sv, tr_TR: tr, uk_UA: uk, yi: ji, zh_CN: zh, zh_TW: zh-rTW
|
||||
host = https://www.transifex.com
|
||||
lang_map = pt_BR: pt-rBR, yi: ji, zh_CN: zh, zh_TW: zh-rTW, id: in, ru_RU: ru, sv_SE: sv, tr_TR: tr, uk_UA: uk, he: iw, es_AR: es-rAR
|
||||
|
||||
[I2P.android]
|
||||
file_filter = app/src/main/res/values-<lang>/strings.xml
|
||||
[o:otf:p:I2P:r:android]
|
||||
file_filter = app/src/main/res/values-<lang>/strings.xml
|
||||
source_file = app/src/main/res/values/strings.xml
|
||||
source_lang = en
|
||||
type = ANDROID
|
||||
minimum_perc = 22
|
||||
|
||||
[o:otf:p:I2P:r:android_lib_helper]
|
||||
file_filter = lib/helper/src/main/res/values-<lang>/strings.xml
|
||||
source_file = lib/helper/src/main/res/values/strings.xml
|
||||
source_lang = en
|
||||
type = ANDROID
|
||||
minimum_perc = 50
|
||||
source_file = app/src/main/res/values/strings.xml
|
||||
source_lang = en
|
||||
type = ANDROID
|
||||
|
||||
[I2P.android_lib_helper]
|
||||
file_filter = lib/helper/src/main/res/values-<lang>/strings.xml
|
||||
minimum_perc = 50
|
||||
source_file = lib/helper/src/main/res/values/strings.xml
|
||||
source_lang = en
|
||||
type = ANDROID
|
||||
|
||||
|
149
CHANGELOG
149
CHANGELOG
@ -1,3 +1,152 @@
|
||||
2.4.0
|
||||
* Update I2P Library
|
||||
|
||||
2.3.0
|
||||
* Update I2P Library
|
||||
|
||||
2.2.0
|
||||
* Add blocklist feed support
|
||||
* Fix translations on stats page
|
||||
* Various bugfixes
|
||||
|
||||
2.1.0-1
|
||||
* adds support for adding base32 addresses to the local addressbook
|
||||
* adds support for destinations with ports in the string to i2ptunnel
|
||||
* adds support for remote applications launching I2P, via MR#3 from @RyeMantis
|
||||
|
||||
2.1.0
|
||||
* Upgrades router to version 2.1.0
|
||||
* Adds jcenter repository back to app/ target, removes jcenter from other targets
|
||||
* explicitly set android.useAndroidX
|
||||
|
||||
2.0.1
|
||||
* Fixes gitlab#49 by applying MUTABLE or IMMUTABLE flags across all PendingIntents
|
||||
|
||||
2.0.0
|
||||
* Updates router to version 2.0.0
|
||||
* Updates gradle plugin
|
||||
* Remove Firefox from supported browsers list due to lack of about:config support
|
||||
* Add Privacy Browser to supported browsers list and write guide for it
|
||||
|
||||
1.9.1
|
||||
* Switches back to mavenCentral builds
|
||||
* Fixes build process for F-Droid main
|
||||
* Using tag i2p.i2p:i2p-android-1.9.0
|
||||
* Allow b32 and blinded b32 to validate in I2PTunnel UI
|
||||
|
||||
1.9.0
|
||||
* Updates router to version 1.9.0
|
||||
* Using tag i2p.i2p:i2p-android-1.9.0
|
||||
|
||||
1.8.2
|
||||
* This update fixes a bug where Family Keys are incorrectly handled by the Android router, leading
|
||||
to a crash.
|
||||
* This update fixes a bug wherein incorrect type-checking caused a crash when using the Network
|
||||
Config page for some users.
|
||||
|
||||
1.8.1
|
||||
* This update fixes a bug where certificates were unpacked to the wrong location on new installs,
|
||||
resulting in the router failing to start.
|
||||
* Decouples the Android version from the I2P library version to allow for android point
|
||||
releases with less pain.
|
||||
|
||||
1.8.0
|
||||
* This release updates the underlying I2P libraries to I2P version 1.8.0
|
||||
* The SAM API now operates in "Interactive Authentication" mode. Users will be prompted via
|
||||
the notificationArea to approve or ignore new SAM connections initiated by external apps.
|
||||
* The network config menu now features a drop-down configuration instead of a slider configuration
|
||||
(since reversed)
|
||||
|
||||
1.7.1
|
||||
* This release updates the underlying I2P libraries to I2P version 1.7.1
|
||||
|
||||
1.7.0
|
||||
* This release updates the underlying I2P libraries to I2P version 1.7.0
|
||||
* Refactor of the unzipResourceToDir function
|
||||
|
||||
1.6.0
|
||||
* This release updates the underlying I2P libraries to I2P version 1.6.0
|
||||
|
||||
1.5.0
|
||||
* This release updates the underlying I2P libraries to I2P version 1.5.0
|
||||
|
||||
0.9.50 2021-05-18
|
||||
* This release updates the underlying I2P libraries to I2P version 0.9.50
|
||||
|
||||
0.9.48 2020-12-02
|
||||
* This release updates the underlying I2P libraries to I2P version 0.9.48
|
||||
* Updates to browser configuration documentation
|
||||
|
||||
0.9.47-1 2020-10-29
|
||||
* This release fixes a number of bugs arising from a misconfigured bootclasspath
|
||||
* Fix a battery-management issue arising on some phones
|
||||
|
||||
0.9.47 / 2020-08-26
|
||||
* Notification bug-fixes on platforms >8.0
|
||||
|
||||
0.9.46 / 2020-06-03
|
||||
* catch ActivityNotFound exception in MainActivity
|
||||
|
||||
0.9.45 / 2020-03-07
|
||||
* No significant changes
|
||||
|
||||
0.9.44 / 2019-12-03
|
||||
* Updated translations
|
||||
* Bumped target sdk version to 28, enforced by google
|
||||
|
||||
0.9.43-1 / 2019-10-28
|
||||
* Fix crash at startup in TCG
|
||||
|
||||
0.9.43 / 2019-10-27
|
||||
* Save state in background thread (tickets #2595, #2632)
|
||||
* Fix ISE in language dialog (ticket #2631)
|
||||
* Fix NPE in create tunnel (ticket #2629)
|
||||
* Update logo after router killed in background
|
||||
* Fix message in tunnels tabs when tunnels not up yet
|
||||
* Hide tunnel actions while TCG is starting
|
||||
* Add battery permissions dialog (ticket #2607)
|
||||
|
||||
0.9.42 / 2019-08-28
|
||||
* Possible fix for tunnel edit dialog crash (ticket #2598)
|
||||
|
||||
0.9.41 / 2019-07-03
|
||||
* New 64 bit libjbigi (ticket #2503)
|
||||
* Update 32 bit jbigi to GMP 6.1.2
|
||||
* Fix for client tunnels not starting after reseed
|
||||
* UPnP Fixes (ticket #2499)
|
||||
* WebView crash fixes (ticket #2390)
|
||||
* i2ptunnel crash fix (ticket #2552)
|
||||
* i2ptunnel ANR fix (ticket #2491)
|
||||
* Browser help pages improvements (tickets #2521, 2523)
|
||||
* Code cleanups and fixes
|
||||
* Update visibility of floating menu items
|
||||
* Put our router info at top of list
|
||||
* Table layout cleanups
|
||||
* Fixes for threads remaining after router stop
|
||||
* Remove BOB
|
||||
* Remove welterde IRC tunnel
|
||||
* Various lint fixes
|
||||
* New translations: Add cs, da, el
|
||||
* Add missing translations to menu: ar, fi, gl, hu, zh_TW
|
||||
|
||||
0.9.40 / 2019-05-10
|
||||
* Open local I2CP socket for 3rd party apps
|
||||
* Fix News URLs
|
||||
* Numerous bug fixes (see trac)
|
||||
|
||||
0.9.39 / 2019-03-23
|
||||
* Set App ID
|
||||
|
||||
0.9.38 / 2019-01-27
|
||||
|
||||
0.9.37 / 2018-10-10
|
||||
|
||||
0.9.36 / 2018-08-27
|
||||
|
||||
0.9.35 / 2018-07-03
|
||||
|
||||
0.9.34 / 2018-04-25
|
||||
|
||||
0.9.33 / 2018-02-18
|
||||
* Translation updates
|
||||
|
||||
|
11
DEVELOPMENT-README.md
Normal file
11
DEVELOPMENT-README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Development Readme
|
||||
|
||||
## How to build development builds of the router core for android?
|
||||
|
||||
Check the RELEASE-PROCESS.md file for general information about how to build and to bump the version.
|
||||
|
||||
In your i2p.i2p codebase checkout, execute `./installer/resources/maven-dev-release.sh` with your build number as first argument.
|
||||
The script locates itself and uses the same codebase as it's in, to produce the maven builds which will be locally installed.
|
||||
|
||||
Next, add the build number to the gradle.properties and build the android build as usual.
|
||||
|
91
DOCKER.md
Normal file
91
DOCKER.md
Normal file
@ -0,0 +1,91 @@
|
||||
Docker Build Instructions
|
||||
=========================
|
||||
|
||||
It is possible to build a container with a pre-installed environment for
|
||||
correctly compiling an I2P for Android development build. Unlike the i2p.i2p
|
||||
container, zero attempt has been made to optimize the size of the container,
|
||||
as it contains a copy of the latest Android SDK, toolchains, and Android NDK,
|
||||
which it must download. To save time, this is cached locally. It is likely to
|
||||
take up to 30 GB of disk space to compile in this way, however, it is very easy
|
||||
and convenient compared to the steps in RELEASE-PROCESS.md and may make
|
||||
building Android reproducibly easier in the future.
|
||||
|
||||
Container dependencies
|
||||
----------------------
|
||||
|
||||
- `menny/android_ndk` (third-party image) (reviewed by idk) (depends on menny/android_sdk
|
||||
- `menny/android_sdk` (third-party image) (reviewed by idk) (depends on ubuntu/18.04)
|
||||
- `ubuntu/18.04` (official docker container) (base container)
|
||||
|
||||
Build the container locally
|
||||
---------------------------
|
||||
|
||||
Run:
|
||||
|
||||
docker build -t i2p.android.base .
|
||||
|
||||
To build the container. It will have a lot to download the first time, so it may take
|
||||
a while to complete.
|
||||
|
||||
Run an Android build in the container
|
||||
-------------------------------------
|
||||
|
||||
Copy the `etc/docker.signing.example.proprties` file to `etc/docker.signing.proprties`,
|
||||
edit it to match your key information and rebuild the container.
|
||||
|
||||
Run:
|
||||
|
||||
docker run -it \
|
||||
-u $(id -u):$(id -g) \
|
||||
--name i2p.android.base \
|
||||
-v $HOME/.gnupg/:/.gnupg/:ro \
|
||||
-v $HOME/.i2p-plugin-keys/:/.i2p-plugin-keys/:ro \
|
||||
-v /run/user/$(id -u)/:/run/user/$(id -u)/:ro \
|
||||
i2p.android.base
|
||||
|
||||
To get the build artifacts for uploading to Maven out of the container, use:
|
||||
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/pkg-mavencentral app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-i2p.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-mstreaming.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-router.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-servlet-i2p.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-streaming.jar app/pkg-mavencentral
|
||||
|
||||
To get the Android build artifacts out of the container, use:
|
||||
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.android.base/app/build/ app/build
|
||||
|
||||
And your android applications will appear in the `app/build` directory, in the same
|
||||
place where non-container builds would go.
|
||||
|
||||
If you encounter a permissions error when rebuilding, delete the `app/build`,
|
||||
`app/pkg-mavencentral` and `app/pkg-temp` path.
|
||||
|
||||
rm -rf app/pkg-temp app/build app/pkg-mavencentral
|
||||
|
||||
Copypasta
|
||||
---------
|
||||
|
||||
Once you have set up builds for the first time, from then on you can update the container and
|
||||
build a fresh set of Maven jars and a new I2P for Android app by copy-pasting the following
|
||||
commands:
|
||||
|
||||
``` sh
|
||||
rm -rf app/pkg-temp app/build app/pkg-mavencentral
|
||||
docker build -t i2p.android.base .
|
||||
docker run -it \
|
||||
-u $(id -u):$(id -g) \
|
||||
--name i2p.android.base \
|
||||
-v $HOME/.gnupg/:/.gnupg/:ro \
|
||||
-v $HOME/.i2p-plugin-keys/:/.i2p-plugin-keys/:ro \
|
||||
-v /run/user/$(id -u)/:/run/user/$(id -u)/:ro \
|
||||
i2p.android.base
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/pkg-mavencentral app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-i2p.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-mstreaming.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-router.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-servlet-i2p.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.i2p/mavencentral-streaming.jar app/pkg-mavencentral
|
||||
docker cp i2p.android.base:/opt/workspace/i2p.android.base/app/build/ app/build
|
||||
```
|
39
Dockerfile
Normal file
39
Dockerfile
Normal file
@ -0,0 +1,39 @@
|
||||
FROM menny/android_ndk
|
||||
ENV VERSION=0.9.50
|
||||
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
|
||||
RUN echo 'deb http://deb.i2p2.de/ sid main' >> /etc/apt/sources.list
|
||||
RUN echo 'deb-src http://deb.i2p2.de/ sid main' >> /etc/apt/sources.list
|
||||
RUN echo 'deb http://archive.ubuntu.com/ubuntu trusty universe' >> /etc/apt/sources.list
|
||||
RUN wget -O /etc/apt/trusted.gpg.d/i2p-debian-repo.key.asc https://geti2p.net/_static/i2p-debian-repo.key.asc
|
||||
COPY etc/debian-jessie-repo.key.asc /etc/apt/trusted.gpg.d
|
||||
RUN mkdir -p /opt/packages && wget -O /opt/packages/openjdk-7-jre-headless.deb http://security.debian.org/debian-security/pool/updates/main/o/openjdk-7/openjdk-7-jre-headless_7u261-2.6.22-1~deb8u1_amd64.deb
|
||||
RUN apt-get update
|
||||
RUN apt-get build-dep -y i2p i2p-router
|
||||
RUN apt-get install -y ant openjdk-8* libxml2-utils junit4 libhamcrest-java libmockito-java libmaven-ant-tasks-java dpkg-sig maven
|
||||
RUN cd /opt/packages && dpkg-sig -l openjdk-7-jre-headless.deb && dpkg -x openjdk-7-jre-headless.deb /opt/packages/openjdk-7-jre
|
||||
RUN git clone https://github.com/i2p/i2p.i2p --depth=1 -b i2p-$VERSION /opt/workspace/i2p.i2p
|
||||
RUN update-java-alternatives --jre-headless --set java-1.8.0-openjdk-amd64
|
||||
RUN update-java-alternatives --set java-1.8.0-openjdk-amd64
|
||||
RUN update-alternatives --set javac /usr/lib/jvm/java-8-openjdk-amd64/bin/javac
|
||||
RUN update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
|
||||
RUN rm /opt/java/openjdk/ -rfv
|
||||
COPY . /opt/workspace/i2p.android.base
|
||||
COPY etc/docker.local.ndk.properties /opt/workspace/i2p.android.base/client/local.properties
|
||||
COPY etc/docker.local.router.properties /opt/workspace/i2p.android.base/routerjars/local.properties
|
||||
COPY etc/docker.local.sdk.properties /opt/workspace/i2p.android.base/local.properties
|
||||
COPY etc/docker.override.properties /opt/workspace/i2p.android.base/override.properties
|
||||
COPY etc/docker.override.properties /opt/workspace/i2p.i2p/override.properties
|
||||
COPY etc/docker.signing.properties /opt/workspace/i2p.android.base/signing.properties
|
||||
WORKDIR /opt/workspace/i2p.android.base
|
||||
RUN find /opt/android-sdk-linux -type d -print0 | xargs -0 chown -R 1000:1000
|
||||
RUN find /opt/android-sdk-linux -type d -print0 | xargs -0 chmod -Rc o+rw
|
||||
RUN find /opt/android-sdk-linux -type d -print0 | xargs -0 chmod -c 0755
|
||||
RUN find /opt/workspace -type d -print0 | xargs -0 chown -R 1000:1000
|
||||
RUN find /opt/workspace -type d -print0 | xargs -0 chmod -Rc o+rw
|
||||
RUN find /opt/workspace -type d -print0 | xargs -0 chmod -c 0755
|
||||
CMD cd /opt/workspace/i2p.i2p && \
|
||||
ant -k mavenCentral; \
|
||||
cp -v *.jar pkg-mavencentral/; \
|
||||
cd /opt/workspace/i2p.android.base && \
|
||||
./gradlew --continue dependencies || true ; \
|
||||
./gradlew --continue assembleRelease; tail -f README.md
|
14
README.md
14
README.md
@ -7,8 +7,8 @@
|
||||
- Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher
|
||||
- Apache Ant 1.8.0 or higher
|
||||
- I2P source
|
||||
- Android SDK for API 21
|
||||
- Android Build Tools 21.1.2
|
||||
- Android SDK for API 28 or higher
|
||||
- Android Build Tools 28.0.0 or higher
|
||||
- Android Support Repository
|
||||
- Gradle 2.2.1
|
||||
|
||||
@ -67,10 +67,18 @@ systemProp.socksProxyPort=9150
|
||||
```
|
||||
sdk.dir=/path/to/android-studio/sdk
|
||||
```
|
||||
1a. For building with a local router development build:
|
||||
cd ../i2p.i2p
|
||||
installer/resources/maven-dev-release.sh x // x is the build number, e.g. 6
|
||||
cd back here
|
||||
edit gradle.properties, add the build number x to I2P_PROPERTIES=0.9.xx-x
|
||||
|
||||
2. `gradle assembleDebug`
|
||||
|
||||
3. The APK will be placed in `i2p.android.base/app/build/outputs/apk`.
|
||||
3. The APK files will be placed in `i2p.android.base/app/build/outputs/apk` subdirectories.
|
||||
|
||||
4. Install debug build on phone in USB debugging mode
|
||||
adb install app/build/outputs/apk/free/debug/app-free-debug.apk
|
||||
|
||||
### Building with Android Studio
|
||||
|
||||
|
@ -1,20 +1,128 @@
|
||||
1. Check out a clean copy of i2p.i2p at the correct release version.
|
||||
2. Edit `routerjars/local.properties` to use the clean i2p.i2p copy.
|
||||
3. Pull the latest translations with `tx pull -a` and commit them.
|
||||
4. Ensure that `signing.properties` contains the details of the release key.
|
||||
5. Edit `gradle.properties` to bump the I2P version.
|
||||
6. Edit `app/build.gradle` to bump the Android version number.
|
||||
7. If the helper has changed since the last release, edit
|
||||
`lib/helper/gradle.properties` to bump the version.
|
||||
8. `./gradlew clean assembleRelease`
|
||||
9. `./gradlew :lib:client:uploadArchives`
|
||||
10. If the helper version was changed: `./gradlew :lib:helper:uploadArchives`
|
||||
11. Check on Sonatype that everything worked, and close/release.
|
||||
12. Update local fdroidserver repo
|
||||
13. `cp app/build/outputs/apk/free/release/app-free-release.apk path/to/fdroid/repo/I2P-VERSION.apk`
|
||||
14. Update `path/to/fdroid/metadata/net.i2p.android.txt`
|
||||
15. `fdroid update`
|
||||
16. Push to download server and put in place.
|
||||
17. Check F-Droid repo works, and app works.
|
||||
18. `mtn ci gradle.properties lib/helper/gradle.properties app/build.gradle`
|
||||
19. Push free and donate builds to Google Play.
|
||||
# Release Process
|
||||
|
||||
Note to all future maintainers: We have 4 channels that need to be updated in order to have a successful
|
||||
Android release. Many of these channels are updated at different rates, and at times you must wait on a
|
||||
third-party service to complete it's tasks before you may continue. When completing an Android release,
|
||||
keep in mind that you must update 1) Maven 2) Google Play 3) f-droid.i2p.io and 4) F-Droid main
|
||||
repository.
|
||||
|
||||
At the time of this revision, 2020/09/13, the main Android maintainer is idk. idk updates Maven, Google
|
||||
Play, and f-droid.i2p.io, and nextl00p handles working with the F-Droid project to provide an I2P release
|
||||
in their main repository.
|
||||
|
||||
NOTE: The docker container built by the Dockerfile in this repostory ensures that the Pre-requisites and
|
||||
Dependencies are properly met by obtaining them from the Debian package in `oldoldstable` and pre-configuring
|
||||
the override.properties that is used in the Docker container.
|
||||
|
||||
## Tag Freezes and Translations
|
||||
|
||||
1-2 weeks before the software is released, I2P Desktop will have a "Tag Freeze" which is the deadline for
|
||||
translations to be checked in. **When** that time comes, someone who has Transifex privileges should use
|
||||
the command: `tx push -s -R I2P.android` to push any and all changed string resources to transifex for
|
||||
translation.
|
||||
|
||||
**>> Beginning of Docker-enabled Steps <<**
|
||||
|
||||
## Prerequirements
|
||||
|
||||
0. Update the changelog!
|
||||
1. Ensure you have the deprecated maven ant tasks. ( https://maven.apache.org/ant-tasks/download.cgi )
|
||||
2. It should exist at `~/.ant/lib/maven-ant-tasks-2.1.3.jar`
|
||||
3. Ensure you have hamcrest-integration, hamcrest-library, hamcrest-core in the hamcrest.home directory.
|
||||
4. Ensure junit 4.12 at least in junit.home, ensure the jar file is named `junit4.jar`.
|
||||
5. Ensure you have the Mockito framework and accompanying documentation in your $JAVA_HOME
|
||||
6. Ensure to have updated the changelog with the changes done.
|
||||
7. Ensure that you are configured to build i2p.i2p with Java 8. On Debian it is easiest to set with
|
||||
`update-java-alternatives --set java-1.8.0-openjdk-amd64` and picking Java 8. **TODO:** add instructions for non-Debian-based
|
||||
systems.
|
||||
8. Ensure that you have a Java 1.7 bootclasspath available. (See **Maven Central** step 2A.)
|
||||
|
||||
## Get all the dependencies ready
|
||||
|
||||
### Maven Central
|
||||
|
||||
1. Check out a clean copy of i2p.i2p at the correct release version. (Make a clean checkout)
|
||||
2. Build the maven packages via `ant mavenCentral` where you end up with mavencentral-*.jar files in the
|
||||
current directory.
|
||||
2. **A)** I2P for Android requires a Java 1.7 bootclasspath, but the servlet jar requires Java 8. So, to do the builds:
|
||||
- First set `javac.compilerargs=-bootclasspath /path/to/java/7/rt.jar:/path/to/java/7/jce.jar` in override.properties
|
||||
- Build with `ant mavenCentral`
|
||||
|
||||
**>> End of Docker-enabled Steps for Maven <<**
|
||||
|
||||
3. Login to http://oss.sonatype.org for uploading the mavencentral-*.jar bundles.
|
||||
4. In nexus, choose "Staging Upload" and upload all of the files with upload mode set to "Artifacts with POM".
|
||||
When uploading the files to nexus, you *must* upload the pom.xml files, and all of their artifacts. For each
|
||||
component, you will need to upload a *.jar, a *.jar.asc, a *sources.jar, a *sources.jar.asc, a javadoc.jar,
|
||||
and a javadoc.jar.asc, and a pom.xml and a pom.xml.asc from the pkg-mavencentral directory during the "Upload
|
||||
Artifacts with POM" operation. You will need to do this once for each component you upload to Nexus.
|
||||
5. Under "Staging Repositories" ensure all where uploaded correctly, select them all and press "Release"
|
||||
in the toolbar.
|
||||
|
||||
#### Example override.properties:
|
||||
|
||||
javac.version=1.7
|
||||
javac.target=1.7
|
||||
javac.source=1.8
|
||||
javac.compilerargs=-bootclasspath /home/user/StudioProjects/java7bootclasspath/rt.jar:/home/user/StudioProjects/java7bootclasspath/jce.jar
|
||||
javac.compilerargs7=-bootclasspath /home/user/StudioProjects/java7bootclasspath/rt.jar:/home/user/StudioProjects/java7bootclasspath/jce.jar
|
||||
build.built-by=name
|
||||
|
||||
### Android Common Build
|
||||
|
||||
Using Docker: in order to use Docker to generate a new Android apk for release, you will
|
||||
need to run the build twice, once for the mavenCentral jars, and once for the actual Android
|
||||
app. After doing the Maven release, follow these steps in the i2p.android.base repository, and re-run
|
||||
the `docker run` step described in `DOCKER.md`
|
||||
|
||||
1. Edit `routerjars/local.properties` to use the clean i2p.i2p copy.
|
||||
2. Pull the latest translations with `tx pull --use-git-timestamps` and commit them. (If you don't have the `tx` command,
|
||||
do `pip install transifex-client` ). If there are broken translations, exclude them and only them.
|
||||
- If there are any new translations, `mtn add` them, and add them to `app/src/main/res/values/arrays.xml`
|
||||
(two places, alphabetical order please)
|
||||
3. Ensure that `signing.properties` contains the details of the release key. If you are using Docker, see
|
||||
`DOCKER.md` to perform this step for Docker builds by editing `etc/docker.signing.properties` instead.
|
||||
4. Edit `gradle.properties` to bump the I2P version.
|
||||
5. Edit `app/build.gradle` to bump the Android version number.
|
||||
6. Edit `CHANGELOG` to add the release and date.
|
||||
7. If the helper has changed since the last release, edit
|
||||
`lib/helper/gradle.properties` to bump the version.
|
||||
8. `./gradlew clean assembleRelease`
|
||||
|
||||
### Libraries
|
||||
|
||||
1. `./gradlew :lib:client:uploadArchives`
|
||||
2. If the helper version was changed and should be released: `./gradlew :lib:helper:uploadArchives`
|
||||
3. Check on Sonatype that everything worked, and close/release.
|
||||
|
||||
## Release Packages
|
||||
|
||||
### F-Droid Guide
|
||||
|
||||
This guide is for f-droid.i2p.io, not for F-Droid's main repository. The repository keystore **and** the
|
||||
config.py used to generate the repository are required to complete this process successfully.
|
||||
|
||||
1. Ensure you have the release keys, the keyfile must be placed at `~/.local/share/fdroidserver/keystore.jks`
|
||||
2. If it's the first time, or you have reinstalled anything, ensure `path/to/fdroid/config.py` has correct
|
||||
information.
|
||||
3. Assuming you already have ran `./gradlew clean assembleRelease` from a earlier step, continue.
|
||||
4. `cp app/build/outputs/apk/free/release/app-free-release.apk path/to/fdroid/repo/I2P-VERSION.apk`
|
||||
5. Update `path/to/fdroid/metadata/net.i2p.android.txt` (The versions at the bottom of the file)
|
||||
6. Run `fdroid update` from inside the fdroid path (install fdroid command via `pip install fdroidserver`)
|
||||
7. Zip/tar the local fdroid repo and archive. `rm fdroid.tgz && tar czf fdroid.tgz archive/ repo/` from the
|
||||
fdroid directory.
|
||||
8. Push to download server and put in place. (via SSH for example, `scp fdroid.tgz download.i2p2.de:~/`)
|
||||
9. On the server run `bin-fd/update-fdroid` and `sudo bin-fd/update-app i2p 0.9.40` (This ensures we use the
|
||||
exact same apk file for the download page as in fdroid and gplay)
|
||||
10. Check F-Droid repo works, and app works.
|
||||
|
||||
### Google Play and finishing up
|
||||
|
||||
1. Verify which files that are changed via `mtn ls cha`. It shouldn't be much more than those bellow this
|
||||
line and possible translations (`mtn ls unk`).
|
||||
2. Commit your release changes, `mtn ci gradle.properties lib/helper/gradle.properties app/build.gradle`
|
||||
3. Push free and donate builds to Google Play via https://play.google.com/apps/publish/
|
||||
4. Tag the new release. Example `mtn tag h: android-0.9.36`
|
||||
5. Push the monotone changes. Make sure that they are there at the next git sync.
|
||||
6. Update download page (version and hash, including F-Droid)
|
||||
|
||||
|
@ -1,11 +1,17 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION as String)
|
||||
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION as String)
|
||||
defaultConfig {
|
||||
versionCode 4745241
|
||||
versionName "$I2P_VERSION"
|
||||
minSdkVersion 9
|
||||
versionCode Integer.parseInt(project.I2P_ANDROID_VERSION_CODE as String)
|
||||
versionName "$I2P_ANDROID_VERSION"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION as String)
|
||||
|
||||
// For Espresso
|
||||
@ -27,14 +33,19 @@ android {
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
checkReleaseBuilds false
|
||||
disable 'MissingDefaultResource'
|
||||
}
|
||||
packagingOptions {
|
||||
exclude 'LICENSE.txt'
|
||||
resources {
|
||||
excludes += ['LICENSE.txt']
|
||||
}
|
||||
}
|
||||
flavorDimensions 'tier'
|
||||
productFlavors {
|
||||
@ -58,30 +69,36 @@ dependencies {
|
||||
implementation project(':lib:client')
|
||||
implementation project(':lib:helper')
|
||||
implementation project(path: ':routerjars', configuration: 'routerjars')
|
||||
|
||||
// Android Support Repository dependencies
|
||||
def supportVersion = '25.3.1'
|
||||
def supportVersion = '28.0.0'
|
||||
implementation "com.android.support:support-v4:$supportVersion"
|
||||
implementation "com.android.support:appcompat-v7:$supportVersion"
|
||||
implementation "com.android.support:preference-v7:$supportVersion"
|
||||
implementation "com.android.support:preference-v14:$supportVersion"
|
||||
implementation "com.android.support:recyclerview-v7:$supportVersion"
|
||||
|
||||
// Remote dependencies
|
||||
implementation 'com.androidplot:androidplot-core:1.4.1'
|
||||
implementation 'com.androidplot:androidplot-core:1.5.11'
|
||||
implementation 'com.eowise:recyclerview-stickyheaders:0.5.2@aar'
|
||||
implementation 'com.inkapplications.viewpageindicator:library:2.4.4'
|
||||
implementation 'com.inkapplications.viewpageindicator:library:2.4.3'
|
||||
implementation 'com.pnikosis:materialish-progress:1.7'
|
||||
implementation "net.i2p:router:$I2P_VERSION"
|
||||
implementation "net.i2p:i2p:$I2P_VERSION"
|
||||
implementation "net.i2p.client:mstreaming:$I2P_VERSION"
|
||||
implementation "net.i2p.client:streaming:$I2P_VERSION"
|
||||
implementation 'net.i2p.android.ext:floatingactionbutton:1.10.1'
|
||||
implementation 'org.sufficientlysecure:html-textview:3.1'
|
||||
|
||||
implementation 'com.github.SufficientlySecure:html-textview:v3.6'
|
||||
// Testing-only dependencies
|
||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2') {
|
||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.2') {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.test.espresso:espresso-core:3.6.1'
|
||||
implementation 'androidx.test.ext:junit:1.2.1'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
}
|
||||
|
||||
project.ext.i2pbase = "../i2p.i2p"
|
||||
def Properties props = new Properties()
|
||||
def propFile = new File(project(':routerjars').projectDir, 'local.properties')
|
||||
@ -108,7 +125,7 @@ task copyI2PResources(type: Copy) {
|
||||
outputs.upToDateWhen { false }
|
||||
into 'src/main/res'
|
||||
into('drawable') {
|
||||
from file(i2pbase + '/installer/resources/themes/console/images/i2plogo.png')
|
||||
from file(i2pbase + '/apps/routerconsole/jsp/themes/console/images/i2plogo.png')
|
||||
}
|
||||
into('raw') {
|
||||
from(i2pbase + '/installer/resources/blocklist.txt') { rename { 'blocklist_txt' } }
|
||||
@ -171,15 +188,15 @@ task copyI2PAssets(type: Copy) {
|
||||
outputs.upToDateWhen { false }
|
||||
into 'src/main/assets/themes/console'
|
||||
into('images') {
|
||||
from file(i2pbase + '/installer/resources/themes/console/images/i2plogo.png')
|
||||
from file(i2pbase + '/installer/resources/themes/console/images/inbound.png')
|
||||
from file(i2pbase + '/installer/resources/themes/console/images/outbound.png')
|
||||
from file(i2pbase + '/apps/routerconsole/jsp/themes/console/images/i2plogo.png')
|
||||
from file(i2pbase + '/apps/routerconsole/jsp/themes/console/images/inbound.png')
|
||||
from file(i2pbase + '/apps/routerconsole/jsp/themes/console/images/outbound.png')
|
||||
}
|
||||
into('light') {
|
||||
from file(i2pbase + '/installer/resources/themes/console/light/console.css')
|
||||
from file(i2pbase + '/apps/routerconsole/jsp/themes/console/light/console.css')
|
||||
}
|
||||
into('light/images') {
|
||||
from file(i2pbase + '/installer/resources/themes/console/light/images/header.png')
|
||||
from file(i2pbase + '/apps/routerconsole/jsp/themes/console/light/images/header.png')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,39 +1,43 @@
|
||||
package net.i2p.android;
|
||||
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import androidx.test.core.app.ActivityScenario;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
|
||||
import static android.support.test.espresso.Espresso.closeSoftKeyboard;
|
||||
import static android.support.test.espresso.Espresso.onView;
|
||||
import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
|
||||
import static android.support.test.espresso.Espresso.pressBack;
|
||||
import static android.support.test.espresso.action.ViewActions.click;
|
||||
import static android.support.test.espresso.action.ViewActions.swipeLeft;
|
||||
import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
|
||||
import static android.support.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.hasSibling;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static androidx.test.espresso.Espresso.closeSoftKeyboard;
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
|
||||
import static androidx.test.espresso.Espresso.pressBack;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.action.ViewActions.swipeLeft;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.hasSibling;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public class I2PActivityTest extends ActivityInstrumentationTestCase2<I2PActivity> {
|
||||
public I2PActivityTest() {
|
||||
super(I2PActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
// For each test method invocation, the Activity will not actually be created
|
||||
// until the first time this method is called.
|
||||
getActivity();
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class I2PActivityTest {
|
||||
|
||||
private ActivityScenario<I2PActivity> scenario;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
scenario = ActivityScenario.launch(I2PActivity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMainTabs() {
|
||||
onView(withId(R.id.router_onoff_button)).check(matches(isDisplayed()));
|
||||
|
||||
@ -55,6 +59,7 @@ public class I2PActivityTest extends ActivityInstrumentationTestCase2<I2PActivit
|
||||
onView(withId(R.id.router_onoff_button)).check(matches(isDisplayed()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMainSwipe() {
|
||||
onView(withId(R.id.router_onoff_button)).check(matches(isDisplayed()));
|
||||
|
||||
@ -70,9 +75,10 @@ public class I2PActivityTest extends ActivityInstrumentationTestCase2<I2PActivit
|
||||
// TODO: test addressbook ViewPager
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingsNavigation() {
|
||||
// Open settings menu
|
||||
openActionBarOverflowOrOptionsMenu(getActivity());
|
||||
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());
|
||||
onView(withText(R.string.menu_settings)).perform(click());
|
||||
|
||||
// Open bandwidth page
|
||||
@ -106,4 +112,4 @@ public class I2PActivityTest extends ActivityInstrumentationTestCase2<I2PActivit
|
||||
pressBack();
|
||||
onView(withText(R.string.settings_label_advanced)).check(doesNotExist());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.i2p.android.router"
|
||||
android:installLocation="auto">
|
||||
android:installLocation="auto"
|
||||
android:sharedUserId="net.i2p">
|
||||
|
||||
<uses-sdk xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:overrideLibrary="android.support.v14.preference" />
|
||||
@ -9,6 +10,16 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
||||
<!-- following two are for UPnP -->
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||
<!-- required for reliable core functionality on Android, see:
|
||||
https://geti2p.net/en/docs/applications/embedding
|
||||
heading: "Design for and Encourage Long Uptimes"
|
||||
-->
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher_itoopie"
|
||||
@ -17,7 +28,12 @@
|
||||
<service
|
||||
android:name=".service.RouterService"
|
||||
android:icon="@drawable/ic_launcher_itoopie"
|
||||
android:label="@string/app_name">
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:foregroundServiceType="specialUse">
|
||||
<property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
android:value="i2p_router_background_process_required_network_operation"/>
|
||||
<intent-filter>
|
||||
<action android:name="net.i2p.android.router.service.IRouterState" />
|
||||
</intent-filter>
|
||||
@ -25,17 +41,28 @@
|
||||
<provider
|
||||
android:name=".provider.CacheProvider"
|
||||
android:authorities="${applicationId}.provider" />
|
||||
<receiver android:name=".receiver.OnBootReceiver">
|
||||
<receiver
|
||||
android:name=".receiver.OnBootReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".receiver.RemoteStartReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="net.i2p.android.router.receiver.START_I2P" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name="net.i2p.android.I2PActivity"
|
||||
android:icon="@drawable/ic_launcher_itoopie"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop">
|
||||
android:launchMode="singleTop"
|
||||
android:exported="true">
|
||||
<!-- Console filters -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -45,6 +72,10 @@
|
||||
<action android:name="net.i2p.android.router.START_I2P" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="net.i2p.android.router.service.APPROVE_SAM" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Addressbook filters -->
|
||||
<intent-filter>
|
||||
@ -95,6 +126,7 @@
|
||||
<activity
|
||||
android:name=".web.WebActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="true"
|
||||
android:label="I2P Web Browser">
|
||||
<!-- Disabled, this browser is not very secure
|
||||
Temporarily enabled until an alternative browser is ready -->
|
||||
|
@ -31,6 +31,13 @@ public class CustomViewPager extends ViewPager {
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
// See Nov. 20, 2013 comment at:
|
||||
// https://github.com/JakeWharton/ViewPagerIndicator/pull/257
|
||||
// Our ticket #2488
|
||||
|
||||
// prevent NPE if fake dragging and touching ViewPager
|
||||
if(isFakeDragging()) return false;
|
||||
|
||||
return mEnabled && mFixedPage < 0 && super.onInterceptTouchEvent(event);
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,8 @@ public class MaterialSeekBarController implements SeekBar.OnSeekBarChangeListene
|
||||
}
|
||||
|
||||
private void setPaddedValue(int value) {
|
||||
mSeekBarValue.setText(String.format("%0" + mMaxDigits +"d", value));
|
||||
//mSeekBarValue.setText(String.format("%0" + mMaxDigits +"d", value));
|
||||
mSeekBarValue.setText(String.format("%" + mMaxDigits +"d", value));
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ import net.i2p.android.router.MainFragment;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.SettingsActivity;
|
||||
import net.i2p.android.router.addressbook.AddressbookContainer;
|
||||
import net.i2p.android.router.service.AndroidSAMSecureSession;
|
||||
import net.i2p.android.router.service.RouterService;
|
||||
import net.i2p.android.router.service.State;
|
||||
import net.i2p.android.router.util.Connectivity;
|
||||
@ -134,6 +135,7 @@ public class I2PActivity extends I2PActivityBase implements
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
setIntent(intent);
|
||||
handleIntents();
|
||||
}
|
||||
|
||||
@ -143,17 +145,29 @@ public class I2PActivity extends I2PActivityBase implements
|
||||
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
Util.d("handleIntent: intent=" + intent.toString());
|
||||
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
Util.d("handleIntent: action=" + action);
|
||||
|
||||
Bundle extra = intent.getExtras();
|
||||
if (extra != null)
|
||||
Util.d("handleIntent extra=" + extra.toString());
|
||||
|
||||
switch (action) {
|
||||
case "net.i2p.android.router.START_I2P":
|
||||
if (mViewPager.getCurrentItem() != 0)
|
||||
mViewPager.setCurrentItem(0, false);
|
||||
autoStart();
|
||||
break;
|
||||
|
||||
case "net.i2p.android.router.service.APPROVE_SAM":
|
||||
Util.w("Affirmed SAM Connection");
|
||||
String ID = extra.getString("ID");
|
||||
Util.d("SAM ID was: " + ID);
|
||||
AndroidSAMSecureSession.affirmResult(ID);
|
||||
break;
|
||||
case Intent.ACTION_PICK:
|
||||
mViewPager.setFixedPage(2, R.string.select_an_address);
|
||||
break;
|
||||
|
@ -35,6 +35,7 @@ class InitActivities {
|
||||
public InitActivities(Context c) {
|
||||
ctx = c;
|
||||
myDir = Util.getFileDir(c);
|
||||
Util.i("My app directory is "+myDir);
|
||||
_ourVersion = Util.getOurVersion(c);
|
||||
}
|
||||
|
||||
@ -59,90 +60,89 @@ class InitActivities {
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
Util.i("Initializing the I2P resources");
|
||||
|
||||
if (checkNewVersion()) {
|
||||
List<Properties> lProps = Util.getPropertiesFromPreferences(ctx);
|
||||
Properties props = lProps.get(0);
|
||||
List<Properties> lProps = Util.getPropertiesFromPreferences(ctx);
|
||||
Properties props = lProps.get(0);
|
||||
|
||||
props.setProperty("i2p.dir.temp", myDir + "/tmp");
|
||||
props.setProperty("i2p.dir.pid", myDir + "/tmp");
|
||||
// Time disabled in default router.config
|
||||
// But lots of time problems on Android, not all carriers support NITZ
|
||||
// and there was no NTP before 3.0. Tablets should be fine?
|
||||
// Phones in airplane mode with wifi enabled still a problem.
|
||||
// Deactivated phones in airplane mode definitely won't have correct time.
|
||||
if (Build.VERSION.SDK_INT < 11) // Honeycomb 3.0
|
||||
props.setProperty("time.disabled", "false");
|
||||
mergeResourceToFile(R.raw.router_config, "router.config", props);
|
||||
mergeResourceToFile(R.raw.logger_config, "logger.config", lProps.get(1));
|
||||
// This is not needed for now, i2ptunnel.config only contains tunnel
|
||||
// settings, which can now be configured manually. We don't want to
|
||||
// overwrite the user's tunnels.
|
||||
//mergeResourceToFile(R.raw.i2ptunnel_config, "i2ptunnel.config", null);
|
||||
copyResourceToFileIfAbsent(R.raw.i2ptunnel_config, "i2ptunnel.config");
|
||||
// FIXME this is a memory hog to merge this way
|
||||
mergeResourceToFile(R.raw.hosts_txt, "hosts.txt", null);
|
||||
mergeResourceToFile(R.raw.more_hosts_txt, "hosts.txt", null);
|
||||
copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt");
|
||||
props.setProperty("i2p.dir.temp", myDir + "/tmp");
|
||||
props.setProperty("i2p.dir.pid", myDir + "/tmp");
|
||||
// Time disabled in default router.config
|
||||
// But lots of time problems on Android, not all carriers support NITZ
|
||||
// and there was no NTP before 3.0. Tablets should be fine?
|
||||
// Phones in airplane mode with wifi enabled still a problem.
|
||||
// Deactivated phones in airplane mode definitely won't have correct time.
|
||||
if (Build.VERSION.SDK_INT < 11) // Honeycomb 3.0
|
||||
props.setProperty("time.disabled", "false");
|
||||
mergeResourceToFile(R.raw.router_config, "router.config", props);
|
||||
mergeResourceToFile(R.raw.logger_config, "logger.config", lProps.get(1));
|
||||
// This is not needed for now, i2ptunnel.config only contains tunnel
|
||||
// settings, which can now be configured manually. We don't want to
|
||||
// overwrite the user's tunnels.
|
||||
//mergeResourceToFile(R.raw.i2ptunnel_config, "i2ptunnel.config", null);
|
||||
copyResourceToFileIfAbsent(R.raw.i2ptunnel_config, "i2ptunnel.config");
|
||||
// FIXME this is a memory hog to merge this way
|
||||
mergeResourceToFile(R.raw.hosts_txt, "hosts.txt", null);
|
||||
mergeResourceToFile(R.raw.more_hosts_txt, "hosts.txt", null);
|
||||
copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt");
|
||||
|
||||
File abDir = new File(myDir, "addressbook");
|
||||
abDir.mkdir();
|
||||
copyResourceToFile(R.raw.subscriptions_txt, "addressbook/subscriptions.txt");
|
||||
mergeResourceToFile(R.raw.addressbook_config_txt, "addressbook/config.txt", null);
|
||||
File abDir = new File(myDir, "addressbook");
|
||||
abDir.mkdir();
|
||||
copyResourceToFileIfAbsent(R.raw.subscriptions_txt, "addressbook/subscriptions.txt");
|
||||
mergeResourceToFile(R.raw.addressbook_config_txt, "addressbook/config.txt", null);
|
||||
|
||||
File docsDir = new File(myDir, "docs");
|
||||
docsDir.mkdir();
|
||||
copyResourceToFile(R.raw.ahelper_conflict_header_ht, "docs/ahelper-conflict-header.ht");
|
||||
copyResourceToFile(R.raw.ahelper_new_header_ht, "docs/ahelper-new-header.ht");
|
||||
copyResourceToFile(R.raw.ahelper_notfound_header_ht, "docs/ahelper-notfound-header.ht");
|
||||
copyResourceToFile(R.raw.auth_header_ht, "docs/auth-header.ht");
|
||||
copyResourceToFile(R.raw.baduri_header_ht, "docs/baduri-header.ht");
|
||||
copyResourceToFile(R.raw.denied_header_ht, "docs/denied-header.ht");
|
||||
copyResourceToFile(R.raw.dnf_header_ht, "docs/dnf-header.ht");
|
||||
copyResourceToFile(R.raw.dnfb_header_ht, "docs/dnfb-header.ht");
|
||||
copyResourceToFile(R.raw.dnfh_header_ht, "docs/dnfh-header.ht");
|
||||
copyResourceToFile(R.raw.dnfp_header_ht, "docs/dnfp-header.ht");
|
||||
copyResourceToFile(R.raw.enc_header_ht, "docs/enc-header.ht");
|
||||
copyResourceToFile(R.raw.encp_header_ht, "docs/encp-header.ht");
|
||||
copyResourceToFile(R.raw.localhost_header_ht, "docs/localhost-header.ht");
|
||||
copyResourceToFile(R.raw.nols_header_ht, "docs/nols-header.ht");
|
||||
copyResourceToFile(R.raw.nolsp_header_ht, "docs/nolsp-header.ht");
|
||||
copyResourceToFile(R.raw.noproxy_header_ht, "docs/noproxy-header.ht");
|
||||
copyResourceToFile(R.raw.protocol_header_ht, "docs/protocol-header.ht");
|
||||
copyResourceToFile(R.raw.reset_header_ht, "docs/reset-header.ht");
|
||||
copyResourceToFile(R.raw.resetp_header_ht, "docs/resetp-header.ht");
|
||||
File docsDir = new File(myDir, "docs");
|
||||
docsDir.mkdir();
|
||||
/*copyResourceToFile(R.raw.ahelper_conflict_header_ht, "docs/ahelper-conflict-header.ht");
|
||||
copyResourceToFile(R.raw.ahelper_new_header_ht, "docs/ahelper-new-header.ht");
|
||||
copyResourceToFile(R.raw.ahelper_notfound_header_ht, "docs/ahelper-notfound-header.ht");
|
||||
copyResourceToFile(R.raw.auth_header_ht, "docs/auth-header.ht");
|
||||
copyResourceToFile(R.raw.baduri_header_ht, "docs/baduri-header.ht");
|
||||
copyResourceToFile(R.raw.denied_header_ht, "docs/denied-header.ht");
|
||||
copyResourceToFile(R.raw.dnf_header_ht, "docs/dnf-header.ht");
|
||||
copyResourceToFile(R.raw.dnfb_header_ht, "docs/dnfb-header.ht");
|
||||
copyResourceToFile(R.raw.dnfh_header_ht, "docs/dnfh-header.ht");
|
||||
copyResourceToFile(R.raw.dnfp_header_ht, "docs/dnfp-header.ht");
|
||||
copyResourceToFile(R.raw.enc_header_ht, "docs/enc-header.ht");
|
||||
copyResourceToFile(R.raw.encp_header_ht, "docs/encp-header.ht");
|
||||
copyResourceToFile(R.raw.localhost_header_ht, "docs/localhost-header.ht");
|
||||
copyResourceToFile(R.raw.nols_header_ht, "docs/nols-header.ht");
|
||||
copyResourceToFile(R.raw.nolsp_header_ht, "docs/nolsp-header.ht");
|
||||
copyResourceToFile(R.raw.noproxy_header_ht, "docs/noproxy-header.ht");
|
||||
copyResourceToFile(R.raw.protocol_header_ht, "docs/protocol-header.ht");
|
||||
copyResourceToFile(R.raw.reset_header_ht, "docs/reset-header.ht");
|
||||
copyResourceToFile(R.raw.resetp_header_ht, "docs/resetp-header.ht");*/
|
||||
|
||||
File cssDir = new File(docsDir, "themes/console/light");
|
||||
cssDir.mkdirs();
|
||||
//copyResourceToFile(R.raw.console_css, "docs/themes/console/light/console.css");
|
||||
//copyResourceToFile(R.raw.android_css, "docs/themes/console/light/android.css");
|
||||
File cssDir = new File(docsDir, "themes/console/light");
|
||||
cssDir.mkdirs();
|
||||
//copyResourceToFile(R.raw.console_css, "docs/themes/console/light/console.css");
|
||||
//copyResourceToFile(R.raw.android_css, "docs/themes/console/light/android.css");
|
||||
|
||||
File imgDir = new File(docsDir, "themes/console/images");
|
||||
imgDir.mkdir();
|
||||
copyResourceToFile(R.drawable.i2plogo, "docs/themes/console/images/i2plogo.png");
|
||||
copyResourceToFile(R.drawable.itoopie_sm, "docs/themes/console/images/itoopie_sm.png");
|
||||
//copyResourceToFile(R.drawable.outbound, "docs/themes/console/images/outbound.png");
|
||||
//copyResourceToFile(R.drawable.inbound, "docs/themes/console/images/inbound.png");
|
||||
File imgDir = new File(docsDir, "themes/console/images");
|
||||
imgDir.mkdir();
|
||||
copyResourceToFile(R.drawable.i2plogo, "docs/themes/console/images/i2plogo.png");
|
||||
copyResourceToFile(R.drawable.itoopie_sm, "docs/themes/console/images/itoopie_sm.png");
|
||||
//copyResourceToFile(R.drawable.outbound, "docs/themes/console/images/outbound.png");
|
||||
//copyResourceToFile(R.drawable.inbound, "docs/themes/console/images/inbound.png");
|
||||
|
||||
File img2Dir = new File(cssDir, "images");
|
||||
img2Dir.mkdir();
|
||||
//copyResourceToFile(R.drawable.header, "docs/themes/console/light/images/header.png");
|
||||
File img2Dir = new File(cssDir, "images");
|
||||
img2Dir.mkdir();
|
||||
//copyResourceToFile(R.drawable.header, "docs/themes/console/light/images/header.png");
|
||||
|
||||
File certDir = new File(myDir, "certificates");
|
||||
certDir.mkdir();
|
||||
File certificates = new File(myDir, "certificates");
|
||||
File[] allcertificates = certificates.listFiles();
|
||||
if ( allcertificates != null) {
|
||||
for (File f : allcertificates) {
|
||||
Util.d("Deleting old certificate file/dir " + f);
|
||||
FileUtil.rmdir(f, false);
|
||||
}
|
||||
File certDir = new File(myDir, "certificates");
|
||||
certDir.mkdir();
|
||||
File certificates = new File(myDir, "certificates");
|
||||
File[] allCertificates = certificates.listFiles();
|
||||
if ( allCertificates != null) {
|
||||
for (File f : allCertificates) {
|
||||
Util.d("Deleting old certificate file/dir " + f);
|
||||
FileUtil.rmdir(f, false);
|
||||
}
|
||||
unzipResourceToDir(R.raw.certificates_zip, "certificates");
|
||||
//File netDBDir = new File(myDir, "netDB");
|
||||
//netDBDir.mkdir();
|
||||
//unzipResourceToDir(R.raw.netdb_zip, "netDB");
|
||||
}
|
||||
File netDBDir = new File(myDir, "netDB");
|
||||
netDBDir.mkdir();
|
||||
//unzipResourceToDir(R.raw.netdb_zip, "netDB");
|
||||
unzipResourceToDir(R.raw.certificates_zip, "certificates");
|
||||
|
||||
// Set up the locations so settings can find them
|
||||
System.setProperty("i2p.dir.base", myDir);
|
||||
@ -178,10 +178,16 @@ class InitActivities {
|
||||
out.write(buf, 0, read);
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Util.e("copyResourceToFile" + "IOE: ", ioe);
|
||||
} catch (Resources.NotFoundException nfe) {
|
||||
Util.e("copyResourceToFile" + "NFE: ", nfe);
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
if (out != null) try { out.close(); } catch (IOException ioe) {}
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {
|
||||
Util.e("copyResourceToFile" + "IOE in.close(): ", ioe);
|
||||
}
|
||||
if (out != null) try { out.close(); } catch (IOException ioe) {
|
||||
Util.e("copyResourceToFile" + "IOE out.close(): ", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -192,7 +198,7 @@ class InitActivities {
|
||||
FileOutputStream out = null;
|
||||
ZipInputStream zis = null;
|
||||
|
||||
Util.d("Creating files in '" + myDir + "/" + folder + "/' from resource");
|
||||
Util.i("Creating files in '" + myDir + "/" + folder + "/' from resource");
|
||||
try {
|
||||
// Context methods
|
||||
in = ctx.getResources().openRawResource(resID);
|
||||
@ -200,6 +206,7 @@ class InitActivities {
|
||||
ZipEntry ze;
|
||||
while ((ze = zis.getNextEntry()) != null) {
|
||||
out = null;
|
||||
Util.i("unzipping "+ze);
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
@ -209,26 +216,51 @@ class InitActivities {
|
||||
}
|
||||
String name = ze.getName();
|
||||
File f = new File(myDir + "/" + folder +"/" + name);
|
||||
if (ze.isDirectory()) {
|
||||
Util.d("Creating directory " + myDir + "/" + folder +"/" + name + " from resource");
|
||||
String canonicalPath = f.getCanonicalPath().replace("/user/0/", "/data/");
|
||||
// account for canonical path differences when using .aab bundles
|
||||
if (!canonicalPath.startsWith(myDir.replace("/user/0/", "/data/"))) {
|
||||
// If these don't match, there's a path-traversal possibility.
|
||||
// So ignore it.
|
||||
Util.e("Path mismatch bug " + canonicalPath.toString() + " " + myDir.toString());
|
||||
} else if (ze.isDirectory()) {
|
||||
Util.i("Creating directory " + myDir + "/" + folder +"/" + name + " from resource");
|
||||
f.mkdir();
|
||||
} else {
|
||||
Util.d("Creating file " + myDir + "/" + folder +"/" + name + " from resource");
|
||||
Util.i("Creating file " + myDir + "/" + folder +"/" + name + " from resource");
|
||||
//create all the leading directories
|
||||
File newFile = new File(myDir+"/"+folder+"/"+name);
|
||||
newFile.getParentFile().mkdirs();
|
||||
byte[] bytes = baos.toByteArray();
|
||||
out = new FileOutputStream(f);
|
||||
out.write(bytes);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
Util.e("unzipResourceToDir" + "IOE: ", ioe);
|
||||
} finally {
|
||||
if (out != null) { try { out.close(); } catch (IOException ioe) {} out = null; }
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
Util.e("unzipResourceToDir" + "IOE: interior out.close ", ioe);
|
||||
}
|
||||
out = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
Util.e("unzipResourceToDir" + "IOE: ", ioe);
|
||||
} catch (Resources.NotFoundException nfe) {
|
||||
Util.e("unzipResourceToDir" + "NFE: ", nfe);
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
if (out != null) try { out.close(); } catch (IOException ioe) {}
|
||||
if (zis != null) try { zis.close(); } catch (IOException ioe) {}
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {
|
||||
Util.e("unzipResourceToDir" + "IOE: in.close() ", ioe);
|
||||
}
|
||||
if (out != null) try { out.close(); } catch (IOException ioe) {
|
||||
Util.e("unzipResourceToDir" + "IOE: out.close() ", ioe);
|
||||
}
|
||||
if (zis != null) try { zis.close(); } catch (IOException ioe) {
|
||||
Util.e("unzipResourceToDir" + "IOE: zis.close() ", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,18 +284,31 @@ class InitActivities {
|
||||
private boolean checkNewVersion() {
|
||||
Properties props = new Properties();
|
||||
|
||||
Util.i("Checking for a new install/version");
|
||||
InputStream fin = null;
|
||||
try {
|
||||
fin = ctx.openFileInput(CONFIG_FILE);
|
||||
DataHelper.loadProps(props, fin);
|
||||
} catch (IOException ioe) {
|
||||
Util.d("Looks like a new install");
|
||||
Util.i("Looks like a new install");
|
||||
} finally {
|
||||
if (fin != null) try { fin.close(); } catch (IOException ioe) {}
|
||||
if (fin != null) {
|
||||
try {
|
||||
Util.i("fin was not null "+CONFIG_FILE);
|
||||
fin.close();
|
||||
} catch (IOException ioe) {
|
||||
Util.i("Error loading config:", ioe);
|
||||
}
|
||||
}else {
|
||||
Util.i("fin was null");
|
||||
}
|
||||
}
|
||||
|
||||
String oldVersion = props.getProperty(PROP_INSTALLED_VERSION);
|
||||
Util.i("Old version is:"+oldVersion);
|
||||
boolean newInstall = oldVersion == null;
|
||||
if (newInstall)
|
||||
return true;
|
||||
boolean newVersion = !_ourVersion.equals(oldVersion);
|
||||
|
||||
if (newVersion) {
|
||||
|
@ -5,6 +5,8 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.EepGet;
|
||||
@ -83,7 +85,7 @@ public class EepGetFetcher implements EepGet.StatusListener {
|
||||
int semi = rv.indexOf(";");
|
||||
if (semi > 0)
|
||||
rv = rv.substring(0, semi);
|
||||
return rv.toLowerCase();
|
||||
return rv.toLowerCase(Locale.US);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,22 +1,41 @@
|
||||
package net.i2p.android.apps;
|
||||
|
||||
import static net.i2p.app.ClientAppState.INITIALIZED;
|
||||
import static net.i2p.app.ClientAppState.RUNNING;
|
||||
import static net.i2p.app.ClientAppState.STARTING;
|
||||
import static net.i2p.app.ClientAppState.STOPPED;
|
||||
import static net.i2p.app.ClientAppState.STOPPING;
|
||||
import static net.i2p.app.ClientAppState.UNINITIALIZED;
|
||||
import static net.i2p.update.UpdateType.BLOCKLIST;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import net.i2p.android.router.NewsActivity;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.Notifications;
|
||||
import net.i2p.app.ClientApp;
|
||||
import net.i2p.app.ClientAppManager;
|
||||
import net.i2p.app.ClientAppState;
|
||||
import net.i2p.crypto.SU3File;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.Banlist;
|
||||
import net.i2p.router.Blocklist;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.news.BlocklistEntries;
|
||||
import net.i2p.router.news.NewsEntry;
|
||||
import net.i2p.router.news.NewsMetadata;
|
||||
import net.i2p.router.news.NewsXMLParser;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.EepGet;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.ReusableGZIPInputStream;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.RFC822Date;
|
||||
import net.i2p.util.ReusableGZIPInputStream;
|
||||
import net.i2p.util.SecureFile;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
@ -27,13 +46,17 @@ import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* From router console, simplified since we don't deal with router versions
|
||||
* or updates.
|
||||
*
|
||||
* As of 0.9.41, implements ClientApp to hang us off the ClientAppManager,
|
||||
* so we can remove the static reference.
|
||||
*/
|
||||
public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
public class NewsFetcher implements Runnable, EepGet.StatusListener, ClientApp {
|
||||
private final Context mCtx;
|
||||
private final RouterContext _context;
|
||||
private final Notifications _notif;
|
||||
@ -44,20 +67,22 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
private boolean _invalidated;
|
||||
private File _newsFile;
|
||||
private File _tempFile;
|
||||
private static NewsFetcher _instance;
|
||||
private volatile boolean _isRunning = true;
|
||||
private Thread _thread;
|
||||
private final ClientAppManager _mgr;
|
||||
private volatile ClientAppState _state = UNINITIALIZED;
|
||||
public static final String APP_NAME = "NewsFetcher";
|
||||
|
||||
public static /*final */ NewsFetcher getInstance() {
|
||||
return _instance;
|
||||
}
|
||||
static final String PROP_BLOCKLIST_TIME = "router.blocklistVersion";
|
||||
private static final String BLOCKLIST_DIR = "docs/feed/blocklist";
|
||||
private static final String BLOCKLIST_FILE = "blocklist.txt";
|
||||
|
||||
/**
|
||||
* As of 0.9.41, returns a new one every time. Only call once.
|
||||
*/
|
||||
public static /* final */ synchronized NewsFetcher getInstance(
|
||||
Context context, RouterContext ctx, Notifications notif) {
|
||||
if (_instance != null)
|
||||
return _instance;
|
||||
_instance = new NewsFetcher(context, ctx, notif);
|
||||
return _instance;
|
||||
return new NewsFetcher(context, ctx, notif);
|
||||
}
|
||||
|
||||
private static final String NEWS_DIR = "docs";
|
||||
@ -71,18 +96,17 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
*
|
||||
* @since 0.7.14 not configurable
|
||||
*/
|
||||
private static final String BACKUP_NEWS_URL_SU3 = "http://avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a.b32.i2p/news.su3";
|
||||
private static final String BACKUP_NEWS_URL_SU3 = "http://dn3tvalnjz432qkqsvpfdqrwpqkw3ye4n4i2uyfr4jexvo3sp5ka.b32.i2p/news/news.su3";
|
||||
private static final String PROP_LAST_CHECKED = "router.newsLastChecked";
|
||||
private static final String PROP_REFRESH_FREQUENCY = "router.newsRefreshFrequency";
|
||||
private static final String DEFAULT_REFRESH_FREQUENCY = 24 * 60 * 60 * 1000 + "";
|
||||
private static final String PROP_NEWS_URL = "router.newsURL";
|
||||
public static final String DEFAULT_NEWS_URL_SU3 = "http://echelon.i2p/news/news.su3";
|
||||
public static final String DEFAULT_NEWS_URL_SU3 = "http://tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq.b32.i2p/news.su3";
|
||||
|
||||
private NewsFetcher(Context context, RouterContext ctx, Notifications notif) {
|
||||
mCtx = context;
|
||||
_context = ctx;
|
||||
_notif = notif;
|
||||
_context.addShutdownTask(new Shutdown());
|
||||
_log = ctx.logManager().getLog(NewsFetcher.class);
|
||||
try {
|
||||
String last = ctx.getProperty(PROP_LAST_CHECKED);
|
||||
@ -96,6 +120,9 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
_newsFile = new File(newsDir, NEWS_FILE);
|
||||
_tempFile = new File(_context.getTempDir(), TEMP_NEWS_FILE);
|
||||
updateLastFetched();
|
||||
_mgr = ctx.clientAppManager();
|
||||
changeState(INITIALIZED);
|
||||
_mgr.register(this);
|
||||
}
|
||||
|
||||
private void updateLastFetched() {
|
||||
@ -134,7 +161,17 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
private static final long RUN_DELAY = 30 * 60 * 1000;
|
||||
|
||||
public void run() {
|
||||
_thread = Thread.currentThread();
|
||||
changeState(RUNNING);
|
||||
try {
|
||||
run2();
|
||||
} finally {
|
||||
_mgr.unregister(this);
|
||||
changeState(STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void run2() {
|
||||
try {
|
||||
Thread.sleep(INITIAL_DELAY);
|
||||
} catch (InterruptedException ie) {
|
||||
@ -276,14 +313,6 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
public void attempting(String url) {
|
||||
}
|
||||
|
||||
private class Shutdown implements Runnable {
|
||||
public void run() {
|
||||
_isRunning = false;
|
||||
if (_thread != null)
|
||||
_thread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SU3 handlers
|
||||
//
|
||||
@ -323,6 +352,11 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
xml.delete();
|
||||
NewsMetadata data = parser.getMetadata();
|
||||
List<NewsEntry> entries = parser.getEntries();
|
||||
BlocklistEntries ble = parser.getBlocklistEntries();
|
||||
if (ble != null && ble.isVerified())
|
||||
processBlocklistEntries(ble);
|
||||
else
|
||||
_log.info("No blocklist entries found in news feed");
|
||||
String sudVersion = su3.getVersionString();
|
||||
String signingKeyName = su3.getSignerString();
|
||||
File to3 = new File(_context.getTempDir(), "tmp3-" + _context.random().nextInt() + ".xml");
|
||||
@ -333,6 +367,104 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process blocklist entries
|
||||
*
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private void processBlocklistEntries(BlocklistEntries ble) {
|
||||
long oldTime = _context.getProperty(PROP_BLOCKLIST_TIME, 0L);
|
||||
if (ble.updated <= oldTime) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Not processing blocklist " + DataHelper.formatDate(ble.updated) +
|
||||
", already have " + DataHelper.formatDate(oldTime));
|
||||
return;
|
||||
}
|
||||
Blocklist bl = _context.blocklist();
|
||||
Banlist ban = _context.banlist();
|
||||
String reason = "Blocklist feed " + DataHelper.formatDate(ble.updated);
|
||||
int banned = 0;
|
||||
for (Iterator<String> iter = ble.entries.iterator(); iter.hasNext(); ) {
|
||||
String s = iter.next();
|
||||
if (s.length() == 44) {
|
||||
byte[] b = Base64.decode(s);
|
||||
if (b == null || b.length != Hash.HASH_LENGTH) {
|
||||
iter.remove();
|
||||
continue;
|
||||
}
|
||||
Hash h = Hash.create(b);
|
||||
if (!ban.isBanlistedForever(h)) {
|
||||
ban.banlistRouterForever(h, reason);
|
||||
_context.commSystem().forceDisconnect(h);
|
||||
}
|
||||
} else {
|
||||
byte[] ip = Addresses.getIP(s);
|
||||
if (ip == null) {
|
||||
iter.remove();
|
||||
continue;
|
||||
}
|
||||
if (!bl.isBlocklisted(ip))
|
||||
bl.add(ip);
|
||||
}
|
||||
if (++banned >= BlocklistEntries.MAX_ENTRIES) {
|
||||
// prevent somebody from destroying the whole network
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (String s : ble.removes) {
|
||||
if (s.length() == 44) {
|
||||
byte[] b = Base64.decode(s);
|
||||
if (b == null || b.length != Hash.HASH_LENGTH)
|
||||
continue;
|
||||
Hash h = Hash.create(b);
|
||||
if (ban.isBanlistedForever(h))
|
||||
ban.unbanlistRouter(h);
|
||||
} else {
|
||||
byte[] ip = Addresses.getIP(s);
|
||||
if (ip == null)
|
||||
continue;
|
||||
if (bl.isBlocklisted(ip))
|
||||
bl.remove(ip);
|
||||
}
|
||||
}
|
||||
// Save the blocks. We do not save the unblocks.
|
||||
File f = new SecureFile(_context.getConfigDir(), BLOCKLIST_DIR);
|
||||
f.mkdirs();
|
||||
f = new File(f, BLOCKLIST_FILE);
|
||||
boolean fail = false;
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(f), "UTF-8"));
|
||||
out.write("# ");
|
||||
out.write(ble.supdated);
|
||||
out.newLine();
|
||||
banned = 0;
|
||||
for (String s : ble.entries) {
|
||||
s = s.replace(':', ';'); // IPv6
|
||||
out.write(reason);
|
||||
out.write(':');
|
||||
out.write(s);
|
||||
out.newLine();
|
||||
if (++banned >= BlocklistEntries.MAX_ENTRIES)
|
||||
break;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Error writing blocklist", ioe);
|
||||
fail = true;
|
||||
} finally {
|
||||
if (out != null) try {
|
||||
out.close();
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
if (!fail) {
|
||||
f.setLastModified(ble.updated);
|
||||
String upd = Long.toString(ble.updated);
|
||||
_context.router().saveConfig(PROP_BLOCKLIST_TIME, upd);
|
||||
}
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Processed " + ble.entries.size() + " blocks and " + ble.removes.size() + " unblocks from news feed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gunzip the file
|
||||
*
|
||||
@ -417,4 +549,69 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
////// begin ClientApp interface
|
||||
|
||||
/**
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public synchronized void startup() {
|
||||
changeState(STARTING);
|
||||
_thread = new I2PAppThread(this, "NewsFetcher", true);
|
||||
_thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public synchronized void shutdown(String[] args) {
|
||||
if (_state != RUNNING)
|
||||
return;
|
||||
changeState(STOPPING);
|
||||
_isRunning = false;
|
||||
if (_thread != null)
|
||||
_thread.interrupt();
|
||||
changeState(STOPPED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public ClientAppState getState() {
|
||||
return _state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public String getName() {
|
||||
return APP_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return APP_NAME;
|
||||
}
|
||||
|
||||
////// end ClientApp interface
|
||||
////// begin ClientApp helpers
|
||||
|
||||
/**
|
||||
* @since 0.9.41
|
||||
*/
|
||||
private void changeState(ClientAppState state) {
|
||||
changeState(state, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.41
|
||||
*/
|
||||
private synchronized void changeState(ClientAppState state, Exception e) {
|
||||
_state = state;
|
||||
_mgr.notify(this, state, null, e);
|
||||
}
|
||||
|
||||
////// end ClientApp helpers
|
||||
}
|
||||
|
@ -1,19 +1,26 @@
|
||||
package net.i2p.android.help;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class Browser implements Comparable<Browser> {
|
||||
public final String packageName;
|
||||
public final CharSequence label;
|
||||
public final Drawable icon;
|
||||
public final boolean isInstalled;
|
||||
public final boolean isKnown;
|
||||
public final boolean isSupported;
|
||||
public final boolean isRecommended;
|
||||
|
||||
private boolean isInstalled;
|
||||
/**
|
||||
* A browser that we don't know about.
|
||||
*
|
||||
@ -80,4 +87,23 @@ public class Browser implements Comparable<Browser> {
|
||||
} else
|
||||
return 2;
|
||||
}
|
||||
|
||||
public boolean isInstalled(Context context){
|
||||
if (isInstalled) {
|
||||
return true;
|
||||
}
|
||||
// Find all installed browsers that listen for ".i2p"
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse("http://stats.i2p"));
|
||||
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
List<ResolveInfo> installedBrowsers = pm.queryIntentActivities(intent, 0);
|
||||
for (ResolveInfo browser : installedBrowsers) {
|
||||
if (browser.activityInfo.packageName.equals(packageName)) {
|
||||
isInstalled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isInstalled;
|
||||
}
|
||||
}
|
||||
|
@ -73,11 +73,15 @@ public class BrowserAdapter extends RecyclerView.Adapter<BrowserAdapter.ViewHold
|
||||
holder.mLabel.setText(browser.label);
|
||||
|
||||
if (browser.isKnown) {
|
||||
if (browser.isRecommended && browser.isInstalled) {
|
||||
if (browser.isRecommended && browser.isInstalled(mCtx)) {
|
||||
holder.mStatus.setImageDrawable(
|
||||
mCtx.getResources().getDrawable(R.drawable.ic_stars_white_24dp));
|
||||
holder.mStatus.setVisibility(View.VISIBLE);
|
||||
} else if (browser.isSupported && !browser.isInstalled) {
|
||||
} else if (browser.isSupported && browser.isInstalled(mCtx)) {
|
||||
holder.mStatus.setImageDrawable(
|
||||
mCtx.getResources().getDrawable(R.drawable.ic_stars_white_24dp));
|
||||
holder.mStatus.setVisibility(View.INVISIBLE);
|
||||
} else if (browser.isSupported && !browser.isInstalled(mCtx)) {
|
||||
holder.mStatus.setImageDrawable(
|
||||
mCtx.getResources().getDrawable(R.drawable.ic_shop_white_24dp));
|
||||
holder.mStatus.setOnClickListener(new View.OnClickListener() {
|
||||
@ -94,7 +98,7 @@ public class BrowserAdapter extends RecyclerView.Adapter<BrowserAdapter.ViewHold
|
||||
}
|
||||
});
|
||||
holder.mStatus.setVisibility(View.VISIBLE);
|
||||
} else if (!browser.isSupported) {
|
||||
} else if (browser.isInstalled(mCtx) && !browser.isSupported) {
|
||||
// Make the icon gray-scale to show it is unsupported
|
||||
ColorMatrix matrix = new ColorMatrix();
|
||||
matrix.setSaturation(0);
|
||||
|
@ -26,6 +26,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -100,8 +102,28 @@ public class BrowserListFragment extends Fragment implements
|
||||
getContext().getResources().getStringArray(R.array.supported_browsers));
|
||||
supportedLabels = Arrays.asList(
|
||||
getContext().getResources().getStringArray(R.array.supported_browser_labels));
|
||||
unsupported = Arrays.asList(
|
||||
context.getResources().getStringArray(R.array.unsupported_browsers));
|
||||
unsupported = allBrowsers(context);//Arrays.asList(
|
||||
//context.getResources().getStringArray(R.array.unsupported_browsers));
|
||||
}
|
||||
|
||||
public List<String> allBrowsers(Context context){
|
||||
//try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse("http://www.google.com"));
|
||||
List<ResolveInfo> browserList;
|
||||
PackageManager pm = context.getPackageManager();
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
// gets all
|
||||
browserList = pm.queryIntentActivities(intent, PackageManager.MATCH_ALL);
|
||||
} else {
|
||||
browserList = pm.queryIntentActivities(intent, 0);
|
||||
}
|
||||
//}catch()
|
||||
List<String> finalResult = new ArrayList<String>();
|
||||
for (ResolveInfo ri : browserList){
|
||||
finalResult.add(ri.resolvePackageName);
|
||||
}
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,8 +143,9 @@ public class BrowserListFragment extends Fragment implements
|
||||
intent.setData(Uri.parse("http://stats.i2p"));
|
||||
|
||||
final PackageManager pm = getContext().getPackageManager();
|
||||
List<ResolveInfo> installedBrowsers = pm.queryIntentActivities(intent, 0);
|
||||
Set<ResolveInfo> installedBrowsers = new HashSet<>(pm.queryIntentActivities(intent, 0));
|
||||
|
||||
// Compare installed browsers to supported browsers
|
||||
for (ResolveInfo browser : installedBrowsers) {
|
||||
if (recommended.contains(browser.activityInfo.packageName)) {
|
||||
browsers.add(new Browser(pm, browser, true, true));
|
||||
|
@ -81,7 +81,7 @@ public class TunnelDetailFragment extends Fragment {
|
||||
try {
|
||||
mGroup = TunnelControllerGroup.getInstance();
|
||||
error = mGroup == null ? getResources().getString(R.string.i2ptunnel_not_initialized) : null;
|
||||
controllers = mGroup.getControllers();
|
||||
controllers = mGroup == null ? null : mGroup.getControllers();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
mGroup = null;
|
||||
controllers = null;
|
||||
|
@ -20,6 +20,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* A single tunnel.
|
||||
* Stored by the TunnelEntryAdapter.
|
||||
*/
|
||||
public class TunnelEntry {
|
||||
public static final int RUNNING = 1;
|
||||
public static final int STARTING = 2;
|
||||
@ -31,6 +35,7 @@ public class TunnelEntry {
|
||||
private final int mId;
|
||||
|
||||
/**
|
||||
* @param tcg non-null
|
||||
* @return the new TunnelEntry, or null if there was an error.
|
||||
*/
|
||||
public static TunnelEntry createNewTunnel(
|
||||
|
@ -5,22 +5,31 @@ import android.os.Build;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.util.FragmentUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Contains the List of TunnelEntries.
|
||||
* There's two of these, one for client tunnels and
|
||||
* one for server tunnels.
|
||||
* Created by the TunnelListFragment.
|
||||
*/
|
||||
public class TunnelEntryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private Context mCtx;
|
||||
private boolean mClientTunnels;
|
||||
private TunnelListFragment.OnTunnelSelectedListener mListener;
|
||||
private FragmentUtils.TwoPaneProvider mTwoPane;
|
||||
private final Context mCtx;
|
||||
private final boolean mClientTunnels;
|
||||
private final TunnelListFragment.OnTunnelSelectedListener mListener;
|
||||
private final FragmentUtils.TwoPaneProvider mTwoPane;
|
||||
private List<TunnelEntry> mTunnels;
|
||||
/**
|
||||
* The current activated item position. Only used on tablets.
|
||||
@ -34,10 +43,10 @@ public class TunnelEntryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
}
|
||||
|
||||
public static class TunnelViewHolder extends RecyclerView.ViewHolder {
|
||||
public ImageView status;
|
||||
public TextView name;
|
||||
public TextView description;
|
||||
public TextView interfacePort;
|
||||
public final ImageView status;
|
||||
public final TextView name;
|
||||
public final TextView description;
|
||||
public final TextView interfacePort;
|
||||
|
||||
public TunnelViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
@ -65,6 +74,8 @@ public class TunnelEntryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
}
|
||||
|
||||
public void addTunnel(TunnelEntry tunnel) {
|
||||
if (mTunnels == null)
|
||||
mTunnels = new ArrayList<TunnelEntry>();
|
||||
boolean wasEmpty = mTunnels.isEmpty();
|
||||
mTunnels.add(tunnel);
|
||||
if (wasEmpty) {
|
||||
@ -120,13 +131,24 @@ public class TunnelEntryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
}
|
||||
}
|
||||
|
||||
private void setClipboard(Context context, String text) {
|
||||
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
|
||||
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text);
|
||||
} else {
|
||||
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
android.content.ClipData clip = android.content.ClipData.newPlainText("Copied Text", text);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the contents of a view (invoked by the layout manager)
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case R.string.router_not_running:
|
||||
((TextView) holder.itemView).setText(
|
||||
mCtx.getString(R.string.router_not_running));
|
||||
mCtx.getString(R.string.i2ptunnel_not_initialized));
|
||||
break;
|
||||
|
||||
case R.layout.listitem_empty:
|
||||
@ -155,6 +177,16 @@ public class TunnelEntryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
tvh.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// TODO
|
||||
// lint priority 8/10
|
||||
// lint: Do not treat position as fixed; only use immediately and call holder.getAdapterPosition() to look it up later
|
||||
// javadocs: Note that unlike ListView, RecyclerView will not call this method again
|
||||
// if the position of the item changes in the data set unless the item itself is invalidated
|
||||
// or the new position cannot be determined.
|
||||
// For this reason, you should only use the position parameter while acquiring
|
||||
// the related data item inside this method and should not keep a copy of it.
|
||||
// If you need the position of an item later on (e.g. in a click listener),
|
||||
// use RecyclerView.ViewHolder.getAdapterPosition() which will have the updated adapter position.
|
||||
int oldPosition = mActivatedPosition;
|
||||
mActivatedPosition = position;
|
||||
notifyItemChanged(oldPosition);
|
||||
@ -164,6 +196,19 @@ public class TunnelEntryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
ViewCompat.getTransitionName(tvh.status));
|
||||
Pair<View, String>[] pairs = new Pair[]{ statusPair};
|
||||
mListener.onTunnelSelected(tunnel.getId(), pairs);
|
||||
view.invalidate();
|
||||
}
|
||||
});
|
||||
tvh.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
//@Override
|
||||
public boolean onLongClick(View view) {
|
||||
setClipboard(mCtx, tunnel.getDestHashBase32());
|
||||
Toast clipboardMessage = Toast.makeText(mCtx, R.string.copied_base32_system_notification_title, Toast. LENGTH_LONG);
|
||||
clipboardMessage.setGravity(Gravity.TOP, 0, 0); //optional
|
||||
clipboardMessage.show();
|
||||
view.invalidate();
|
||||
return true;
|
||||
|
||||
}
|
||||
});
|
||||
break;
|
||||
@ -171,6 +216,7 @@ public class TunnelEntryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return the size of the dataset (invoked by the layout manager)
|
||||
|
@ -13,10 +13,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TunnelEntryLoader extends AsyncTaskLoader<List<TunnelEntry>> {
|
||||
private TunnelControllerGroup mGroup;
|
||||
private boolean mClientTunnels;
|
||||
private final TunnelControllerGroup mGroup;
|
||||
private final boolean mClientTunnels;
|
||||
private List<TunnelEntry> mData;
|
||||
private Handler mHandler;
|
||||
private final Handler mHandler;
|
||||
private TunnelControllerMonitor mMonitor;
|
||||
|
||||
public TunnelEntryLoader(Context context, TunnelControllerGroup tcg, boolean clientTunnels) {
|
||||
|
@ -31,6 +31,12 @@ import net.i2p.i2ptunnel.TunnelControllerGroup;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The list of tunnels.
|
||||
* There's two of these, one for client tunnels and
|
||||
* one for server tunnels.
|
||||
* Creates the TunnelEntryAdapter.
|
||||
*/
|
||||
public class TunnelListFragment extends Fragment implements
|
||||
LoaderManager.LoaderCallbacks<List<TunnelEntry>> {
|
||||
public static final String SHOW_CLIENT_TUNNELS = "show_client_tunnels";
|
||||
|
@ -19,7 +19,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.viewpagerindicator.TitlePageIndicator;
|
||||
//import com.viewpagerindicator.TitlePageIndicator;
|
||||
|
||||
import net.i2p.android.i2ptunnel.preferences.EditTunnelContainerFragment;
|
||||
import net.i2p.android.i2ptunnel.util.TunnelUtil;
|
||||
@ -33,6 +33,11 @@ import net.i2p.router.RouterContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The top level Fragment of the tunnels tabs.
|
||||
* Creates client and server TunnelListFragments,
|
||||
* the options menu, and the new tunnel wizard button.
|
||||
*/
|
||||
public class TunnelsContainer extends Fragment implements
|
||||
FragmentUtils.TwoPaneProvider,
|
||||
TunnelListFragment.OnTunnelSelectedListener,
|
||||
@ -47,7 +52,7 @@ public class TunnelsContainer extends Fragment implements
|
||||
private boolean mTwoPane;
|
||||
|
||||
ViewPager mViewPager;
|
||||
TitlePageIndicator mPageIndicator;
|
||||
//TitlePageIndicator mPageIndicator;
|
||||
FragmentPagerAdapter mFragPagerAdapter;
|
||||
|
||||
private static final String FRAGMENT_CLIENT = "client_fragment";
|
||||
@ -65,12 +70,11 @@ public class TunnelsContainer extends Fragment implements
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
private boolean showActions() {
|
||||
private static boolean showActions() {
|
||||
RouterContext rCtx = Util.getRouterContext();
|
||||
TunnelControllerGroup tcg = TunnelControllerGroup.getInstance();
|
||||
return rCtx != null && tcg != null &&
|
||||
(tcg.getState() == ClientAppState.STARTING ||
|
||||
tcg.getState() == ClientAppState.RUNNING);
|
||||
tcg.getState() == ClientAppState.RUNNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -78,7 +82,7 @@ public class TunnelsContainer extends Fragment implements
|
||||
View v = inflater.inflate(R.layout.container_tunnels, container, false);
|
||||
|
||||
mViewPager = (ViewPager) v.findViewById(R.id.pager);
|
||||
mPageIndicator = (TitlePageIndicator) v.findViewById(R.id.page_indicator);
|
||||
//mPageIndicator = (TitlePageIndicator) v.findViewById(R.id.page_indicator);
|
||||
mNewTunnel = (ImageButton) v.findViewById(R.id.promoted_action);
|
||||
mNewTunnel.setVisibility(showActions() ? View.VISIBLE : View.GONE);
|
||||
|
||||
@ -107,7 +111,7 @@ public class TunnelsContainer extends Fragment implements
|
||||
mViewPager.setAdapter(mFragPagerAdapter);
|
||||
|
||||
// Bind the page indicator to the pager.
|
||||
mPageIndicator.setViewPager(mViewPager);
|
||||
//mPageIndicator.setViewPager(mViewPager);
|
||||
|
||||
mNewTunnel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -211,8 +215,17 @@ public class TunnelsContainer extends Fragment implements
|
||||
if (requestCode == TUNNEL_WIZARD_REQUEST) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Bundle tunnelData = data.getExtras().getBundle(TUNNEL_WIZARD_DATA);
|
||||
// ticket #2483
|
||||
if (tunnelData == null)
|
||||
return;
|
||||
// TODO fetch earlier
|
||||
TunnelControllerGroup tcg = TunnelControllerGroup.getInstance();
|
||||
if (tcg == null) {
|
||||
// router went away
|
||||
Toast.makeText(getActivity().getApplicationContext(),
|
||||
R.string.router_not_running, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
TunnelConfig cfg = TunnelUtil.createConfigFromWizard(getActivity(), tcg, tunnelData);
|
||||
TunnelEntry tunnel = TunnelEntry.createNewTunnel(getActivity(), tcg, cfg);
|
||||
|
||||
|
@ -16,6 +16,9 @@ import net.i2p.i2ptunnel.TunnelControllerGroup;
|
||||
import net.i2p.i2ptunnel.ui.TunnelConfig;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class BaseTunnelPreferenceFragment extends CustomPreferenceFragment {
|
||||
protected static final String ARG_TUNNEL_ID = "tunnelId";
|
||||
@ -88,11 +91,15 @@ public abstract class BaseTunnelPreferenceFragment extends CustomPreferenceFragm
|
||||
// TODO: There used to be a possible ANR here, because the underlying I2P code
|
||||
// checks if the session is open as part of updating its config. We may need to save
|
||||
// completely asynchronously (and ensure we do actually save before the app closes).
|
||||
task.execute().get();
|
||||
task.execute().get(2, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Util.e("Interrupted while saving tunnel config", e);
|
||||
} catch (ExecutionException e) {
|
||||
Util.e("Error while saving tunnel config", e);
|
||||
} catch (CancellationException e) {
|
||||
Util.e("Cancelled while saving tunnel config", e);
|
||||
} catch (TimeoutException e) {
|
||||
Util.e("Timed out while savomg tunnel config", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,8 @@ public class GeneralTunnelPreferenceFragment extends BaseTunnelPreferenceFragmen
|
||||
generalCategory.removePreference(generalCategory.findPreference(getString(R.string.TUNNEL_SHARED_CLIENT)));
|
||||
addPreferencesFromResource(R.xml.tunnel_gen_server_port, portCategory);
|
||||
portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_TARGET_PORT)));
|
||||
portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_USE_SSL)));
|
||||
// # TODO: See trac issue #2296
|
||||
//portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_USE_SSL)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,8 +169,11 @@ public class GeneralTunnelPreferenceFragment extends BaseTunnelPreferenceFragmen
|
||||
|
||||
@Override
|
||||
protected void generalClientStandardOrIrc(boolean isStandardOrIrc) {
|
||||
/*
|
||||
# TODO: See trac issue #2296
|
||||
if (!isStandardOrIrc)
|
||||
portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_USE_SSL)));
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -185,7 +189,8 @@ public class GeneralTunnelPreferenceFragment extends BaseTunnelPreferenceFragmen
|
||||
@Override
|
||||
protected void generalServerHttpBidirOrStreamr(boolean isStreamr) {
|
||||
addPreferencesFromResource(R.xml.tunnel_gen_client_port, portCategory);
|
||||
portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_USE_SSL)));
|
||||
// # TODO: See trac issue #2296
|
||||
//portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_USE_SSL)));
|
||||
if (isStreamr)
|
||||
portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_LISTEN_PORT)));
|
||||
|
||||
@ -201,7 +206,8 @@ public class GeneralTunnelPreferenceFragment extends BaseTunnelPreferenceFragmen
|
||||
protected void generalServerPortStreamr(boolean isStreamr) {
|
||||
if (isStreamr) {
|
||||
portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_TARGET_HOST)));
|
||||
portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_USE_SSL)));
|
||||
// # TODO: See trac issue #2296
|
||||
//portCategory.removePreference(portCategory.findPreference(getString(R.string.TUNNEL_USE_SSL)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,9 @@ import java.util.List;
|
||||
* InetAddress.getByName(), which will trigger a NetworkOnMainThreadException otherwise.
|
||||
*/
|
||||
public class SaveTunnelTask extends AsyncTask<Void, Void, List<String>> {
|
||||
TunnelControllerGroup mGroup;
|
||||
int mTunnelId;
|
||||
TunnelConfig mCfg;
|
||||
final TunnelControllerGroup mGroup;
|
||||
final int mTunnelId;
|
||||
final TunnelConfig mCfg;
|
||||
|
||||
public SaveTunnelTask(TunnelControllerGroup group, int tunnelId, TunnelConfig cfg) {
|
||||
mGroup = group;
|
||||
|
@ -11,7 +11,7 @@ package net.i2p.android.i2ptunnel.util;
|
||||
* tunnel properties always exist.
|
||||
*/
|
||||
public abstract class TunnelLogic {
|
||||
protected String mType;
|
||||
protected final String mType;
|
||||
|
||||
public TunnelLogic(String type) {
|
||||
mType = type;
|
||||
|
@ -7,6 +7,7 @@ import android.os.Bundle;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.android.wizard.model.Page;
|
||||
import net.i2p.i2ptunnel.TunnelController;
|
||||
import net.i2p.i2ptunnel.TunnelControllerGroup;
|
||||
@ -99,6 +100,7 @@ public class TunnelUtil extends GeneralHelper {
|
||||
public static void writeTunnelToPreferences(Context ctx, TunnelControllerGroup tcg, int tunnel) {
|
||||
new TunnelUtil(tcg).writeTunnelToPreferences(ctx, tunnel);
|
||||
}
|
||||
|
||||
public void writeTunnelToPreferences(Context ctx, int tunnel) {
|
||||
Resources res = ctx.getResources();
|
||||
|
||||
@ -122,9 +124,9 @@ public class TunnelUtil extends GeneralHelper {
|
||||
}
|
||||
|
||||
class TunnelToPreferences extends TunnelLogic {
|
||||
SharedPreferences.Editor ed;
|
||||
Resources res;
|
||||
int tunnel;
|
||||
final SharedPreferences.Editor ed;
|
||||
final Resources res;
|
||||
final int tunnel;
|
||||
|
||||
public TunnelToPreferences(SharedPreferences.Editor ed, Resources res, int tunnel, String type) {
|
||||
super(type);
|
||||
@ -182,8 +184,10 @@ public class TunnelUtil extends GeneralHelper {
|
||||
|
||||
@Override
|
||||
protected void generalClientStandardOrIrc(boolean isStandardOrIrc) {
|
||||
/* # TODO: See trac issue #2296
|
||||
if (isStandardOrIrc)
|
||||
ed.putBoolean(res.getString(R.string.TUNNEL_USE_SSL), isSSLEnabled(tunnel));
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -212,7 +216,8 @@ public class TunnelUtil extends GeneralHelper {
|
||||
protected void generalServerPortStreamr(boolean isStreamr) {
|
||||
if (!isStreamr) {
|
||||
ed.putString(res.getString(R.string.TUNNEL_TARGET_HOST), getTargetHost(tunnel));
|
||||
ed.putBoolean(res.getString(R.string.TUNNEL_USE_SSL), isSSLEnabled(tunnel));
|
||||
// # TODO: See trac issue #2296
|
||||
//ed.putBoolean(res.getString(R.string.TUNNEL_USE_SSL), isSSLEnabled(tunnel));
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,6 +330,7 @@ public class TunnelUtil extends GeneralHelper {
|
||||
public static TunnelConfig createConfigFromPreferences(Context ctx, TunnelControllerGroup tcg, int tunnel) {
|
||||
return new TunnelUtil(tcg).createConfigFromPreferences(ctx, tunnel);
|
||||
}
|
||||
|
||||
public TunnelConfig createConfigFromPreferences(Context ctx, int tunnel) {
|
||||
Resources res = ctx.getResources();
|
||||
|
||||
@ -345,11 +351,11 @@ public class TunnelUtil extends GeneralHelper {
|
||||
}
|
||||
|
||||
class TunnelConfigFromPreferences extends TunnelLogic {
|
||||
TunnelConfig cfg;
|
||||
SharedPreferences prefs;
|
||||
Resources res;
|
||||
TunnelControllerGroup tcg;
|
||||
int tunnel;
|
||||
final TunnelConfig cfg;
|
||||
final SharedPreferences prefs;
|
||||
final Resources res;
|
||||
final TunnelControllerGroup tcg;
|
||||
final int tunnel;
|
||||
|
||||
public TunnelConfigFromPreferences(TunnelConfig cfg, SharedPreferences prefs, Resources res,
|
||||
TunnelControllerGroup tcg, int tunnel, String type) {
|
||||
@ -414,8 +420,10 @@ public class TunnelUtil extends GeneralHelper {
|
||||
|
||||
@Override
|
||||
protected void generalClientStandardOrIrc(boolean isStandardOrIrc) {
|
||||
/* # TODO: See trac issue #2296
|
||||
if (isStandardOrIrc)
|
||||
cfg.setUseSSL(prefs.getBoolean(res.getString(R.string.TUNNEL_USE_SSL), false));
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -444,7 +452,8 @@ public class TunnelUtil extends GeneralHelper {
|
||||
protected void generalServerPortStreamr(boolean isStreamr) {
|
||||
if (!isStreamr) {
|
||||
cfg.setTargetHost(prefs.getString(res.getString(R.string.TUNNEL_TARGET_HOST), "127.0.0.1"));
|
||||
cfg.setUseSSL(prefs.getBoolean(res.getString(R.string.TUNNEL_USE_SSL), false));
|
||||
// # TODO: See trac issue #2296
|
||||
//cfg.setUseSSL(prefs.getBoolean(res.getString(R.string.TUNNEL_USE_SSL), false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,10 +569,17 @@ public class TunnelUtil extends GeneralHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data non-null
|
||||
*/
|
||||
public static TunnelConfig createConfigFromWizard(
|
||||
Context ctx, TunnelControllerGroup tcg, Bundle data) {
|
||||
return new TunnelUtil(tcg).createConfigFromWizard(ctx, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data non-null
|
||||
*/
|
||||
public TunnelConfig createConfigFromWizard(Context ctx, Bundle data) {
|
||||
// Get the Bundle keys
|
||||
Resources res = ctx.getResources();
|
||||
@ -574,21 +590,26 @@ public class TunnelUtil extends GeneralHelper {
|
||||
// Update the TunnelConfig from the tunnel wizard settings
|
||||
String kClientServer = res.getString(R.string.i2ptunnel_wizard_k_client_server);
|
||||
String kType = res.getString(R.string.i2ptunnel_wizard_k_type);
|
||||
String clientServer = data.getBundle(kClientServer).getString(Page.SIMPLE_DATA_KEY);
|
||||
String typeName = data.getBundle(clientServer + ":" + kType).getString(Page.SIMPLE_DATA_KEY);
|
||||
String type = getTypeFromName(typeName, ctx);
|
||||
cfg.setType(type);
|
||||
try {
|
||||
String clientServer = data.getBundle(kClientServer).getString(Page.SIMPLE_DATA_KEY);
|
||||
String typeName = data.getBundle(clientServer + ":" + kType).getString(Page.SIMPLE_DATA_KEY);
|
||||
String type = getTypeFromName(typeName, ctx);
|
||||
cfg.setType(type);
|
||||
|
||||
new TunnelConfigFromWizard(cfg, data, res, _group, type).runLogic();
|
||||
} catch (NullPointerException ex) {
|
||||
Util.e("Exception while trying to create config from wizard: "+ex.getMessage());
|
||||
}
|
||||
|
||||
new TunnelConfigFromWizard(cfg, data, res, _group, type).runLogic();
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
class TunnelConfigFromWizard extends TunnelLogic {
|
||||
TunnelConfig cfg;
|
||||
Bundle data;
|
||||
Resources res;
|
||||
TunnelControllerGroup tcg;
|
||||
final TunnelConfig cfg;
|
||||
final Bundle data;
|
||||
final Resources res;
|
||||
final TunnelControllerGroup tcg;
|
||||
|
||||
public TunnelConfigFromWizard(TunnelConfig cfg, Bundle data, Resources res,
|
||||
TunnelControllerGroup tcg, String type) {
|
||||
|
@ -3,12 +3,11 @@ package net.i2p.android.preferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.SettingsActivity;
|
||||
|
||||
public class AdvancedPreferenceFragment extends PreferenceFragmentCompat {
|
||||
public class AdvancedPreferenceFragment extends I2PreferenceFragment {
|
||||
private static final String PREFERENCE_CATEGORY_TRANSPORTS = "preference_category_transports";
|
||||
private static final String PREFERENCE_CATEGORY_EXPL_TUNNELS = "preference_category_expl_tunnels";
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.i2p.android.preferences;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
@ -30,6 +31,7 @@ public class TransportsPreferenceFragment extends I2PreferenceFragment {
|
||||
((SettingsActivity) getActivity()).getSupportActionBar().setTitle(R.string.settings_label_transports);
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private void loadProperties() {
|
||||
Context context= getActivity();
|
||||
RouterContext ctx = Util.getRouterContext();
|
||||
|
@ -20,7 +20,7 @@ public class IntListPreference extends ListPreference {
|
||||
getPersistedInt(0);
|
||||
} catch (ClassCastException e) {
|
||||
// Fix for where this preference was previously stored in a ListPreference
|
||||
getSharedPreferences().edit().remove(getKey()).commit();
|
||||
getSharedPreferences().edit().remove(getKey()).apply();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import net.i2p.android.ext.floatingactionbutton.FloatingActionsMenu;
|
||||
import net.i2p.android.ext.floatingactionbutton.FloatingActionsMenu.OnFloatingActionsMenuUpdateListener;
|
||||
import net.i2p.android.router.dialog.AboutDialog;
|
||||
import net.i2p.android.router.dialog.TextResourceDialog;
|
||||
import net.i2p.android.router.log.LogActivity;
|
||||
@ -42,6 +43,17 @@ public class ConsoleContainer extends Fragment {
|
||||
}
|
||||
|
||||
mConsoleMenu = (FloatingActionsMenu) v.findViewById(R.id.console_action_menu);
|
||||
// update visibility based on router state
|
||||
mConsoleMenu.setOnFloatingActionsMenuUpdateListener(new OnFloatingActionsMenuUpdateListener() {
|
||||
public void onMenuExpanded() {
|
||||
// this is called after the animation starts, sadly
|
||||
setMenuVisibility();
|
||||
}
|
||||
public void onMenuCollapsed() {
|
||||
// call it here too so the expand animation isn't glitchy as often
|
||||
setMenuVisibility();
|
||||
}
|
||||
});
|
||||
mConsoleMenu.findViewById(R.id.action_news).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
@ -1,17 +1,22 @@
|
||||
package net.i2p.android.router;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -23,6 +28,7 @@ import android.widget.ScrollView;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
import net.i2p.android.I2PActivityBase;
|
||||
@ -69,6 +75,7 @@ public class MainFragment extends I2PFragmentBase {
|
||||
private TextView vAdvStatusText;
|
||||
|
||||
private static final String PREF_CONFIGURE_BROWSER = "app.dialog.configureBrowser";
|
||||
private static final String PREF_CONFIGURE_BATTERY = "app.dialog.configureBattery";
|
||||
private static final String PREF_FIRST_START = "app.router.firstStart";
|
||||
private static final String PREF_SHOW_STATS = "i2pandroid.main.showStats";
|
||||
protected static final String PROP_NEW_INSTALL = "i2p.newInstall";
|
||||
@ -320,7 +327,10 @@ public class MainFragment extends I2PFragmentBase {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateState(State newState) {
|
||||
/**
|
||||
* Changes the logo based on the state.
|
||||
*/
|
||||
private void updateState(State newState) {
|
||||
if (newState == State.INIT ||
|
||||
newState == State.STOPPED ||
|
||||
newState == State.MANUAL_STOPPED ||
|
||||
@ -328,13 +338,13 @@ public class MainFragment extends I2PFragmentBase {
|
||||
newState == State.NETWORK_STOPPED) {
|
||||
mConsoleLights.setImageResource(R.drawable.routerlogo_0);
|
||||
} else if (newState == State.STARTING ||
|
||||
//newState == State.GRACEFUL_SHUTDOWN || // Don't change lights for graceful
|
||||
newState == State.STOPPING ||
|
||||
newState == State.MANUAL_STOPPING ||
|
||||
newState == State.MANUAL_QUITTING ||
|
||||
newState == State.NETWORK_STOPPING) {
|
||||
mConsoleLights.setImageResource(R.drawable.routerlogo_1);
|
||||
} else if (newState == State.RUNNING) {
|
||||
} else if (newState == State.RUNNING ||
|
||||
newState == State.GRACEFUL_SHUTDOWN) {
|
||||
mConsoleLights.setImageResource(R.drawable.routerlogo_2);
|
||||
} else if (newState == State.ACTIVE) {
|
||||
mConsoleLights.setImageResource(R.drawable.routerlogo_3);
|
||||
@ -375,9 +385,9 @@ public class MainFragment extends I2PFragmentBase {
|
||||
String uptime = DataHelper.formatDuration(ctx.router().getUptime());
|
||||
int active = ctx.commSystem().countActivePeers();
|
||||
int known = Math.max(ctx.netDb().getKnownRouters() - 1, 0);
|
||||
vUptime.setText("" + uptime);
|
||||
vActive.setText("" + active);
|
||||
vKnown.setText("" + known);
|
||||
vUptime.setText(uptime);
|
||||
vActive.setText(Integer.toString(active));
|
||||
vKnown.setText(Integer.toString(known));
|
||||
|
||||
// Load running tunnels
|
||||
loadDestinations(ctx);
|
||||
@ -396,20 +406,21 @@ public class MainFragment extends I2PFragmentBase {
|
||||
//ctx.commSystem().getReachabilityStatus();
|
||||
|
||||
String status =
|
||||
"Exploratory Tunnels in/out: " + inEx + " / " + outEx
|
||||
+ "\nClient Tunnels in/out: " + inCl + " / " + outCl;
|
||||
getString(R.string.notification_status_expl, inEx, outEx) + '\n' +
|
||||
getString(R.string.notification_status_client, inCl, outCl);
|
||||
|
||||
|
||||
// Need to see if we have the participation option set to on.
|
||||
// I thought there was a router method for that? I guess not! WHY NOT?
|
||||
// It would be easier if we had a number to test status.
|
||||
String participate = "\nParticipation: " + tunnelStatus + " (" + part + ")";
|
||||
String participate = '\n' + getString(R.string.settings_label_hiddenMode) + ": " + tunnelStatus + " (" + part + ")";
|
||||
|
||||
String details =
|
||||
"\nMemory: " + DataHelper.formatSize(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())
|
||||
+ "B / " + DataHelper.formatSize(Runtime.getRuntime().maxMemory()) + 'B'
|
||||
+ "\nJob Lag: " + jobLag
|
||||
+ "\nMsg Delay: " + msgDelay;
|
||||
'\n' + getString(R.string.stats_memory) + ": " +
|
||||
DataHelper.formatSize(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) +
|
||||
"B / " + DataHelper.formatSize(Runtime.getRuntime().maxMemory()) + 'B' +
|
||||
'\n' + getString(R.string.stats_lag) + ": " + jobLag +
|
||||
'\n' + getString(R.string.stats_delay) + ": " + msgDelay;
|
||||
|
||||
_savedStatus = status + participate + details;
|
||||
vAdvStatusText.setText(_savedStatus);
|
||||
@ -437,6 +448,7 @@ public class MainFragment extends I2PFragmentBase {
|
||||
// network but no router context
|
||||
vStatusContainer.setVisibility(View.GONE);
|
||||
getActivity().findViewById(R.id.console_usage_stats).setVisibility(View.INVISIBLE);
|
||||
updateState(State.STOPPED);
|
||||
/**
|
||||
* **
|
||||
* RouterService svc = _routerService; String status = "connected? "
|
||||
@ -526,8 +538,8 @@ public class MainFragment extends I2PFragmentBase {
|
||||
* compare translated nicknames - put "shared clients" first in the sort
|
||||
*/
|
||||
private class AlphaComparator implements Comparator<Destination> {
|
||||
private String xsc;
|
||||
private RouterContext _ctx;
|
||||
private final String xsc;
|
||||
private final RouterContext _ctx;
|
||||
|
||||
public AlphaComparator(RouterContext ctx) {
|
||||
_ctx = ctx;
|
||||
@ -578,16 +590,18 @@ public class MainFragment extends I2PFragmentBase {
|
||||
);
|
||||
if (language == null) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
|
||||
// avoid ISE caused by fragment detachment ticket #2631
|
||||
final String languages[] = getResources().getStringArray(R.array.languages);
|
||||
b.setTitle(R.string.choose_language)
|
||||
.setItems(R.array.language_names, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// Save the language choice
|
||||
String language = getResources().getStringArray(R.array.languages)[which];
|
||||
String language = languages[which];
|
||||
PreferenceManager.getDefaultSharedPreferences(getActivity())
|
||||
.edit()
|
||||
.putString(getString(R.string.PREF_LANGUAGE), language)
|
||||
.commit();
|
||||
.apply();
|
||||
// Close the dialog
|
||||
dialog.dismiss();
|
||||
// Broadcast the change to RouterService just in case the router is running
|
||||
@ -614,16 +628,62 @@ public class MainFragment extends I2PFragmentBase {
|
||||
ab.setPref(PREF_CONFIGURE_BROWSER, false);
|
||||
Intent hi = new Intent(getActivity(), BrowserConfigActivity.class);
|
||||
startActivity(hi);
|
||||
checkDialog();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int i) {
|
||||
dialog.cancel();
|
||||
dialog.dismiss();
|
||||
ab.setPref(PREF_CONFIGURE_BROWSER, false);
|
||||
checkDialog();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
} else if (ab.getPref(PREF_CONFIGURE_BATTERY, true)) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
// only for Marshmallow and newer versions
|
||||
final Intent intent = new Intent();
|
||||
final Context mContext = ab.getApplicationContext();
|
||||
String packageName = mContext.getPackageName();
|
||||
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
|
||||
b.setTitle(R.string.configure_no_doze_title);
|
||||
b.setMessage(R.string.configure_no_doze);
|
||||
b.setCancelable(false);
|
||||
b.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int i) {
|
||||
String packageName = mContext.getPackageName();
|
||||
ab.setPref(PREF_CONFIGURE_BATTERY, false);
|
||||
dialog.dismiss();
|
||||
// Simply do not re-attempt a battery optimization after the first time,
|
||||
// even if an error occurs. http://trac.i2p2.i2p/ticket/2783
|
||||
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
|
||||
intent.setData(Uri.parse("package:" + packageName));
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
mContext.startActivity(intent);
|
||||
} catch (ActivityNotFoundException activityNotFound) {
|
||||
ab.setPref(PREF_CONFIGURE_BATTERY, false);
|
||||
} catch (AndroidRuntimeException activityNotFound) {
|
||||
ab.setPref(PREF_CONFIGURE_BATTERY, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int i) {
|
||||
dialog.cancel();
|
||||
ab.setPref(PREF_CONFIGURE_BATTERY, false);
|
||||
}
|
||||
});
|
||||
b.show();
|
||||
}
|
||||
} else {
|
||||
ab.setPref(PREF_CONFIGURE_BATTERY, false);
|
||||
}
|
||||
}
|
||||
/*VersionDialog dialog = new VersionDialog();
|
||||
String oldVersion = ((I2PActivityBase) getActivity()).getPref(PREF_INSTALLED_VERSION, "??");
|
||||
|
@ -13,6 +13,7 @@ import android.widget.TextView;
|
||||
|
||||
import net.i2p.android.apps.NewsFetcher;
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@ -33,12 +34,16 @@ public class NewsFragment extends I2PFragmentBase {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
NewsFetcher nf = NewsFetcher.getInstance();
|
||||
if (nf != null) {
|
||||
// Always update the status
|
||||
TextView tv = (TextView) getActivity().findViewById(R.id.news_status);
|
||||
tv.setText(nf.status().replace(" ", " "));
|
||||
tv.setVisibility(View.VISIBLE);
|
||||
RouterContext ctx = getRouterContext();
|
||||
if (ctx != null) {
|
||||
NewsFetcher nf = (NewsFetcher) ctx.clientAppManager().getRegisteredApp(NewsFetcher.APP_NAME);
|
||||
if (nf != null) {
|
||||
// Always update the status
|
||||
// This is the news last updated/checked text at the bottom
|
||||
TextView tv = (TextView) getActivity().findViewById(R.id.news_status);
|
||||
tv.setText(nf.status().replace(" ", " "));
|
||||
tv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
// Only update the content if we need to
|
||||
|
@ -4,7 +4,7 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.wizard.model.AbstractWizardModel;
|
||||
import net.i2p.android.wizard.model.I2PB64DestinationPage;
|
||||
import net.i2p.android.wizard.model.I2PDestinationPage;
|
||||
import net.i2p.android.wizard.model.PageList;
|
||||
import net.i2p.android.wizard.model.SingleTextFieldPage;
|
||||
|
||||
@ -22,7 +22,7 @@ public class AddressbookAddWizardModel extends AbstractWizardModel {
|
||||
.setDescription(res.getString(R.string.addressbook_add_wizard_desc_name))
|
||||
.setRequired(true),
|
||||
|
||||
new I2PB64DestinationPage(this, res.getString(R.string.addressbook_add_wizard_k_destination))
|
||||
new I2PDestinationPage(this, res.getString(R.string.i2ptunnel_wizard_k_dest))
|
||||
.setDescription(res.getString(R.string.addressbook_add_wizard_desc_destination))
|
||||
.setRequired(true)
|
||||
);
|
||||
|
@ -20,7 +20,7 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.viewpagerindicator.TitlePageIndicator;
|
||||
//import com.viewpagerindicator.TitlePageIndicator;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.NamingServiceUtil;
|
||||
@ -92,10 +92,10 @@ public class AddressbookContainer extends Fragment
|
||||
|
||||
if (!mTwoPane) {
|
||||
mViewPager = (ViewPager) v.findViewById(R.id.pager);
|
||||
TitlePageIndicator pageIndicator = (TitlePageIndicator) v.findViewById(R.id.page_indicator);
|
||||
//TitlePageIndicator pageIndicator = (TitlePageIndicator) v.findViewById(R.id.page_indicator);
|
||||
mFragPagerAdapter = new AddressbookPagerAdapter(getActivity(), getChildFragmentManager());
|
||||
mViewPager.setAdapter(mFragPagerAdapter);
|
||||
pageIndicator.setViewPager(mViewPager);
|
||||
//pageIndicator.setViewPager(mViewPager);
|
||||
}
|
||||
|
||||
return v;
|
||||
|
@ -25,16 +25,16 @@ public class AboutDialog extends DialogFragment {
|
||||
View view = li.inflate(R.layout.fragment_dialog_about, null);
|
||||
|
||||
final String currentVersion = Util.getOurVersion(getActivity());
|
||||
TextView tv = (TextView)view.findViewById(R.id.about_version);
|
||||
TextView tv = (TextView) view.findViewById(R.id.about_version);
|
||||
tv.setText(currentVersion);
|
||||
|
||||
tv = (TextView)view.findViewById(R.id.url_project);
|
||||
tv = (TextView) view.findViewById(R.id.url_project);
|
||||
Linkify.addLinks(tv, I2Patterns.I2P_WEB_URL, "http://");
|
||||
tv = (TextView)view.findViewById(R.id.url_android_bugs);
|
||||
tv = (TextView) view.findViewById(R.id.url_android_bugs);
|
||||
Linkify.addLinks(tv, I2Patterns.I2P_WEB_URL, "http://");
|
||||
tv = (TextView)view.findViewById(R.id.url_android_volunteer);
|
||||
tv = (TextView) view.findViewById(R.id.url_android_volunteer);
|
||||
Linkify.addLinks(tv, I2Patterns.I2P_WEB_URL, "http://");
|
||||
tv = (TextView)view.findViewById(R.id.url_donate);
|
||||
tv = (TextView) view.findViewById(R.id.url_gitlab);
|
||||
Linkify.addLinks(tv, I2Patterns.I2P_WEB_URL, "http://");
|
||||
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
|
||||
|
@ -154,6 +154,8 @@ public class NetDbDetailFragment extends I2PFragmentBase {
|
||||
String val = (String)e.getValue();
|
||||
addTableRow(table, DataHelper.stripHTML(key), DataHelper.stripHTML(val));
|
||||
}
|
||||
// spacer
|
||||
addTableRow(table, "", "");
|
||||
|
||||
addresses.addView(table);
|
||||
}
|
||||
@ -230,9 +232,11 @@ public class NetDbDetailFragment extends I2PFragmentBase {
|
||||
TextView tl1, tl2;
|
||||
|
||||
row = new TableRow(getActivity());
|
||||
// left top right bottom
|
||||
row.setPadding(10, 0, 0, 0);
|
||||
|
||||
tl1 = new TextView(getActivity());
|
||||
tl1.setPadding(0, 0, 20, 0);
|
||||
tl2 = new TextView(getActivity());
|
||||
|
||||
tl1.setText(key);
|
||||
|
@ -5,6 +5,7 @@ import android.support.v4.content.AsyncTaskLoader;
|
||||
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.router.RouterInfo;
|
||||
import net.i2p.router.RouterContext;
|
||||
@ -24,14 +25,27 @@ public class NetDbEntryLoader extends AsyncTaskLoader<List<NetDbEntry>> {
|
||||
mRouters = routers;
|
||||
}
|
||||
|
||||
/** put us on top */
|
||||
private static class RouterInfoComparator implements Comparator<RouterInfo> {
|
||||
private final Hash _us;
|
||||
|
||||
public RouterInfoComparator(Hash us) {
|
||||
_us = us;
|
||||
}
|
||||
|
||||
public int compare(RouterInfo l, RouterInfo r) {
|
||||
return l.getIdentity().getHash().toBase64().compareTo(r.getIdentity().getHash().toBase64());
|
||||
Hash lh = l.getIdentity().getHash();
|
||||
Hash rh = r.getIdentity().getHash();
|
||||
if (lh.equals(_us))
|
||||
return -1;
|
||||
if (rh.equals(_us))
|
||||
return 1;
|
||||
return lh.toBase64().compareTo(rh.toBase64());
|
||||
}
|
||||
}
|
||||
|
||||
private class LeaseSetComparator implements Comparator<LeaseSet> {
|
||||
private RouterContext mRContext;
|
||||
private final RouterContext mRContext;
|
||||
|
||||
public LeaseSetComparator(RouterContext rContext) {
|
||||
super();
|
||||
@ -53,9 +67,9 @@ public class NetDbEntryLoader extends AsyncTaskLoader<List<NetDbEntry>> {
|
||||
public List<NetDbEntry> loadInBackground() {
|
||||
List<NetDbEntry> ret = new ArrayList<>();
|
||||
RouterContext routerContext = Util.getRouterContext();
|
||||
if (routerContext != null && routerContext.netDb().isInitialized()) {
|
||||
if (routerContext != null && routerContext.netDb().isInitialized() && routerContext.routerHash() != null) {
|
||||
if (mRouters) {
|
||||
Set<RouterInfo> routers = new TreeSet<>(new RouterInfoComparator());
|
||||
Set<RouterInfo> routers = new TreeSet<>(new RouterInfoComparator(routerContext.routerHash()));
|
||||
routers.addAll(routerContext.netDb().getRouters());
|
||||
for (RouterInfo ri : routers) {
|
||||
NetDbEntry entry = NetDbEntry.fromRouterInfo(routerContext, ri);
|
||||
|
@ -17,7 +17,7 @@ import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class NetDbStatsLoader extends AsyncTaskLoader<List<ObjectCounter<String>>> {
|
||||
private RouterContext mRContext;
|
||||
private final RouterContext mRContext;
|
||||
private List<ObjectCounter<String>> mData;
|
||||
|
||||
public NetDbStatsLoader(Context context, RouterContext rContext) {
|
||||
@ -95,7 +95,7 @@ public class NetDbStatsLoader extends AsyncTaskLoader<List<ObjectCounter<String>
|
||||
int rv = 0;
|
||||
for (RouterAddress addr : info.getAddresses()) {
|
||||
String style = addr.getTransportStyle();
|
||||
if (style.equals("NTCP")) {
|
||||
if (style.equals("NTCP") || style.equals("NTCP2")) {
|
||||
rv |= NTCP;
|
||||
} else if (style.equals("SSU")) {
|
||||
if (addr.getOption("iport0") != null)
|
||||
@ -108,7 +108,12 @@ public class NetDbStatsLoader extends AsyncTaskLoader<List<ObjectCounter<String>
|
||||
rv |= IPV6;
|
||||
|
||||
}
|
||||
return getContext().getString(TNAMES[rv]);
|
||||
int tname = TNAMES[rv];
|
||||
// remap cases with no string to "Hidden or starting up"
|
||||
// so we don't crash NotFoundException
|
||||
if (tname == 0)
|
||||
tname = TNAMES[0];
|
||||
return getContext().getString(tname);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,6 +77,7 @@ public class NetDbSummaryTableFragment extends Fragment {
|
||||
titleRow.setPadding(10, 0, 0, 0);
|
||||
|
||||
tl1 = new TextView(getActivity());
|
||||
tl1.setPadding(0, 0, 20, 0);
|
||||
tl1.setTextSize(20);
|
||||
tl2 = new TextView(getActivity());
|
||||
tl2.setTextSize(20);
|
||||
@ -108,6 +109,7 @@ public class NetDbSummaryTableFragment extends Fragment {
|
||||
row.setPadding(10, 0, 0, 0);
|
||||
|
||||
tl1 = new TextView(getActivity());
|
||||
tl1.setPadding(0, 0, 20, 0);
|
||||
tl2 = new TextView(getActivity());
|
||||
|
||||
tl1.setText(name);
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.android.router.provider;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
@ -18,6 +19,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -153,7 +155,7 @@ public class CacheProvider extends ContentProvider {
|
||||
// first seg is empty since string starts with /
|
||||
String nonce = segs.length > 1 ? segs[1] : null;
|
||||
String scheme = segs.length > 2 ? segs[2] : null;
|
||||
String host = segs.length > 3 ? segs[3].toLowerCase() : null;
|
||||
String host = segs.length > 3 ? segs[3].toLowerCase(Locale.US) : null;
|
||||
String realPath = segs.length > 4 ? segs[4] : "";
|
||||
String query = uri.getEncodedQuery();
|
||||
if (query == null) {
|
||||
@ -230,10 +232,11 @@ public class CacheProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
private ParcelFileDescriptor eepFetch(Uri uri) throws FileNotFoundException {
|
||||
AppCache cache = AppCache.getInstance(getContext());
|
||||
Context ctx = getContext();
|
||||
AppCache cache = AppCache.getInstance(ctx);
|
||||
OutputStream out;
|
||||
try {
|
||||
out = cache.createCacheFile(uri);
|
||||
out = cache.createCacheFile(ctx, uri);
|
||||
} catch (IOException ioe) {
|
||||
throw new FileNotFoundException(ioe.toString());
|
||||
}
|
||||
@ -244,7 +247,7 @@ public class CacheProvider extends ContentProvider {
|
||||
File file = cache.getCacheFile(uri);
|
||||
if (file.length() > 0) {
|
||||
// this call will insert it back to us (don't set as current base)
|
||||
Uri content = cache.addCacheFile(uri, false);
|
||||
Uri content = cache.addCacheFile(ctx, uri, false);
|
||||
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||
} else {
|
||||
Util.d("CacheProvider Sucess but no data " + uri);
|
||||
@ -252,7 +255,7 @@ public class CacheProvider extends ContentProvider {
|
||||
} else {
|
||||
Util.d("CacheProvider Eepget fail " + uri);
|
||||
}
|
||||
AppCache.getInstance().removeCacheFile(uri);
|
||||
cache.removeCacheFile(ctx, uri);
|
||||
throw new FileNotFoundException("eepget fail");
|
||||
}
|
||||
|
||||
@ -319,7 +322,7 @@ public class CacheProvider extends ContentProvider {
|
||||
for (String key : toDelete) {
|
||||
edit.remove(key);
|
||||
}
|
||||
edit.commit();
|
||||
edit.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,11 +358,10 @@ public class CacheProvider extends ContentProvider {
|
||||
return _sharedPrefs.getString(pref, null);
|
||||
}
|
||||
|
||||
/** @return success */
|
||||
private boolean setPref(String pref, String val) {
|
||||
private void setPref(String pref, String val) {
|
||||
SharedPreferences.Editor edit = _sharedPrefs.edit();
|
||||
edit.putString(pref, val);
|
||||
return edit.commit();
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
/** @return success */
|
||||
|
@ -5,6 +5,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import net.i2p.android.router.util.Util;
|
||||
|
||||
import net.i2p.android.router.I2PConstants;
|
||||
import net.i2p.android.router.service.RouterService;
|
||||
@ -14,12 +15,26 @@ public class OnBootReceiver extends BroadcastReceiver implements I2PConstants {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
|
||||
Util.e("spoofed BOOT_COMPLETED");
|
||||
return;
|
||||
}
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean startOnBoot = prefs.getBoolean(PREF_START_ON_BOOT, false);
|
||||
|
||||
if (startOnBoot) {
|
||||
Intent routerService = new Intent(context, RouterService.class);
|
||||
context.startService(routerService);
|
||||
// Ticket #2404
|
||||
try {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
|
||||
context.startForegroundService(routerService);
|
||||
} else {
|
||||
context.startService(routerService);
|
||||
}
|
||||
} catch (IllegalStateException ex) {
|
||||
Util.e("Error: ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
package net.i2p.android.router.receiver;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.i2p.android.router.service.RouterService;
|
||||
import net.i2p.android.router.util.Util;
|
||||
|
||||
public class RemoteStartReceiver extends BroadcastReceiver {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if(Util.getRouterContext() == null){
|
||||
Intent rsIntent = new Intent(context, RouterService.class);
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
|
||||
context.startForegroundService(rsIntent);
|
||||
} else {
|
||||
context.startService(rsIntent);
|
||||
}
|
||||
Toast.makeText(context, "Starting I2P Router", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package net.i2p.android.router.service;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import net.i2p.android.I2PActivity;
|
||||
import net.i2p.android.I2PActivityBase;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.Notifications;
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.sam.*;
|
||||
import net.i2p.sam.SAMException;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Implements SAMSecureSessionInterface on Android platforms using a Toast
|
||||
* as the interactive channel.
|
||||
*
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public class AndroidSAMSecureSession extends AppCompatActivity implements SAMSecureSessionInterface {
|
||||
private static final String URI_I2P_ANDROID = "net.i2p.android";
|
||||
private final Context mCtx;
|
||||
private final RouterService _routerService;
|
||||
private final StatusBar _statusBar;
|
||||
static private Map<String, Integer> results = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
public static void affirmResult(String clientId) {
|
||||
Util.d("Affirmed result for: " + clientId);
|
||||
results.put(clientId, 1);
|
||||
}
|
||||
|
||||
public AndroidSAMSecureSession(Context ctx, RouterService rCtx, StatusBar statusBar) {
|
||||
mCtx = ctx;
|
||||
_routerService = rCtx;
|
||||
_statusBar = statusBar;
|
||||
}
|
||||
|
||||
private void waitForResult(String clientId) {
|
||||
for (int i=0;i<60;i++) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
Util.e("SAMSecureSession Error", e);
|
||||
}
|
||||
Integer result = results.get(clientId);
|
||||
if (result == null)
|
||||
continue;
|
||||
if (result != -1)
|
||||
break;
|
||||
Util.d("Waiting on user to approve SAM connection for: "+clientId);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isResult(String clientId) {
|
||||
waitForResult(clientId);
|
||||
final Integer finResult = results.get(clientId);
|
||||
if (finResult == null)
|
||||
return false;
|
||||
_routerService.updateStatus();
|
||||
if (finResult == 0) {
|
||||
Util.w("SAM connection cancelled by user request");
|
||||
return false;
|
||||
}
|
||||
if (finResult == 1) {
|
||||
Util.w("SAM connection allowed by user action");
|
||||
return true;
|
||||
}
|
||||
Util.w("SAM connection denied by timeout.");
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkResult(String clientId) {
|
||||
Intent intent = new Intent("net.i2p.android.router.service.APPROVE_SAM", null, mCtx, I2PActivity.class );
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setPackage(URI_I2P_ANDROID);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean("approveSAMConnection", true);
|
||||
bundle.putString("ID", clientId);
|
||||
intent.putExtras(bundle);
|
||||
PendingIntent pendingIntent;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
|
||||
pendingIntent = PendingIntent.getActivity(
|
||||
mCtx, 7656,
|
||||
intent,
|
||||
PendingIntent.FLAG_MUTABLE,
|
||||
bundle);
|
||||
} else {
|
||||
pendingIntent = PendingIntent.getActivity(
|
||||
mCtx, 7656,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT,
|
||||
bundle);
|
||||
}
|
||||
String dlgText = mCtx.getString(R.string.settings_confirm_sam) + "\n";//""</br>";
|
||||
dlgText += mCtx.getString(R.string.settings_confirm_sam_id) + clientId + "\n";//""</br>";
|
||||
dlgText += mCtx.getString(R.string.settings_confirm_allow_sam) + "\n";//""</br>";
|
||||
dlgText += mCtx.getString(R.string.settings_confirm_deny_sam) + "\n";//""</br>";
|
||||
|
||||
|
||||
_statusBar.replaceIntent(StatusBar.ICON_ACTIVE, dlgText, pendingIntent);
|
||||
return isResult(clientId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean approveOrDenySecureSession(Properties i2cpProps, Properties props) throws SAMException {
|
||||
String ID = props.getProperty("USER");
|
||||
if (ID == null)
|
||||
ID = i2cpProps.getProperty("inbound.nickname");
|
||||
if (ID == null)
|
||||
ID = i2cpProps.getProperty("outbound.nickname");
|
||||
if (ID == null)
|
||||
ID = props.getProperty("ID");
|
||||
if (ID == null) {
|
||||
MessageDigest messageDigest = null;
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
ID = "No_ID_Present";
|
||||
}
|
||||
if (messageDigest != null) {
|
||||
String combinedProps = i2cpProps.toString() + props.toString();
|
||||
messageDigest.update(combinedProps.getBytes());
|
||||
ID = messageDigest.digest().toString();
|
||||
}else{
|
||||
ID = "No_ID_Present";
|
||||
}
|
||||
}
|
||||
return checkResult(ID);
|
||||
}
|
||||
}
|
@ -1,20 +1,30 @@
|
||||
package net.i2p.android.router.service;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
|
||||
import net.i2p.BOB.BOB;
|
||||
import net.i2p.I2PAppContext;
|
||||
//import net.i2p.BOB.BOB;
|
||||
import net.i2p.addressbook.DaemonThread;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Looper;
|
||||
import android.preference.PreferenceManager;
|
||||
import net.i2p.android.apps.NewsFetcher;
|
||||
import net.i2p.android.router.service.AndroidSAMSecureSession;
|
||||
import net.i2p.android.router.util.Notifications;
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.i2ptunnel.TunnelControllerGroup;
|
||||
import net.i2p.router.Job;
|
||||
import net.i2p.router.JobImpl;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.sam.SAMBridge;
|
||||
import net.i2p.sam.SAMSecureSessionInterface;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Load the clients we want.
|
||||
@ -22,7 +32,8 @@ import java.io.IOException;
|
||||
* We can't use LoadClientAppsJob (reading in clients.config) directly
|
||||
* because Class.forName() needs a PathClassLoader argument -
|
||||
* http://doandroids.com/blogs/2010/6/10/android-classloader-dynamic-loading-of/
|
||||
* ClassLoader cl = new PathClassLoader(_apkPath, ClassLoader.getSystemClassLoader());
|
||||
* ClassLoader cl = new PathClassLoader(_apkPath,
|
||||
* ClassLoader.getSystemClassLoader());
|
||||
*
|
||||
* We can't extend LoadClientAppsJob to specify a class loader,
|
||||
* even if we use it only for Class.forName() and not for
|
||||
@ -37,47 +48,70 @@ import java.io.IOException;
|
||||
*/
|
||||
class LoadClientsJob extends JobImpl {
|
||||
|
||||
private Context mCtx;
|
||||
private Notifications _notif;
|
||||
private final Context mCtx;
|
||||
private final RouterService _routerService;
|
||||
private final Notifications _notif;
|
||||
private DaemonThread _addressbook;
|
||||
private BOB _bob;
|
||||
public SAMBridge SAM_BRIDGE;
|
||||
private final StatusBar _statusBar;
|
||||
// private BOB _bob;
|
||||
|
||||
/** this is the delay to load (and start) the clients. */
|
||||
private static final long LOAD_DELAY = 90*1000;
|
||||
private static final long LOAD_DELAY = 60 * 1000;
|
||||
|
||||
public LoadClientsJob(Context ctx, RouterContext rCtx, Notifications notif, StatusBar status) {
|
||||
super(rCtx);
|
||||
mCtx = ctx;
|
||||
_routerService = null;
|
||||
_notif = notif;
|
||||
getTiming().setStartAfter(getContext().clock().now() + LOAD_DELAY);
|
||||
_statusBar = status;
|
||||
}
|
||||
|
||||
public LoadClientsJob(Context ctx, RouterContext rCtx, RouterService rSvc, Notifications notif, StatusBar status) {
|
||||
super(rCtx);
|
||||
mCtx = ctx;
|
||||
_routerService = rSvc;
|
||||
_notif = notif;
|
||||
getTiming().setStartAfter(getContext().clock().now() + LOAD_DELAY);
|
||||
_statusBar = status;
|
||||
}
|
||||
|
||||
public LoadClientsJob(Context ctx, RouterContext rCtx, Notifications notif) {
|
||||
super(rCtx);
|
||||
mCtx = ctx;
|
||||
_routerService = null;
|
||||
_notif = notif;
|
||||
getTiming().setStartAfter(getContext().clock().now() + LOAD_DELAY);
|
||||
_statusBar = null;
|
||||
}
|
||||
|
||||
public String getName() { return "Start Clients"; }
|
||||
public String getName() {
|
||||
return "Start Clients";
|
||||
}
|
||||
|
||||
public void runJob() {
|
||||
Job j = new RunI2PTunnel(getContext());
|
||||
getContext().jobQueue().addJob(j);
|
||||
Job jtunnel = new RunI2PTunnel(getContext());
|
||||
getContext().jobQueue().addJob(jtunnel);
|
||||
|
||||
Thread t = new I2PAppThread(new StatSummarizer(), "StatSummarizer", true);
|
||||
t.setPriority(Thread.NORM_PRIORITY - 1);
|
||||
t.start();
|
||||
|
||||
NewsFetcher fetcher = NewsFetcher.getInstance(mCtx, getContext(), _notif);
|
||||
t = new I2PAppThread(fetcher, "NewsFetcher", true);
|
||||
t.start();
|
||||
|
||||
_addressbook = new DaemonThread(new String[] {"addressbook"});
|
||||
_addressbook.setName("Addressbook");
|
||||
_addressbook.setDaemon(true);
|
||||
_addressbook.start();
|
||||
|
||||
// add other clients here
|
||||
_bob = new BOB(I2PAppContext.getGlobalContext(), null, new String[0]);
|
||||
try {
|
||||
_bob.startup();
|
||||
} catch (IOException ioe) {}
|
||||
|
||||
// _bob = new BOB(I2PAppContext.getGlobalContext(), null, new String[0]);
|
||||
// try {
|
||||
// _bob.startup();
|
||||
// } catch (IOException ioe) {}
|
||||
boolean useSAM = PreferenceManager.getDefaultSharedPreferences(mCtx).getBoolean("i2pandroid.client.SAM", true);
|
||||
Util.i("SAM API " + useSAM);
|
||||
if (useSAM) {
|
||||
Job jsam = new RunI2PSAM(getContext());
|
||||
getContext().jobQueue().addJob(jsam);
|
||||
Util.i("SAM API started successfully" + useSAM);
|
||||
} else {
|
||||
Util.i("SAM API disabled, not starting " + useSAM);
|
||||
}
|
||||
getContext().addShutdownTask(new ClientShutdownHook());
|
||||
}
|
||||
|
||||
@ -87,15 +121,35 @@ class LoadClientsJob extends JobImpl {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
public String getName() { return "Start I2P Tunnel"; }
|
||||
public String getName() {
|
||||
return "Start I2P Tunnel";
|
||||
}
|
||||
|
||||
public void runJob() {
|
||||
if (!getContext().router().isRunning()) {
|
||||
if (getContext().router().isAlive()) {
|
||||
requeue(1000);
|
||||
} else {
|
||||
Util.e("Router stopped before i2ptunnel could start");
|
||||
}
|
||||
return;
|
||||
}
|
||||
Util.d("Starting i2ptunnel");
|
||||
TunnelControllerGroup tcg = TunnelControllerGroup.getInstance();
|
||||
TunnelControllerGroup tcg = TunnelControllerGroup.getInstance(getContext());
|
||||
try {
|
||||
tcg.startup();
|
||||
int sz = tcg.getControllers().size();
|
||||
Util.d("i2ptunnel started " + sz + " clients");
|
||||
|
||||
// no use starting these until i2ptunnel starts
|
||||
RouterContext ctx = getContext();
|
||||
NewsFetcher fetcher = NewsFetcher.getInstance(mCtx, getContext(), _notif);
|
||||
ctx.routerAppManager().addAndStart(fetcher, new String[0]);
|
||||
|
||||
_addressbook = new DaemonThread(new String[] { "addressbook" });
|
||||
_addressbook.setName("Addressbook");
|
||||
_addressbook.setDaemon(true);
|
||||
_addressbook.start();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
Util.e("i2ptunnel failed to start", iae);
|
||||
}
|
||||
@ -103,14 +157,62 @@ class LoadClientsJob extends JobImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private class RunI2PSAM extends JobImpl {
|
||||
|
||||
public RunI2PSAM(RouterContext ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "Start SAM API";
|
||||
}
|
||||
|
||||
public void runJob() {
|
||||
if (!getContext().router().isRunning()) {
|
||||
if (getContext().router().isAlive()) {
|
||||
requeue(1000);
|
||||
} else {
|
||||
Util.e("Router stopped before SAM API could start");
|
||||
}
|
||||
return;
|
||||
}
|
||||
Util.d("Starting SAM");
|
||||
try {
|
||||
Util.i("Starting the SAM API");
|
||||
Looper.prepare();
|
||||
AndroidSAMSecureSession _androidSecureSession = new AndroidSAMSecureSession(mCtx, _routerService, _statusBar);
|
||||
SAMSecureSessionInterface _secureSession = _androidSecureSession;
|
||||
SAM_BRIDGE = new SAMBridge("127.0.0.1",
|
||||
7656,
|
||||
false,
|
||||
SAM_PROPERTIES(),
|
||||
"sam.keys",
|
||||
new File("sam_config"),
|
||||
_secureSession);
|
||||
SAM_BRIDGE.run();
|
||||
} catch (IOException e) {
|
||||
Util.e(e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Properties SAM_PROPERTIES() throws IOException {
|
||||
Util.i("Getting the default properties");
|
||||
Properties sam_properties = new Properties();
|
||||
return sam_properties;
|
||||
}
|
||||
}
|
||||
|
||||
private class ClientShutdownHook implements Runnable {
|
||||
public void run() {
|
||||
Util.d("client shutdown hook");
|
||||
// i2ptunnel registers its own hook
|
||||
// StatSummarizer registers its own hook
|
||||
// NewsFetcher registers its own hook
|
||||
if (_bob != null)
|
||||
_bob.shutdown(null);
|
||||
// if (_bob != null)
|
||||
// _bob.shutdown(null);
|
||||
if (SAM_BRIDGE != null)
|
||||
SAM_BRIDGE.shutdown(null);
|
||||
if (_addressbook != null)
|
||||
_addressbook.halt();
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package net.i2p.android.router.service;
|
||||
|
||||
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
@ -105,7 +108,7 @@ public class RouterService extends Service {
|
||||
if(lastState == State.RUNNING || lastState == State.ACTIVE) {
|
||||
Intent intent = new Intent(this, RouterService.class);
|
||||
intent.putExtra(EXTRA_RESTART, true);
|
||||
onStartCommand(intent, 12345, 67890);
|
||||
onStartCommand(intent, START_FLAG_REDELIVERY | START_FLAG_RETRY, 67890);
|
||||
} else if(lastState == State.MANUAL_QUITTING || lastState == State.GRACEFUL_SHUTDOWN) {
|
||||
synchronized(_stateLock) {
|
||||
setState(State.MANUAL_QUITTED);
|
||||
@ -168,10 +171,25 @@ public class RouterService extends Service {
|
||||
}
|
||||
_handler.removeCallbacks(_updater);
|
||||
_handler.postDelayed(_updater, 50);
|
||||
|
||||
// We need to *not* check if we're restarting on Android greater than Oreo due to
|
||||
// changes in how notifications work and the use of NotificationChannels.
|
||||
if(!restart) {
|
||||
startForeground(1337, _statusBar.getNote());
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
startForeground(1337, _statusBar.getNote(), FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
|
||||
} else {
|
||||
startForeground(1337, _statusBar.getNote());
|
||||
}
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
startForeground(1337, _statusBar.getNote());
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
startForeground(1337, _statusBar.getNote(), FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//return START_STICKY;
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
@ -214,6 +232,7 @@ public class RouterService extends Service {
|
||||
// Launch the router!
|
||||
// TODO Store this somewhere instead of relying on global context?
|
||||
Router r = new Router();
|
||||
r.setUPnPScannerCallback(new SSDPLocker(RouterService.this));
|
||||
r.runRouter();
|
||||
synchronized(_stateLock) {
|
||||
if(_state != State.STARTING) {
|
||||
@ -226,7 +245,7 @@ public class RouterService extends Service {
|
||||
throw new IllegalStateException("Router has no context?");
|
||||
}
|
||||
_context.router().setKillVMOnEnd(false);
|
||||
Job loadJob = new LoadClientsJob(RouterService.this, _context, _notif);
|
||||
Job loadJob = new LoadClientsJob(RouterService.this, _context, RouterService.this, _notif, _statusBar);
|
||||
_context.jobQueue().addJob(loadJob);
|
||||
_context.addShutdownTask(new ShutdownHook());
|
||||
_context.addFinalShutdownTask(new FinalShutdownHook());
|
||||
@ -252,6 +271,16 @@ public class RouterService extends Service {
|
||||
private String _currTitle;
|
||||
private boolean _hadTunnels;
|
||||
|
||||
public void updateStatus() {
|
||||
RouterContext ctx = _context;
|
||||
if(ctx != null && (_state == State.RUNNING || _state == State.ACTIVE || _state == State.GRACEFUL_SHUTDOWN)) {
|
||||
Router router = ctx.router();
|
||||
if(router.isAlive()) {
|
||||
updateStatus(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStatus(RouterContext ctx) {
|
||||
int active = ctx.commSystem().countActivePeers();
|
||||
int known = Math.max(ctx.netDb().getKnownRouters() - 1, 0);
|
||||
@ -794,12 +823,12 @@ public class RouterService extends Service {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return success
|
||||
* Saves state in background thread
|
||||
*/
|
||||
private boolean saveState() {
|
||||
private void saveState() {
|
||||
SharedPreferences prefs = getSharedPreferences(SHARED_PREFS, 0);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString(LAST_STATE, _state.toString());
|
||||
return edit.commit();
|
||||
edit.apply();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package net.i2p.android.router.service;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.WifiManager.MulticastLock;
|
||||
|
||||
import net.i2p.router.transport.UPnPScannerCallback;
|
||||
|
||||
/**
|
||||
* To lock/unlock UPnP, so it works on some phones.
|
||||
* Many many phones don't require this, but do be safe...
|
||||
*
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public class SSDPLocker implements UPnPScannerCallback {
|
||||
|
||||
private final MulticastLock lock;
|
||||
|
||||
public SSDPLocker(Context context) {
|
||||
WifiManager wifi = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
||||
lock = wifi.createMulticastLock("ssdp");
|
||||
lock.setReferenceCounted(false);
|
||||
}
|
||||
|
||||
public void beforeScan() {
|
||||
lock.acquire();
|
||||
}
|
||||
|
||||
public void afterScan() {
|
||||
if (lock.isHeld())
|
||||
lock.release();
|
||||
}
|
||||
}
|
@ -1,14 +1,19 @@
|
||||
package net.i2p.android.router.service;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.view.Gravity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.i2p.android.I2PActivity;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.Notifications;
|
||||
|
||||
class StatusBar {
|
||||
|
||||
@ -16,6 +21,9 @@ class StatusBar {
|
||||
private final NotificationManager mNotificationManager;
|
||||
private final NotificationCompat.Builder mNotifyBuilder;
|
||||
private Notification mNotif;
|
||||
private final String NOTIFICATION_CHANNEL_ID = "net.i2p.android.STARTUP_STATE_CHANNEL";
|
||||
private final String channelName = "I2P Router Service";
|
||||
NotificationChannel mNotificationChannel;
|
||||
|
||||
private static final int ID = 1337;
|
||||
|
||||
@ -28,39 +36,90 @@ class StatusBar {
|
||||
|
||||
StatusBar(Context ctx) {
|
||||
mCtx = ctx;
|
||||
mNotificationManager = (NotificationManager) ctx.getSystemService(
|
||||
mNotificationManager = (NotificationManager) mCtx.getSystemService(
|
||||
Context.NOTIFICATION_SERVICE);
|
||||
assert mNotificationManager != null;
|
||||
|
||||
Thread.currentThread().setUncaughtExceptionHandler(
|
||||
new CrashHandler(mNotificationManager));
|
||||
|
||||
int icon = ICON_STARTING;
|
||||
// won't be shown if replace() is called
|
||||
String text = ctx.getString(R.string.notification_status_starting);
|
||||
String text = mCtx.getString(R.string.notification_status_starting);
|
||||
mNotifyBuilder = notifyBuilder(icon, text);
|
||||
}
|
||||
|
||||
mNotifyBuilder = new NotificationCompat.Builder(ctx)
|
||||
.setContentText(text)
|
||||
.setSmallIcon(icon)
|
||||
.setColor(mCtx.getResources().getColor(R.color.primary_light))
|
||||
.setOngoing(true)
|
||||
.setOnlyAlertOnce(true);
|
||||
private NotificationCompat.Builder notifyBuilder(int icon, String text) {
|
||||
NotificationCompat.Builder tNotifyBuilder;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
tNotifyBuilder = new NotificationCompat.Builder(mCtx);
|
||||
} else {
|
||||
tNotifyBuilder = new NotificationCompat.Builder(mCtx, NOTIFICATION_CHANNEL_ID);
|
||||
}
|
||||
tNotifyBuilder.setContentText(text);
|
||||
tNotifyBuilder.setSmallIcon(icon);
|
||||
tNotifyBuilder.setColor(mCtx.getResources().getColor(R.color.primary_light));
|
||||
tNotifyBuilder.setOngoing(true);
|
||||
tNotifyBuilder.setPriority(NotificationManager.IMPORTANCE_LOW);
|
||||
tNotifyBuilder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
|
||||
Intent intent = new Intent(ctx, I2PActivity.class);
|
||||
PendingIntent pi = this.pendingIntent();
|
||||
tNotifyBuilder.setContentIntent(pi);
|
||||
return tNotifyBuilder;
|
||||
}
|
||||
|
||||
private PendingIntent pendingIntent() {
|
||||
Intent intent = new Intent(mCtx, I2PActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent pi = PendingIntent.getActivity(ctx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
mNotifyBuilder.setContentIntent(pi);
|
||||
PendingIntent pi = null;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
|
||||
pi = PendingIntent.getActivity(mCtx,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_MUTABLE);
|
||||
} else {
|
||||
pi = PendingIntent.getActivity(mCtx,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
|
||||
public void replace(int icon, int textResource) {
|
||||
PendingIntent pi = pendingIntent();
|
||||
mNotifyBuilder.setContentIntent(pi);
|
||||
replace(icon, mCtx.getString(textResource));
|
||||
}
|
||||
|
||||
public void replace(int icon, String title) {
|
||||
PendingIntent pi = pendingIntent();
|
||||
mNotifyBuilder.setContentIntent(pi);
|
||||
mNotifyBuilder.setSmallIcon(icon)
|
||||
.setStyle(null)
|
||||
.setTicker(title);
|
||||
update(title);
|
||||
}
|
||||
|
||||
public void replaceIntent(int icon, String text, PendingIntent pi) {
|
||||
mNotifyBuilder.setContentIntent(pi);
|
||||
mNotifyBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
|
||||
mNotifyBuilder.setAutoCancel(true);
|
||||
mNotifyBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
|
||||
mNotifyBuilder.setSmallIcon(icon).setContentText(text);
|
||||
update(null, text);
|
||||
}
|
||||
|
||||
public void replaceIntent(int icon, int textResource, PendingIntent pi) {
|
||||
String text = mCtx.getString(textResource);
|
||||
mNotifyBuilder.setContentIntent(pi);
|
||||
mNotifyBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
|
||||
mNotifyBuilder.setAutoCancel(true);
|
||||
mNotifyBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
|
||||
mNotifyBuilder.setSmallIcon(icon).setContentText(text);
|
||||
update(null, text);
|
||||
}
|
||||
|
||||
public void update(String title) {
|
||||
update(title, null);
|
||||
}
|
||||
@ -72,8 +131,17 @@ class StatusBar {
|
||||
}
|
||||
|
||||
public void update(String title, String text) {
|
||||
mNotifyBuilder.setContentTitle(title)
|
||||
.setContentText(text);
|
||||
if (title != null)
|
||||
mNotifyBuilder.setContentTitle(title);
|
||||
if (text != null)
|
||||
mNotifyBuilder.setContentText(text);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
mNotificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationManager.createNotificationChannel(mNotificationChannel);
|
||||
mNotificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotifyBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
|
||||
//
|
||||
}
|
||||
mNotif = mNotifyBuilder.build();
|
||||
mNotificationManager.notify(ID, mNotif);
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ public class AppCache {
|
||||
private static AppCache _instance;
|
||||
private static File _cacheDir;
|
||||
private static long _totalSize;
|
||||
private static ContentResolver _resolver;
|
||||
/** the LRU cache */
|
||||
private final Map<Integer, Object> _cache;
|
||||
|
||||
@ -62,7 +61,6 @@ public class AppCache {
|
||||
_cacheDir = new File(ctx.getCacheDir(), DIR_NAME);
|
||||
_cacheDir.mkdir();
|
||||
Util.d("AppCache cache dir " + _cacheDir);
|
||||
_resolver = ctx.getContentResolver();
|
||||
_cache = new LHM(MAX_FILES);
|
||||
initialize();
|
||||
}
|
||||
@ -72,9 +70,9 @@ public class AppCache {
|
||||
* addCacheFile() or removeCacheFile() after the data is written.
|
||||
* @param key no fragment allowed
|
||||
*/
|
||||
public OutputStream createCacheFile(Uri key) throws IOException {
|
||||
public OutputStream createCacheFile(Context ctx, Uri key) throws IOException {
|
||||
// remove any old file so the total stays correct
|
||||
removeCacheFile(key);
|
||||
removeCacheFile(ctx, key);
|
||||
File f = toFile(key);
|
||||
f.getParentFile().mkdirs();
|
||||
return new FileOutputStream(f);
|
||||
@ -88,7 +86,7 @@ public class AppCache {
|
||||
* @param key no fragment allowed
|
||||
* @param setAsCurrentBase tell CacheProvider
|
||||
*/
|
||||
public Uri addCacheFile(Uri key, boolean setAsCurrentBase) {
|
||||
public Uri addCacheFile(Context ctx, Uri key, boolean setAsCurrentBase) {
|
||||
int hash = toHash(key);
|
||||
synchronized(_cache) {
|
||||
_cache.put(hash, DUMMY);
|
||||
@ -96,19 +94,19 @@ public class AppCache {
|
||||
// file:/// uri
|
||||
//return Uri.fromFile(toFile(hash)).toString();
|
||||
// content:// uri
|
||||
return insertContent(key, setAsCurrentBase);
|
||||
return insertContent(ctx, key, setAsCurrentBase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a previously written file from the cache index and disk.
|
||||
* @param key no fragment allowed
|
||||
*/
|
||||
public void removeCacheFile(Uri key) {
|
||||
public void removeCacheFile(Context ctx, Uri key) {
|
||||
int hash = toHash(key);
|
||||
synchronized(_cache) {
|
||||
_cache.remove(hash);
|
||||
}
|
||||
deleteContent(key);
|
||||
deleteContent(ctx, key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,7 +116,7 @@ public class AppCache {
|
||||
*
|
||||
* @param key no fragment allowed
|
||||
*/
|
||||
public Uri getCacheUri(Uri key) {
|
||||
public Uri getCacheUri(Context ctx, Uri key) {
|
||||
int hash = toHash(key);
|
||||
// poke the LRU
|
||||
Object present;
|
||||
@ -126,7 +124,7 @@ public class AppCache {
|
||||
present = _cache.get(hash);
|
||||
}
|
||||
if (present != null)
|
||||
setAsCurrentBase(key);
|
||||
setAsCurrentBase(ctx, key);
|
||||
return CacheProvider.getContentUri(key);
|
||||
}
|
||||
|
||||
@ -242,7 +240,7 @@ public class AppCache {
|
||||
/**
|
||||
* @return the uri inserted or null on failure
|
||||
*/
|
||||
private static Uri insertContent(Uri key, boolean setAsCurrentBase) {
|
||||
private static Uri insertContent(Context ctx, Uri key, boolean setAsCurrentBase) {
|
||||
String path = toFile(key).getAbsolutePath();
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(CacheProvider.DATA, path);
|
||||
@ -250,8 +248,9 @@ public class AppCache {
|
||||
cv.put(CacheProvider.CURRENT_BASE, Boolean.TRUE);
|
||||
Uri uri = CacheProvider.getContentUri(key);
|
||||
if (uri != null) {
|
||||
_resolver.insert(uri, cv);
|
||||
return uri;
|
||||
ContentResolver resolver = ctx.getContentResolver();
|
||||
resolver.insert(uri, cv);
|
||||
return uri;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -259,19 +258,23 @@ public class AppCache {
|
||||
/**
|
||||
* Set key as current base. May be content or i2p key.
|
||||
*/
|
||||
private static void setAsCurrentBase(Uri key) {
|
||||
private static void setAsCurrentBase(Context ctx, Uri key) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(CacheProvider.CURRENT_BASE, Boolean.TRUE);
|
||||
Uri uri = CacheProvider.getContentUri(key);
|
||||
if (uri != null)
|
||||
_resolver.insert(uri, cv);
|
||||
if (uri != null) {
|
||||
ContentResolver resolver = ctx.getContentResolver();
|
||||
resolver.insert(uri, cv);
|
||||
}
|
||||
}
|
||||
|
||||
/** ok for now but we will need to store key in the map and delete by integer */
|
||||
private static void deleteContent(Uri key) {
|
||||
private static void deleteContent(Context ctx, Uri key) {
|
||||
Uri uri = CacheProvider.getContentUri(key);
|
||||
if (uri != null)
|
||||
_resolver.delete(uri, null, null);
|
||||
if (uri != null) {
|
||||
ContentResolver resolver = ctx.getContentResolver();
|
||||
resolver.delete(uri, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,20 +32,50 @@ public class NamingServiceUtil {
|
||||
String kDest = res.getString(R.string.addressbook_add_wizard_k_destination);
|
||||
|
||||
String hostName = data.getBundle(kHostName).getString(Page.SIMPLE_DATA_KEY);
|
||||
String host = toASCII(res, hostName); // Already validated, won't throw IAE
|
||||
String host;
|
||||
try {
|
||||
// Already validated, won't throw IAE
|
||||
// ^^^ NOT TRUE ticket #2489 ^^^
|
||||
host = toASCII(res, hostName);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
Toast.makeText(ctx,
|
||||
iae.getMessage(),
|
||||
Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
String displayHost = host.equals(hostName) ? hostName :
|
||||
hostName + " (" + host + ')';
|
||||
|
||||
String destB64 = data.getBundle(kDest).getString(Page.SIMPLE_DATA_KEY);
|
||||
Destination dest = new Destination();
|
||||
try {
|
||||
dest.fromBase64(destB64);
|
||||
} catch (DataFormatException e) {} // Already validated
|
||||
|
||||
String dest = data.getBundle(kDest).getString(Page.SIMPLE_DATA_KEY).split(":")[0];
|
||||
Destination destination = new Destination();
|
||||
if (dest.endsWith(".b32.i2p")) {
|
||||
NamingService dns = NamingServiceUtil.getNamingService(Util.getRouterContext(),"");
|
||||
destination = dns.lookup(dest);
|
||||
int i = 0;
|
||||
while (destination == null) {
|
||||
dns = NamingServiceUtil.getNamingService(Util.getRouterContext(),"");
|
||||
destination = dns.lookup(dest);
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
i++;
|
||||
if (i > 500){
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
destination.fromBase64(dest);
|
||||
} catch (DataFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// Check if already in addressbook
|
||||
Destination oldDest = ns.lookup(host);
|
||||
if (oldDest != null) {
|
||||
if (destB64.equals(oldDest.toBase64()))
|
||||
if (destination.toBase64().equals(oldDest.toBase64()))
|
||||
Toast.makeText(ctx,
|
||||
"Host name " + displayHost + " is already in address book, unchanged.",
|
||||
Toast.LENGTH_LONG).show();
|
||||
@ -55,7 +85,7 @@ public class NamingServiceUtil {
|
||||
Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
// Put the new host name
|
||||
success = ns.put(host, dest);
|
||||
success = ns.put(host, destination);
|
||||
if (!success)
|
||||
Toast.makeText(ctx,
|
||||
"Failed to add Destination " + displayHost + " to naming service " + ns.getName(),
|
||||
|
@ -2,16 +2,20 @@ package net.i2p.android.router.util;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
public class Notifications {
|
||||
private final Context mCtx;
|
||||
private final NotificationManager mNotificationManager;
|
||||
|
||||
|
||||
|
||||
public static final int ICON = R.drawable.ic_stat_router_active;
|
||||
|
||||
public Notifications(Context ctx) {
|
||||
@ -25,18 +29,36 @@ public class Notifications {
|
||||
}
|
||||
|
||||
public void notify(String title, String text, Class<?> c) {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(mCtx)
|
||||
.setContentTitle(title)
|
||||
.setContentText(text)
|
||||
.setSmallIcon(ICON)
|
||||
.setColor(mCtx.getResources().getColor(R.color.primary_light))
|
||||
.setAutoCancel(true);
|
||||
notify(title, text, "", c);
|
||||
}
|
||||
|
||||
public void notify(String title, String text, String channel, Class<?> c) {
|
||||
NotificationCompat.Builder b;
|
||||
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
b = new NotificationCompat.Builder(mCtx);
|
||||
} else {
|
||||
if (channel.equals("")){
|
||||
b = new NotificationCompat.Builder(mCtx);
|
||||
} else {
|
||||
b = new NotificationCompat.Builder(mCtx, channel);
|
||||
}
|
||||
}
|
||||
|
||||
b.setContentTitle(title);
|
||||
b.setContentText(text);
|
||||
b.setSmallIcon(ICON);
|
||||
b.setColor(mCtx.getResources().getColor(R.color.primary_light));
|
||||
b.setAutoCancel(true);
|
||||
|
||||
if (c != null) {
|
||||
Intent intent = new Intent(mCtx, c);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent pi = PendingIntent.getActivity(mCtx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PendingIntent pi;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
|
||||
pi = PendingIntent.getActivity(mCtx, 0, intent, PendingIntent.FLAG_MUTABLE);
|
||||
} else {
|
||||
pi = PendingIntent.getActivity(mCtx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
b.setContentIntent(pi);
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
@ -185,9 +186,9 @@ public abstract class Util implements I2PConstants {
|
||||
toRemove.setProperty("routerconsole.lang", "");
|
||||
toRemove.setProperty("routerconsole.country", "");
|
||||
} else {
|
||||
routerProps.setProperty("routerconsole.lang", language[0].toLowerCase());
|
||||
routerProps.setProperty("routerconsole.lang", language[0].toLowerCase(Locale.US));
|
||||
if (language.length == 2)
|
||||
routerProps.setProperty("routerconsole.country", language[1].toUpperCase());
|
||||
routerProps.setProperty("routerconsole.country", language[1].toUpperCase(Locale.US));
|
||||
else
|
||||
toRemove.setProperty("routerconsole.country", "");
|
||||
}
|
||||
@ -445,10 +446,15 @@ public abstract class Util implements I2PConstants {
|
||||
case IPV4_UNKNOWN_IPV6_OK:
|
||||
case IPV4_DISABLED_IPV6_OK:
|
||||
case IPV4_SNAT_IPV6_OK:
|
||||
RouterAddress ra = routerInfo.getTargetAddress("NTCP");
|
||||
if (ra == null)
|
||||
List<RouterAddress> ras = routerInfo.getTargetAddresses("NTCP", "NTCP2");
|
||||
if (ras.isEmpty())
|
||||
return new NetStatus(NetStatus.Level.INFO, toStatusString(ctx, status));
|
||||
byte[] ip = ra.getIP();
|
||||
byte[] ip = null;
|
||||
for (RouterAddress ra : ras) {
|
||||
ip = ra.getIP();
|
||||
if (ip != null)
|
||||
break;
|
||||
}
|
||||
if (ip == null)
|
||||
return new NetStatus(NetStatus.Level.ERROR, ctx.getString(R.string.net_status_error_unresolved_tcp));
|
||||
// TODO set IPv6 arg based on configuration?
|
||||
@ -462,7 +468,7 @@ public abstract class Util implements I2PConstants {
|
||||
|
||||
case REJECT_UNSOLICITED:
|
||||
case IPV4_DISABLED_IPV6_FIREWALLED:
|
||||
if (routerInfo.getTargetAddress("NTCP") != null)
|
||||
if (routerInfo.getTargetAddresses("NTCP", "NTCP2").isEmpty())
|
||||
return new NetStatus(NetStatus.Level.WARN, ctx.getString(R.string.net_status_warn_firewalled_inbound_tcp));
|
||||
// fall through...
|
||||
case IPV4_FIREWALLED_IPV6_OK:
|
||||
@ -483,7 +489,7 @@ public abstract class Util implements I2PConstants {
|
||||
case IPV4_UNKNOWN_IPV6_FIREWALLED:
|
||||
case IPV4_DISABLED_IPV6_UNKNOWN:
|
||||
default:
|
||||
ra = routerInfo.getTargetAddress("SSU");
|
||||
RouterAddress ra = routerInfo.getTargetAddress("SSU");
|
||||
if (ra == null && rCtx.router().getUptime() > 5 * 60 * 1000) {
|
||||
if (rCtx.commSystem().countActivePeers() <= 0)
|
||||
return new NetStatus(NetStatus.Level.ERROR, ctx.getString(R.string.net_status_error_no_active_peers));
|
||||
|
@ -28,10 +28,11 @@ import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
public class I2PWebViewClient extends WebViewClient {
|
||||
|
||||
private Fragment _parentFrag;
|
||||
private final Fragment _parentFrag;
|
||||
private BGLoad _lastTask;
|
||||
/** save it here so we can dismiss it in onPageFinished() */
|
||||
private ProgressDialog _lastDialog;
|
||||
@ -76,7 +77,7 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
fail(view, "Bad URL " + url);
|
||||
return true;
|
||||
}
|
||||
s = s.toLowerCase();
|
||||
s = s.toLowerCase(Locale.US);
|
||||
if (!(s.equals("http") || s.equals("https") ||
|
||||
s.equals(CONTENT))) {
|
||||
Util.d("Not loading URL " + url);
|
||||
@ -93,7 +94,7 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
return true;
|
||||
}
|
||||
|
||||
h = h.toLowerCase();
|
||||
h = h.toLowerCase(Locale.US);
|
||||
if (h.endsWith(".i2p")) {
|
||||
if (!s.equals("http")) {
|
||||
fail(view, "Bad URL " + url);
|
||||
@ -211,7 +212,8 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
//reverse back to a i2p URI so we can delete it from the AppCache
|
||||
uri = CacheProvider.getI2PUri(uri);
|
||||
Util.d("clearing AppCache entry for current page " + uri);
|
||||
AppCache.getInstance(view.getContext()).removeCacheFile(uri);
|
||||
Context ctx = view.getContext();
|
||||
AppCache.getInstance(ctx).removeCacheFile(ctx, uri);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// this actually only deletes the row in the provider,
|
||||
// not the actual file, but it will be overwritten in the reload.
|
||||
@ -315,9 +317,10 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
protected Integer doInBackground(String... urls) {
|
||||
final String url = urls[0];
|
||||
Uri uri = Uri.parse(url);
|
||||
File cacheFile = AppCache.getInstance(_ctx).getCacheFile(uri);
|
||||
final AppCache cache = AppCache.getInstance(_ctx);
|
||||
File cacheFile = cache.getCacheFile(uri);
|
||||
if (cacheFile.exists()) {
|
||||
final Uri resUri = AppCache.getInstance(_ctx).getCacheUri(uri);
|
||||
final Uri resUri = cache.getCacheUri(_ctx, uri);
|
||||
Util.d("Loading " + url + " from resource cache " + resUri);
|
||||
_view.post(new Runnable() {
|
||||
@Override
|
||||
@ -335,7 +338,7 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
//EepGetFetcher fetcher = new EepGetFetcher(url);
|
||||
OutputStream out = null;
|
||||
try {
|
||||
out = AppCache.getInstance(_ctx).createCacheFile(uri);
|
||||
out = cache.createCacheFile(_ctx, uri);
|
||||
// write error to stream
|
||||
EepGetFetcher fetcher = new EepGetFetcher(url, out, true);
|
||||
fetcher.addStatusListener(this);
|
||||
@ -348,11 +351,11 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
if (success) {
|
||||
// store in cache, get content URL, and load that way
|
||||
// Set as current base
|
||||
final Uri content = AppCache.getInstance(_ctx).addCacheFile(uri, true);
|
||||
final Uri content = cache.addCacheFile(_ctx, uri, true);
|
||||
if (content != null) {
|
||||
Util.d("Stored cache in " + content);
|
||||
} else {
|
||||
AppCache.getInstance(_ctx).removeCacheFile(uri);
|
||||
cache.removeCacheFile(_ctx, uri);
|
||||
Util.d("cache create error");
|
||||
return 0;
|
||||
}
|
||||
@ -391,7 +394,7 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
AppCache.getInstance(_ctx).removeCacheFile(uri);
|
||||
cache.removeCacheFile(_ctx, uri);
|
||||
Util.d("loading error data URL: " + url);
|
||||
final String finalMsg = msg;
|
||||
_view.post(new Runnable() {
|
||||
@ -439,8 +442,9 @@ public class I2PWebViewClient extends WebViewClient {
|
||||
} else {
|
||||
// nothing
|
||||
}
|
||||
} catch (IllegalArgumentException iae) {
|
||||
} catch (RuntimeException iae) {
|
||||
// throws IAE - not attached to window manager - perhaps due to screen rotation?
|
||||
// Also includes android.view.WindowManager$BadTokenException extends RuntimeException
|
||||
Util.e("Error while updating I2PWebViewClient dialog", iae);
|
||||
}
|
||||
}
|
||||
|
@ -49,19 +49,21 @@ public class WebFragment extends I2PFragmentBase {
|
||||
wv.getSettings().setBuiltInZoomControls(true);
|
||||
// http://stackoverflow.com/questions/2369310/webview-double-tap-zoom-not-working-on-a-motorola-droid-a855
|
||||
wv.getSettings().setUseWideViewPort(true);
|
||||
_uriStr = getArguments().getString(HTML_URI);
|
||||
if (_uriStr != null) {
|
||||
Uri uri = Uri.parse(_uriStr);
|
||||
//wv.getSettings().setLoadsImagesAutomatically(true);
|
||||
//wv.loadUrl(uri.toString());
|
||||
// go thru the client so .i2p will work too
|
||||
_wvClient.shouldOverrideUrlLoading(wv, uri.toString());
|
||||
} else {
|
||||
wv.getSettings().setLoadsImagesAutomatically(false);
|
||||
int id = getArguments().getInt(HTML_RESOURCE_ID, 0);
|
||||
// no default, so restart should keep previous view
|
||||
if (id != 0)
|
||||
loadResource(wv, id);
|
||||
if (getArguments() != null) {
|
||||
_uriStr = getArguments().getString(HTML_URI);
|
||||
if (_uriStr != null) {
|
||||
Uri uri = Uri.parse(_uriStr);
|
||||
//wv.getSettings().setLoadsImagesAutomatically(true);
|
||||
//wv.loadUrl(uri.toString());
|
||||
// go thru the client so .i2p will work too
|
||||
_wvClient.shouldOverrideUrlLoading(wv, uri.toString());
|
||||
} else {
|
||||
wv.getSettings().setLoadsImagesAutomatically(false);
|
||||
int id = getArguments().getInt(HTML_RESOURCE_ID, 0);
|
||||
// no default, so restart should keep previous view
|
||||
if (id != 0)
|
||||
loadResource(wv, id);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import com.eowise.recyclerview.stickyheaders.StickyHeadersAdapter;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
@ -49,7 +51,7 @@ public class AlphanumericHeaderAdapter implements StickyHeadersAdapter<Alphanume
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder headerViewHolder, int position) {
|
||||
String sortString = mAdapter.getSortString(position).toUpperCase();
|
||||
String sortString = mAdapter.getSortString(position).toUpperCase(Locale.getDefault());
|
||||
if (sortString.isEmpty())
|
||||
headerViewHolder.itemView.setVisibility(View.GONE);
|
||||
else {
|
||||
@ -63,7 +65,7 @@ public class AlphanumericHeaderAdapter implements StickyHeadersAdapter<Alphanume
|
||||
|
||||
@Override
|
||||
public long getHeaderId(int position) {
|
||||
String sortString = mAdapter.getSortString(position).toUpperCase();
|
||||
String sortString = mAdapter.getSortString(position).toUpperCase(Locale.getDefault());
|
||||
if (sortString.isEmpty())
|
||||
return Integer.MAX_VALUE;
|
||||
|
||||
|
@ -3,19 +3,17 @@ package net.i2p.android.util;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.util.SparseArray;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class MemoryFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||
private FragmentManager mFragmentManager;
|
||||
private Map<Integer, String> mFragmentTags;
|
||||
private final FragmentManager mFragmentManager;
|
||||
private final SparseArray<String> mFragmentTags;
|
||||
|
||||
public MemoryFragmentPagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
mFragmentManager = fm;
|
||||
mFragmentTags = new HashMap<>();
|
||||
mFragmentTags = new SparseArray<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,10 +30,10 @@ import java.util.List;
|
||||
* To create an actual wizard model, extend this class and implement {@link #onNewRootPageList()}.
|
||||
*/
|
||||
public abstract class AbstractWizardModel implements ModelCallbacks {
|
||||
protected Context mContext;
|
||||
protected final Context mContext;
|
||||
|
||||
private List<ModelCallbacks> mListeners = new ArrayList<ModelCallbacks>();
|
||||
private PageList mRootPageList;
|
||||
private final List<ModelCallbacks> mListeners = new ArrayList<ModelCallbacks>();
|
||||
private final PageList mRootPageList;
|
||||
|
||||
public AbstractWizardModel(Context context) {
|
||||
mContext = context;
|
||||
@ -67,7 +67,10 @@ public abstract class AbstractWizardModel implements ModelCallbacks {
|
||||
|
||||
public void load(Bundle savedValues) {
|
||||
for (String key : savedValues.keySet()) {
|
||||
mRootPageList.findByKey(key).resetData(savedValues.getBundle(key));
|
||||
// Expanded the code to hunt NPE - Ticket #2389
|
||||
Page tmp = mRootPageList.findByKey(key);
|
||||
Bundle tmpBundle = savedValues.getBundle(key);
|
||||
tmp.resetData(tmpBundle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
package net.i2p.android.wizard.model;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import net.i2p.android.wizard.ui.I2PB64DestinationFragment;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
|
||||
/**
|
||||
* A page asking for an I2P Destination.
|
||||
* This must be the B64 representation of a Destination.
|
||||
*/
|
||||
public class I2PB64DestinationPage extends SingleTextFieldPage {
|
||||
private String mFeedback;
|
||||
|
||||
public I2PB64DestinationPage(ModelCallbacks callbacks, String title) {
|
||||
super(callbacks, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment createFragment() {
|
||||
return I2PB64DestinationFragment.create(getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
String data = mData.getString(SIMPLE_DATA_KEY);
|
||||
try {
|
||||
new Destination().fromBase64(data);
|
||||
} catch (DataFormatException dfe) {
|
||||
mFeedback = "Invalid B64";
|
||||
return false;
|
||||
}
|
||||
mFeedback = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showFeedback() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeedback() {
|
||||
return mFeedback;
|
||||
}
|
||||
}
|
@ -4,9 +4,12 @@ import java.util.Locale;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.android.wizard.ui.I2PDestinationFragment;
|
||||
import net.i2p.client.naming.NamingService;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.client.naming.DummyNamingService;
|
||||
|
||||
/**
|
||||
* A page asking for an I2P Destination.
|
||||
@ -27,12 +30,20 @@ public class I2PDestinationPage extends SingleTextFieldPage {
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
String data = mData.getString(SIMPLE_DATA_KEY);
|
||||
String data = mData.getString(SIMPLE_DATA_KEY).split(":")[0];
|
||||
if (data.toLowerCase(Locale.US).endsWith(".b32.i2p")) { /* B32 */
|
||||
if (data.length() != BASE32_HASH_LENGTH + 8) {
|
||||
mFeedback = "Invalid B32";
|
||||
return false;
|
||||
if (data.length() == BASE32_HASH_LENGTH){
|
||||
mFeedback = "";
|
||||
return true;
|
||||
}
|
||||
if (data.length() >= BASE32_HASH_LENGTH + 8) {
|
||||
if (data.length() <= BASE32_HASH_LENGTH + 12) {
|
||||
mFeedback = "";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mFeedback = "Invalid B32";
|
||||
return false;
|
||||
} else if (data.endsWith(".i2p")) { /* Domain */
|
||||
// Valid
|
||||
} else if (data.length() >= 516) { /* B64 */
|
||||
|
@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 str4d
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.i2p.android.wizard.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.android.wizard.model.Page;
|
||||
import net.i2p.android.wizard.model.SingleTextFieldPage;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class I2PB64DestinationFragment extends Fragment {
|
||||
static final int REQUEST_DESTINATION_FILE = 1;
|
||||
|
||||
private static final String ARG_KEY = "key";
|
||||
|
||||
private PageFragmentCallbacks mCallbacks;
|
||||
private SingleTextFieldPage mPage;
|
||||
protected TextView mFieldView;
|
||||
private TextView mFeedbackView;
|
||||
|
||||
public static I2PB64DestinationFragment create(String key) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_KEY, key);
|
||||
|
||||
I2PB64DestinationFragment fragment = new I2PB64DestinationFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public I2PB64DestinationFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Bundle args = getArguments();
|
||||
String mKey = args.getString(ARG_KEY);
|
||||
mPage = (SingleTextFieldPage) mCallbacks.onGetPage(mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_wizard_page_single_text_field_picker, container, false);
|
||||
((TextView) rootView.findViewById(android.R.id.title)).setText(mPage.getTitle());
|
||||
((TextView) rootView.findViewById(R.id.wizard_text_field_desc)).setText(mPage.getDesc());
|
||||
|
||||
Button b = (Button) rootView.findViewById(R.id.wizard_text_field_pick);
|
||||
b.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
public void onClick(View view) {
|
||||
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
i.setType("text/plain");
|
||||
i.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
try {
|
||||
startActivityForResult(
|
||||
Intent.createChooser(i,"Select B64 file"),
|
||||
REQUEST_DESTINATION_FILE);
|
||||
} catch (android.content.ActivityNotFoundException ex) {
|
||||
Toast.makeText(getActivity(), "Please install a File Manager.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mFieldView = ((TextView) rootView.findViewById(R.id.wizard_text_field));
|
||||
mFieldView.setHint(mPage.getTitle());
|
||||
if (mPage.getData().getString(Page.SIMPLE_DATA_KEY) != null)
|
||||
mFieldView.setText(mPage.getData().getString(Page.SIMPLE_DATA_KEY));
|
||||
else if (mPage.getDefault() != null) {
|
||||
mFieldView.setText(mPage.getDefault());
|
||||
mPage.getData().putString(Page.SIMPLE_DATA_KEY, mPage.getDefault());
|
||||
}
|
||||
|
||||
mFeedbackView = (TextView) rootView.findViewById(R.id.wizard_text_field_feedback);
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
if (!(activity instanceof PageFragmentCallbacks)) {
|
||||
throw new ClassCastException("Activity must implement PageFragmentCallbacks");
|
||||
}
|
||||
|
||||
mCallbacks = (PageFragmentCallbacks) activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mCallbacks = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
mFieldView.addTextChangedListener(new TextWatcher() {
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1,
|
||||
int i2) {
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
}
|
||||
|
||||
public void afterTextChanged(Editable editable) {
|
||||
mPage.getData().putString(Page.SIMPLE_DATA_KEY,
|
||||
(editable != null) ? editable.toString() : null);
|
||||
mPage.notifyDataChanged();
|
||||
if (mPage.showFeedback()) {
|
||||
mFeedbackView.setText(mPage.getFeedback());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
|
||||
// In a future update to the support library, this should override setUserVisibleHint
|
||||
// instead of setMenuVisibility.
|
||||
if (mFieldView != null) {
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
|
||||
Context.INPUT_METHOD_SERVICE);
|
||||
if (!menuVisible) {
|
||||
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == REQUEST_DESTINATION_FILE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Uri result = data.getData();
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
ParcelFileDescriptor pfd = getActivity().getContentResolver().openFileDescriptor(result, "r");
|
||||
br = new BufferedReader(
|
||||
new InputStreamReader(
|
||||
new ParcelFileDescriptor.AutoCloseInputStream(pfd)));
|
||||
try {
|
||||
mFieldView.setText(br.readLine());
|
||||
} catch (IOException ioe) {
|
||||
Util.e("Failed to read B64 file", ioe);
|
||||
Toast.makeText(getActivity(), "Failed to read B64 file.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
Util.e("Could not find B64 file", fnfe);
|
||||
Toast.makeText(getActivity(), "Could not find B64 file.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} catch (SecurityException se) {
|
||||
Util.e("Could not open B64 file", se);
|
||||
Toast.makeText(getActivity(), "Could not open B64 file.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (br != null)
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,10 +5,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.viewpagerindicator.TitlePageIndicator
|
||||
android:id="@+id/page_indicator"
|
||||
style="@style/PagerIndicator" />
|
||||
|
||||
<!-- The main content view -->
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
|
@ -29,10 +29,6 @@
|
||||
android:layout_weight="2"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.viewpagerindicator.TitlePageIndicator
|
||||
android:id="@+id/page_indicator"
|
||||
style="@style/PagerIndicator" />
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -4,17 +4,12 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.viewpagerindicator.TitlePageIndicator
|
||||
android:id="@+id/page_indicator"
|
||||
style="@style/PagerIndicator" />
|
||||
|
||||
<!-- The main content view -->
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_below="@id/page_indicator" />
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
<net.i2p.android.ext.floatingactionbutton.AddFloatingActionButton
|
||||
android:id="@+id/promoted_action"
|
||||
|
@ -64,13 +64,13 @@
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/about_donate" />
|
||||
android:text="@string/about_gitlab" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/url_donate"
|
||||
android:id="@+id/url_gitlab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/url_donate" />
|
||||
android:text="@string/url_gitlab" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
android:layout_toRightOf="@id/tunnel_name"
|
||||
android:ellipsize="start"
|
||||
android:gravity="end"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:text="Interface:port"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Secondary" />
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:ellipsize="marquee"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:text="RouterInfo hash"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Privacy Brower has native I2P support!</h2>
|
||||
<p>Make sure your I2P router is started before launching Privacy Browser</p>
|
||||
<p>Privacy Browser supports both I2P and Orbot (Tor), but not at the same time.</p>
|
||||
<h2>How to configure Privacy Browser:</h2>
|
||||
<ol>
|
||||
<li>Open the main menu and tap “Settings”</li>
|
||||
<li>Select "Disable Javascript"(Recommended)</li>
|
||||
<li>Select "Enable Incognito Mode"(Optional)</li>
|
||||
<li>Tap the "Proxy" menu item and select "I2P" from the submenu</li>
|
||||
<li>Exit the settings menu.</li>
|
||||
</ol>
|
||||
<a href="https://eyedeekay.github.io/Configuring-Privacy-Browser-for-I2P-on-Android/">A detailed guide with screenshots to is available online</a>
|
||||
</body>
|
||||
</html>
|
@ -11,7 +11,7 @@
|
||||
</ul>
|
||||
|
||||
<h2>Using clients with pre-configured tunnels</h2>
|
||||
<p>The app starts an HTTP proxy tunnel at localhost port 4444 and IRC client tunnels at localhost ports 6668 - 6672. The IRC clients are "shared clients" on the same tunnels. Once you see the tunnel icon turn green on the main console (several minutes after startup), you should be able to connect.</p>
|
||||
<p>The app starts an HTTP proxy tunnel at 127.0.0.1 port 4444 and IRC client tunnels at 127.0.0.1 ports 6668 - 6672. The IRC clients are "shared clients" on the same tunnels. Once you see the tunnel icon turn green on the main console (several minutes after startup), you should be able to connect.</p>
|
||||
|
||||
<h2>What does the clock icon on a yellow background mean?</h2>
|
||||
<p>When a tunnel's indicator is yellow with a clock icon, the tunnel is in standby mode. This means that I2P has not built the tunnel yet, but will do so automatically when you start using it. This helps to minimize resource use and conserve battery life.</p>
|
||||
|
@ -1,11 +1,11 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure Orweb:</h2>
|
||||
<ol>
|
||||
<li>Open Orweb's settings menu.</li>
|
||||
<li>Change the "Proxy Port" to <code>4444</code>.</li>
|
||||
<li>Exit Orweb using the back button, then open it again.</li>
|
||||
</ol>
|
||||
<h2>Sorry, this browser is unsupported</h2>
|
||||
<ul>
|
||||
<li>OrFox has been deprecated by the Guardian Project in favor of Tor
|
||||
Browser for Android. It is no longer supported.
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -1,17 +1,11 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure Orfox:</h2>
|
||||
<ol>
|
||||
<li>Install the ProxyMob add-on. Click <a
|
||||
href="https://guardianproject.info/downloads/proxymob.xpi">HERE</a>, and choose to open
|
||||
the URL in Firefox.
|
||||
<h2>Sorry, this browser is unsupported</h2>
|
||||
<ul>
|
||||
<li>OrFox has been deprecated by the Guardian Project in favor of Tor
|
||||
Browser for Android. It is no longer supported.
|
||||
</li>
|
||||
<li>In the main Firefox menu, click "Tools", then "Add-ons".</li>
|
||||
<li>Click on "Proxy Mobile".</li>
|
||||
<li>Change the value of "HTTP Proxy Port" to <code>4444</code>.</li>
|
||||
<li>Change the value of "HTTPS Proxy Port" to <code>4444</code>.</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure IceRaven for Android:</h2>
|
||||
<h3>Configuration via Webextension</h3>
|
||||
<ol>
|
||||
<li>Open IceRaven and click the main menu. Scroll to the top, and tap the "Add-Ons" submenu.</li>
|
||||
<li>Tap on the "Add-Ons Manager" option.</li>
|
||||
<li>Find the "I2P Proxy for Android and Other" extension in the Add-Ons collection and tap on the <code>+</code> symbol</li>
|
||||
<li>You can now browse I2P Sites!</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
@ -9,8 +9,8 @@
|
||||
<p>With this app installed, other apps that are designed for I2P will use it automatically.</p>
|
||||
|
||||
<h2>Pre-configured HTTP proxy</h2>
|
||||
<p>The app starts an HTTP proxy at localhost port 4444. To use it, configure your browser's HTTP proxy setting to use localhost:4444.</p>
|
||||
<p>The app starts an HTTP proxy at 127.0.0.1 port 4444. To use it, configure your browser's HTTP proxy setting to use 127.0.0.1:4444.</p>
|
||||
<p>The HTTP proxy is tested with the "Orweb" app. It should also work with Firefox 4 Mobile and the ProxyMob Firefox plugin, if you have at least 512 MB of RAM.</p>
|
||||
<p>See the "Browser configuration" help page for more info.</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
34
app/src/main/res/raw/help_org_gnu_icecat.html
Normal file
34
app/src/main/res/raw/help_org_gnu_icecat.html
Normal file
@ -0,0 +1,34 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure GNU IceCat:</h2>
|
||||
<ol>
|
||||
<li>Click <a href="about:config?filter=network.proxy">HERE</a>, and choose to open the URL in IceCatMobile.</li>
|
||||
<li>Change the value of "network.proxy.type" to <code>1</code>.</li>
|
||||
<li>Change the value of "network.proxy.http" to <code>127.0.0.1</code>.</li>
|
||||
<li>Change the value of "network.proxy.http_port" to <code>4444</code>.</li>
|
||||
<li>Change the value of "network.proxy.ssl" to <code>127.0.0.1</code>.</li>
|
||||
<li>Change the value of "network.proxy.ssl_port" to <code>4444</code>.</li>
|
||||
<li>Change the value of "media.peerconnection.ice.proxy_only" to <code>true</code>.</li>
|
||||
<li>You may also wish to install plugins to help manage your browser's
|
||||
default javascript settings, such as NoScript and/or uMatrix, and use
|
||||
Private Browsing to manage your browser's cache.
|
||||
</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
<h3>Alternate Configuration(Requires Root!)</h3>
|
||||
<ol>
|
||||
<li>Install <a href="https://github.com/v1nc/user.js-updater">user.js-updater</a></li>
|
||||
<li>Select IceCatMobile from the list of browsers</li>
|
||||
<li>Paste the following URL where it says "type custom user.js url" <a href="https://github.com/eyedeekay/firefox.profile.i2p/raw/master/firefox.profile.i2p/user.js">https://github.com/eyedeekay/firefox.profile.i2p/raw/master/firefox.profile.i2p/user.js</a></li>
|
||||
<li>Tap "Update"</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
<h3>Rootless Configuration via Webextension</h3>
|
||||
<ol>
|
||||
<li>Open this link in GNU IceCat and get the WebExtension from <a href="https://github.com/eyedeekay/i2psetproxy.js/releases">Github</a></li>
|
||||
<li>Click through the "Blocked Extension" warning</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
34
app/src/main/res/raw/help_org_mozilla_fennec_fdroid.html
Normal file
34
app/src/main/res/raw/help_org_mozilla_fennec_fdroid.html
Normal file
@ -0,0 +1,34 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure Fennec Firefox:</h2>
|
||||
<ol>
|
||||
<li>Click <a href="about:config?filter=proxy">HERE</a>, and choose to open the URL in Fennec.</li>
|
||||
<li>Change the value of "network.proxy.type" to <code>1</code>.</li>
|
||||
<li>Change the value of "network.proxy.http" to <code>127.0.0.1</code>.</li>
|
||||
<li>Change the value of "network.proxy.http_port" to <code>4444</code>.</li>
|
||||
<li>Change the value of "network.proxy.ssl" to <code>127.0.0.1</code>.</li>
|
||||
<li>Change the value of "network.proxy.ssl_port" to <code>4444</code>.</li>
|
||||
<li>Change the value of "media.peerconnection.ice.proxy_only" to <code>true</code>.</li>
|
||||
<li>You may also wish to install plugins to help manage your browser's
|
||||
default javascript settings, such as NoScript and/or uMatrix, and use
|
||||
Private Browsing to manage your browser's cache.
|
||||
</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
<h3>Alternate Configuration(Requires Root!)</h3>
|
||||
<ol>
|
||||
<li>Install <a href="https://github.com/v1nc/user.js-updater">user.js-updater</a></li>
|
||||
<li>Select Fennec from the list of browsers</li>
|
||||
<li>Paste the following URL where it says "type custom user.js url" <a href="https://github.com/eyedeekay/firefox.profile.i2p/raw/master/firefox.profile.i2p/user.js">https://github.com/eyedeekay/firefox.profile.i2p/raw/master/firefox.profile.i2p/user.js</a></li>
|
||||
<li>Tap "Update"</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
<h3>Rootless Configuration via Webextension</h3>
|
||||
<ol>
|
||||
<li>Open this link in Fennec and get the WebExtension from <a href="https://github.com/eyedeekay/i2psetproxy.js/releases">Github</a></li>
|
||||
<li>Click through the "Blocked Extension" warning</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
@ -3,12 +3,31 @@
|
||||
<body>
|
||||
<h2>How to configure Firefox:</h2>
|
||||
<ol>
|
||||
<li>Click <a href="about:config?filter=network.proxy">HERE</a>, and choose to open the URL in Firefox.</li>
|
||||
<li>Click <a href="about:config?filter=proxy">HERE</a>, and choose to open the URL in Firefox.</li>
|
||||
<li>Change the value of "network.proxy.type" to <code>1</code>.</li>
|
||||
<li>Change the value of "network.proxy.http" to <code>127.0.0.1</code>.</li>
|
||||
<li>Change the value of "network.proxy.http_port" to <code>4444</code>.</li>
|
||||
<li>Change the value of "network.proxy.ssl" to <code>127.0.0.1</code>.</li>
|
||||
<li>Change the value of "network.proxy.ssl_port" to <code>4444</code>.</li>
|
||||
<li>Change the value of "media.peerconnection.ice.proxy_only" to <code>true</code>.</li>
|
||||
<li>You may also wish to install plugins to help manage your browser's
|
||||
default javascript settings, such as NoScript and/or uMatrix, and use
|
||||
Private Browsing to manage your browser's cache.
|
||||
</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
<h3>Alternate Configuration(Requires Root!)</h3>
|
||||
<ol>
|
||||
<li>Install <a href="https://github.com/v1nc/user.js-updater">user.js-updater</a></li>
|
||||
<li>Select Firefox from the list of browsers</li>
|
||||
<li>Paste the following URL where it says "type custom user.js url" <a href="https://github.com/eyedeekay/firefox.profile.i2p/raw/master/firefox.profile.i2p/user.js">https://github.com/eyedeekay/firefox.profile.i2p/raw/master/firefox.profile.i2p/user.js</a></li>
|
||||
<li>Tap "Update"</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
<h3>Rootless Configuration via Webextension</h3>
|
||||
<ol>
|
||||
<li>Open this link in Firefox and get the WebExtension from <a href="https://github.com/eyedeekay/i2psetproxy.js/releases">Github</a></li>
|
||||
<li>Click through the "Blocked Extension" warning</li>
|
||||
<li>You can now browse I2P eepsites!</li>
|
||||
</ol>
|
||||
</body>
|
||||
|
@ -4,6 +4,6 @@
|
||||
<h2>This browser is unknown</h2>
|
||||
<p>We have not tested this browser with I2P, so we don't know anything about it.</p>
|
||||
<p>But if this browser supports proxies, it will work with I2P.</p>
|
||||
<p>Configure this browser's HTTP and HTTPS proxy settings to use <code>localhost:4444</code>.</p>
|
||||
<p>Configure this browser's HTTP and HTTPS proxy settings to use <code>127.0.0.1:4444</code>.</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -33,7 +33,7 @@ tunnel.1.type=ircclient
|
||||
tunnel.1.sharedClient=true
|
||||
tunnel.1.interface=127.0.0.1
|
||||
tunnel.1.listenPort=6668
|
||||
tunnel.1.targetDestination=irc.dg.i2p:6667,irc.postman.i2p:6667,irc.echelon.i2p:6667
|
||||
tunnel.1.targetDestination=irc.postman.i2p:6667,irc.echelon.i2p:6667
|
||||
tunnel.1.i2cpHost=127.0.0.1
|
||||
tunnel.1.i2cpPort=7654
|
||||
tunnel.1.option.inbound.nickname=shared clients
|
||||
@ -101,27 +101,55 @@ tunnel.3.option.outbound.lengthVariance=0
|
||||
tunnel.3.option.outbound.priority=15
|
||||
tunnel.3.startOnLoad=true
|
||||
|
||||
# irc
|
||||
tunnel.4.name=IRC welterde
|
||||
tunnel.4.description=IRC tunnel to welterde's network
|
||||
tunnel.4.type=ircclient
|
||||
tunnel.4.sharedClient=true
|
||||
tunnel.4.interface=127.0.0.1
|
||||
tunnel.4.listenPort=6669
|
||||
tunnel.4.targetDestination=irc.welterde.i2p
|
||||
tunnel.4.i2cpHost=127.0.0.1
|
||||
tunnel.4.i2cpPort=7654
|
||||
tunnel.4.option.inbound.nickname=shared clients
|
||||
tunnel.4.option.outbound.nickname=shared clients
|
||||
tunnel.4.option.i2cp.delayOpen=true
|
||||
tunnel.4.option.i2cp.reduceIdleTime=600000
|
||||
tunnel.4.option.i2cp.reduceOnIdle=true
|
||||
tunnel.4.option.i2cp.reduceQuantity=1
|
||||
tunnel.4.option.i2p.streaming.connectDelay=1000
|
||||
tunnel.4.option.i2p.streaming.maxWindowSize=16
|
||||
tunnel.4.option.inbound.length=2
|
||||
tunnel.4.option.inbound.lengthVariance=0
|
||||
tunnel.4.option.outbound.length=2
|
||||
tunnel.4.option.outbound.lengthVariance=0
|
||||
tunnel.4.option.outbound.priority=15
|
||||
tunnel.4.startOnLoad=true
|
||||
# I2P Git Repositories SSH Access
|
||||
tunnel.6.description=I2P Git Repositories SSH Access
|
||||
tunnel.6.interface=127.0.0.1
|
||||
tunnel.6.listenPort=7670
|
||||
tunnel.6.name=gitssh.idk.i2p
|
||||
tunnel.6.option.i2cp.closeIdleTime=1800000
|
||||
tunnel.6.option.i2cp.closeOnIdle=false
|
||||
tunnel.6.option.i2cp.delayOpen=true
|
||||
tunnel.6.option.i2cp.destination.sigType=7
|
||||
tunnel.6.option.i2cp.newDestOnResume=false
|
||||
tunnel.6.option.i2cp.reduceIdleTime=1200000
|
||||
tunnel.6.option.i2cp.reduceOnIdle=true
|
||||
tunnel.6.option.i2cp.reduceQuantity=1
|
||||
tunnel.6.option.inbound.backupQuantity=1
|
||||
tunnel.6.option.inbound.length=3
|
||||
tunnel.6.option.inbound.nickname=gitssh.idk.i2p
|
||||
tunnel.6.option.inbound.quantity=3
|
||||
tunnel.6.option.outbound.backupQuantity=1
|
||||
tunnel.6.option.outbound.length=3
|
||||
tunnel.6.option.outbound.nickname=gitssh.idk.i2p
|
||||
tunnel.6.option.outbound.quantity=3
|
||||
tunnel.6.sharedClient=false
|
||||
tunnel.6.startOnLoad=false
|
||||
tunnel.6.targetDestination=gitssh.idk.i2p
|
||||
tunnel.6.type=client
|
||||
|
||||
# I2P Git Repositories HTTP Access(Android only)
|
||||
# Disabled by default, useful for Android gitlab clients like labcoat
|
||||
tunnel.7.description=I2P Git Repositories HTTP Access(Android Only)
|
||||
tunnel.7.interface=127.0.0.1
|
||||
tunnel.7.listenPort=7671
|
||||
tunnel.7.name=git.idk.i2p
|
||||
tunnel.7.option.i2cp.closeIdleTime=1800000
|
||||
tunnel.7.option.i2cp.closeOnIdle=false
|
||||
tunnel.7.option.i2cp.delayOpen=true
|
||||
tunnel.7.option.i2cp.destination.sigType=7
|
||||
tunnel.7.option.i2cp.newDestOnResume=false
|
||||
tunnel.7.option.i2cp.reduceIdleTime=1200000
|
||||
tunnel.7.option.i2cp.reduceOnIdle=true
|
||||
tunnel.7.option.i2cp.reduceQuantity=1
|
||||
tunnel.7.option.inbound.backupQuantity=1
|
||||
tunnel.7.option.inbound.length=3
|
||||
tunnel.7.option.inbound.nickname=git.idk.i2p
|
||||
tunnel.7.option.inbound.quantity=3
|
||||
tunnel.7.option.outbound.backupQuantity=1
|
||||
tunnel.7.option.outbound.length=3
|
||||
tunnel.7.option.outbound.nickname=git.idk.i2p
|
||||
tunnel.7.option.outbound.quantity=3
|
||||
tunnel.7.sharedClient=false
|
||||
tunnel.7.startOnLoad=false
|
||||
tunnel.7.targetDestination=ssh.idk.i2p
|
||||
tunnel.7.type=client
|
||||
|
@ -53,6 +53,10 @@ i2np.bandwidth.outboundKBytesPerSecond=50
|
||||
i2np.ntcp.enable=true
|
||||
i2np.ntcp.maxConnections=32
|
||||
#
|
||||
# NTCP2
|
||||
#
|
||||
i2np.ntcp2.enable=true
|
||||
#
|
||||
# UDP
|
||||
#
|
||||
i2np.udp.enable=true
|
||||
|
@ -1,3 +1,2 @@
|
||||
http://i2p-projekt.i2p/hosts.txt
|
||||
http://i2host.i2p/cgi-bin/i2hostetag
|
||||
http://stats.i2p/cgi-bin/newhosts.txt
|
||||
|
@ -36,9 +36,8 @@ services. You can also access the normal web anonymously via I2P's built-in web
|
||||
proxy (outproxy). <a href="https://geti2p.net/en/about/browser-config"
|
||||
target="_blank">Configure your browser</a> to use the HTTP proxy at
|
||||
<code>127.0.0.1 port 4444</code>, then browse to an eepsite or a normal,
|
||||
unencrypted <code>http://</code> address. For a pre-configured browser, you may
|
||||
wish to try <a href="http://echelon.i2p/i2pfox/">I2PFox</a>, a custom build of
|
||||
Firefox security hardened and tailored especially for I2P. If you wish to
|
||||
unencrypted <code>http://</code> address.
|
||||
If you wish to
|
||||
disable or change outproxy access to the normal internet, remove or modify the
|
||||
outproxy entry for <code>false.i2p</code> under the <i>Outproxies</i> option in
|
||||
the <a href="/i2ptunnel/edit?tunnel=0" target="_blank">I2P HTTP Proxy Tunnel
|
||||
@ -80,13 +79,12 @@ target="_blank">geti2p.net</a>. If you want to know
|
||||
more about how I2P works or how you can participate, this is your first port of
|
||||
call!</li>
|
||||
<li class="tidylist"><b>I2P Community Forums</b><br><a
|
||||
href="http://forum.i2p/" target="_blank">forum.i2p</a>: A secure
|
||||
href="http://i2pforum.i2p/" target="_blank">i2pforum.i2p</a>: A secure
|
||||
and anonymous online forum community where developers
|
||||
and users alike discuss problems and ideas relating to I2P and associated
|
||||
topics, and <a href="http://zzz.i2p/" target="_blank">zzz's developer
|
||||
forums</a> for both end users and developers.</li>
|
||||
topics.</li>
|
||||
<li class="tidylist"><b>I2P Anonymous Pastebin</b><br><a
|
||||
href="http://pastethis.i2p/" target="_blank">pastethis.i2p</a>: Secure and
|
||||
href="http://paste.idk.i2p/" target="_blank">paste.idk.i2p</a>: Secure and
|
||||
anonymous paste service allowing anonymous text and text-based code
|
||||
sharing over I2P.</li>
|
||||
<li class="tidylist"><b>Echelon's I2P Resources</b><br><a
|
||||
@ -95,14 +93,6 @@ href="http://echelon.i2p/" target="_blank">echelon.i2p</a>: I2P software
|
||||
including a <a href="http://echelon.i2p/I2Pguide/index.html"
|
||||
target="_blank">beginner's guide</a> and pre-release developer builds of I2P
|
||||
for the adventurous to try.</li>
|
||||
<li class="tidylist"><b>Ugha's Wiki</b><br><a href="http://ugha.i2p/"
|
||||
target="_blank">ugha.i2p</a>: An open wiki that anyone can edit with plenty of
|
||||
information about I2P, help for beginners, additional links into the network,
|
||||
and more.</li>
|
||||
<li class="tidylist"><b>I2P-to-Freenet Proxy</b><br><a
|
||||
href="http://fproxy.tino.i2p/" target="_blank">fproxy.tino.i2p</a>:
|
||||
Peer into the world of the <a href="http://freenetproject.org/"
|
||||
target="_blank">Freenet</a> network with Tino's I2P-to-Freenet proxy.</li>
|
||||
<li class="tidylist"><b>The Planet (on I2P)</b><br><a
|
||||
href="http://planet.i2p/" target="_blank">planet.i2p</a>: An RSS aggregator
|
||||
site that takes news and events from around I2P and publishes them all in one
|
||||
@ -149,32 +139,24 @@ discussion forum</a>,
|
||||
<a href="irc://127.0.0.1:6668/i2p-help">#i2p-help</a>, <a
|
||||
href="irc://127.0.0.1:6668/i2p">#i2p</a> or <a
|
||||
href="irc://127.0.0.1:6668/i2p-chat">#i2p-chat</a> on I2P's internal IRC
|
||||
network (<code>irc.postman.i2p</code> or <code>irc.freshcoffee.i2p</code>).
|
||||
network (<code>irc.postman.i2p</code> or <code>irc.echelon.i2p</code>).
|
||||
These channels are also available outside of I2P's encrypted, anonymous network
|
||||
via <a href="irc://irc.freenode.net/i2p">Freenode IRC</a>.
|
||||
</li>
|
||||
|
||||
<li class="tidylist"><b>Reporting Bugs</b><br>If you'd like to report a bug,
|
||||
please file a ticket on <a href="http://trac.i2p2.i2p/"
|
||||
target="_blank">trac.i2p2.i2p</a>. For developer-related discussions, please
|
||||
visit <a href="http://zzz.i2p/" target="_blank">zzz's developer forums</a> or
|
||||
please file a ticket on <a href="http://git.idk.i2p/"
|
||||
target="_blank">git.idk.i2p</a>. For developer-related discussions, please
|
||||
visit <a href="http://i2pforum.i2p/" target="_blank">I2P's developer forums</a> or
|
||||
come and visit the <a href="irc://127.0.0.1:6668/i2p-dev">developer channel</a>
|
||||
on I2P's IRC network. Developers can browse source at <a
|
||||
href="http://stats.i2p/cgi-bin/viewmtn/" target="_blank">zzz's mtn repository
|
||||
viewer</a>, <a href="http://i2host.i2p/cgi-bin/view/branch/changes/i2p.i2p"
|
||||
target="_blank">Sponge's instance</a>, or via <a
|
||||
href="http://trac.i2p2.i2p/browser" target="_blank">trac.i2p2.i2p</a>. We
|
||||
primarily use <a href="http://i2p-projekt.i2p/monotone.html"
|
||||
target="_blank">monotone</a> to manage our source code.
|
||||
href="git.idk.i2p/i2p-hackers/i2p.i2p/-/commits/master" target="_blank">git.idk.i2p</a> or
|
||||
<a href="https://github.com/i2p/i2p.i2p" target="_blank">GitHub</a>.
|
||||
</li>
|
||||
|
||||
<li class="tidylist"><b>Get Involved!</b><br>I2P is developed and maintained
|
||||
mostly through unfunded, voluntary participation by community members. We're
|
||||
happy to accept <a href="http://i2p-projekt.i2p/donate.html"
|
||||
target="_blank">donations</a>, which go into essential hosting and
|
||||
administrative costs. We have <a href="http://i2p-projekt.i2p/bounties.html"
|
||||
target="_blank">cash bounties</a> for aspects of I2P for developers looking for
|
||||
incentives to participate, and we're always looking for more <a
|
||||
mostly through unfunded, voluntary participation by community members. We're
|
||||
always looking for more <a
|
||||
href="http://i2p-projekt.i2p/newdevelopers.html" target="_blank">Java coders</a>,
|
||||
<a href="http://i2p-projekt.i2p/newtranslators.html"
|
||||
target="_blank">translators</a>, promoters and users to help I2P grow. The
|
||||
@ -188,6 +170,6 @@ page</a> on the website.
|
||||
</ul>
|
||||
|
||||
<div class="topness"><a href="#top">[Return to Top]</a></div>
|
||||
<div class="footnote"><hr>Document updated: June 2011</div>
|
||||
<div class="footnote"><hr>Document updated: May 2021</div>
|
||||
</div>
|
||||
</body></html>
|
||||
|
129
app/src/main/res/values-ar/strings.xml
Normal file
129
app/src/main/res/values-ar/strings.xml
Normal file
@ -0,0 +1,129 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="app_name">I2P</string>
|
||||
<string name="desc_i2p_logo">شعار I2P</string>
|
||||
<string name="choose_language">اختر اللغة</string>
|
||||
<string name="welcome_new_version">نسخة جديدة مثبتة. يرجى قراءة ملاحظات الإصدار. الإصدار:</string>
|
||||
<string name="label_tunnels">نفق</string>
|
||||
<string name="label_status">الحالة</string>
|
||||
<string name="label_console">وحدة التحكم</string>
|
||||
<string name="label_addresses">عناوين</string>
|
||||
<string name="label_addressbook">دفتر العناوين</string>
|
||||
<string name="label_i2ptunnel_client">أنفاق العميل</string>
|
||||
<string name="label_i2ptunnel_server">أنفاق الخادم</string>
|
||||
<string name="label_logs">السجلات</string>
|
||||
<string name="label_error_logs">سجلات الأخطاء</string>
|
||||
<string name="label_news">الأخبار</string>
|
||||
<string name="label_peers_status">المستخدمين</string>
|
||||
<string name="label_release_notes">ملاحظات الإصدار</string>
|
||||
<string name="label_licenses">الرخص</string>
|
||||
<string name="label_browse">تصفح</string>
|
||||
<string name="label_graphs">رسم بياني</string>
|
||||
<string name="button_router_off">اضغط لفترة طويلة لبدء I2P</string>
|
||||
<string name="button_router_on">I2P يعمل (اضغط لفترة طويلة لإيقافه)</string>
|
||||
<string name="button_router_graceful">سيتم إغلاق I2P في %s</string>
|
||||
<string name="button_shutdown_now">اضغط لفترة طويلة لوقفه الآن</string>
|
||||
<string name="button_cancel_graceful">اضغط لفترة طويلة لإلغاء إيقاف التشغيل</string>
|
||||
<string name="no_internet">لا يوجد اتصال متاح بالإنترنت </string>
|
||||
<string name="hidden">مختفي</string>
|
||||
<string name="testing">جاري التجريب</string>
|
||||
<string name="firewalled">ممنوع من الجدار الناري</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="uptime">مدة الاشتغال</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">S</string>
|
||||
<string name="download">تحميل</string>
|
||||
<string name="upload">رفع</string>
|
||||
<string name="first_start_title">تهانينا على تثبيتِ I2P!</string>
|
||||
<string name="first_start_read">أثناء انتظارك، فضلا اطلع على ملاحظات الإصدار والصفحة الرئيسية</string>
|
||||
<string name="action_search">بحث</string>
|
||||
<string name="action_add">إضافة</string>
|
||||
<string name="action_edit">تحرير</string>
|
||||
<string name="action_delete">حذف</string>
|
||||
<string name="action_reload">إعادة تحميل</string>
|
||||
<string name="action_refresh">تحديث</string>
|
||||
<string name="stats_not_ready">مدير الإحصاءات غير جاهز حاليا. يرجى المحاولة لاحقا</string>
|
||||
<string name="statistics">إحصائيات</string>
|
||||
<string name="routers">الموجه</string>
|
||||
<string name="countries">بلدان</string>
|
||||
<string name="country">البلد</string>
|
||||
<string name="transport">نقل</string>
|
||||
<string name="version">إصدار</string>
|
||||
<string name="count">عدد</string>
|
||||
<string name="tname_0">مختفي</string>
|
||||
<string name="menu_settings">الإعدادات</string>
|
||||
<string name="settings_enable">تفعيل</string>
|
||||
<string name="settings_label_bandwidth">سرعة الاتصال</string>
|
||||
<string name="settings_label_network">الشبكة</string>
|
||||
<string name="settings_label_hiddenMode">المشاركة</string>
|
||||
<string name="settings_label_logging">تسجيل</string>
|
||||
<string name="settings_label_default_log_level">نوع السجل</string>
|
||||
<string name="settings_label_appearance">المظهر</string>
|
||||
<string name="settings_label_language">اللغة</string>
|
||||
<string name="settings_default">افتراضي</string>
|
||||
<string name="settings_label_advanced">متقدم</string>
|
||||
<string name="settings_label_transports">نقل</string>
|
||||
<string name="settings_label_expl_length">الطول</string>
|
||||
<string name="settings_summ_expl_lengthVariance">نسبة %s</string>
|
||||
<string name="settings_label_expl_quantity">الكمية</string>
|
||||
<string name="settings_label_expl_backupQuantity">قدر نسخ الاحتياط</string>
|
||||
<string name="menu_about">حول</string>
|
||||
<string name="about_version">الإصدار:</string>
|
||||
<string name="about_project">مركز المشروع:</string>
|
||||
<string name="menu_help">المساعدة</string>
|
||||
<string name="general">عام</string>
|
||||
<string name="addressbook_add_wizard_k_name">الاسم</string>
|
||||
<string name="addressbook_add_wizard_k_destination">اتجاه</string>
|
||||
<string name="i2ptunnel_type_client">مستخدم عادي</string>
|
||||
<string name="i2ptunnel_type_httpclient">HTTP client</string>
|
||||
<string name="i2ptunnel_type_ircclient">IRC برنامج</string>
|
||||
<string name="i2ptunnel_type_server">خادم عادي</string>
|
||||
<string name="i2ptunnel_type_httpserver">HTTP خادم</string>
|
||||
<string name="i2ptunnel_type_sockstunnel">SOCKS 4/4a/5 بروكسي</string>
|
||||
<string name="i2ptunnel_type_socksirctunnel">SOCKS IRC بروكسي دردشة</string>
|
||||
<string name="i2ptunnel_type_connectclient">اتصال/SSL/HTTPS بروكسي</string>
|
||||
<string name="i2ptunnel_type_ircserver">IRC خادم</string>
|
||||
<string name="i2ptunnel_new_tunnel">نفق جديد</string>
|
||||
<string name="i2ptunnel_msg_config_saved">تم حفظ الإعدادات</string>
|
||||
<string name="i2ptunnel_msg_config_save_failed">فشل حفظ الإعدادات</string>
|
||||
<string name="i2ptunnel_msg_tunnel_starting">ابدأ النفق</string>
|
||||
<string name="i2ptunnel_msg_tunnel_stopping">توقيف النفق</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">المستخدم أو الخادم</string>
|
||||
<string name="i2ptunnel_wizard_k_name">الاسم</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">وصف</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">اتجاه</string>
|
||||
<string name="i2ptunnel_wizard_k_outproxies">بروكسي خارجي</string>
|
||||
<string name="i2ptunnel_wizard_k_auto_start">تشغيل آلي</string>
|
||||
<string name="next">التالي</string>
|
||||
<string name="prev">السابق</string>
|
||||
<string name="finish">رفع</string>
|
||||
<string name="review">مراجعة</string>
|
||||
<string name="enabled">مفعل</string>
|
||||
<string name="i2ptunnel_view_target">الهدف</string>
|
||||
<string name="i2ptunnel_view_autostart">تشغيل آلي</string>
|
||||
<string name="name">الاسم</string>
|
||||
<string name="description">وصف</string>
|
||||
<string name="auto_start">تشغيل آلي</string>
|
||||
<string name="outproxies">بروكسي خارجي</string>
|
||||
<string name="irc">IRC</string>
|
||||
<string name="use_ssl">استعمل SSL</string>
|
||||
<string name="profile">بروفايل</string>
|
||||
<string name="access_control">سيطرة الوصول</string>
|
||||
<string name="disabled">معطل</string>
|
||||
<string name="whitelist">قائمة بيضاء</string>
|
||||
<string name="blacklist">قائمة سوداء</string>
|
||||
<string name="unlimited">غير محدود</string>
|
||||
<string name="tunnel_summ_delay_open">عطل النفق حتى الحاجة اليه</string>
|
||||
<string name="tunnel_summ_reduce_quantity">قلل قدر الأنفاق عند الانتظار</string>
|
||||
<string name="num_minutes">%sدقائق </string>
|
||||
<string name="close_tunnels">قفل النفق عند الانتظار</string>
|
||||
<string name="http_client">HTTP client</string>
|
||||
<string name="username">اسم المستخدم</string>
|
||||
<string name="password">كلمة السر</string>
|
||||
<string name="other">أخرى</string>
|
||||
<string name="custom_options">خيارات خاصة</string>
|
||||
<string name="all">الكل</string>
|
||||
<string name="no_messages">لا رسائل</string>
|
||||
</resources>
|
348
app/src/main/res/values-az/strings.xml
Normal file
348
app/src/main/res/values-az/strings.xml
Normal file
@ -0,0 +1,348 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="app_name">I2P</string>
|
||||
<string name="desc_i2p_logo">I2P loqo</string>
|
||||
<string name="choose_language">Dili seç</string>
|
||||
<string name="welcome_new_install">I2P-yə xoş gəlmisiniz! Bu tətbiqetmə ALPHA proqram tminatıdır və güclü məxfilyi təmin etmir. Zəhmət olmasa buraxılış qeydləri və lisenziya məlumatlarını oxuyun.</string>
|
||||
<string name="welcome_new_version">Yeni versiya quraşdırıldı. Zəhmət olmasa buraxılış qeydlərini oxuyun. Versiya:</string>
|
||||
<string name="label_tunnels">Tunellər</string>
|
||||
<string name="label_status">Status</string>
|
||||
<string name="label_console">Konsol</string>
|
||||
<string name="label_addresses">Ünvanlar</string>
|
||||
<string name="label_addressbook">Ünvan kitabçası</string>
|
||||
<string name="label_i2ptunnel_client">Müştəri tunelləri</string>
|
||||
<string name="label_i2ptunnel_server">Server tunelləri</string>
|
||||
<string name="label_logs">Jurnallar</string>
|
||||
<string name="label_error_logs">Xəta jurnalları</string>
|
||||
<string name="label_news">Xəbərlər</string>
|
||||
<string name="label_peers_status">Bənzərlər</string>
|
||||
<string name="label_release_notes">Buraxılış qeydləri</string>
|
||||
<string name="label_licenses">Lisenziyalar</string>
|
||||
<string name="label_browse">Bax</string>
|
||||
<string name="label_graphs">Qrafiklər</string>
|
||||
<string name="button_router_off">I2P-ni başlamaq üçün uzun klik</string>
|
||||
<string name="button_router_on">I2P işləyir (dayandırmaq üçün uzun kliklə)</string>
|
||||
<string name="button_router_graceful">I2P bağlanacaq %s</string>
|
||||
<string name="button_shutdown_now">İndi dayandırmaq üçün uzun kliklə</string>
|
||||
<string name="button_cancel_graceful">Söndürməyi ləğv etmək üçün uzun kliklə</string>
|
||||
<string name="no_internet">İnternet bağlantısı yoxdur</string>
|
||||
<string name="hidden">Gizli</string>
|
||||
<string name="testing">Test etmək</string>
|
||||
<string name="firewalled">Qoruyucu divar</string>
|
||||
<string name="symmetric_nat">Simmetrik NAT</string>
|
||||
<string name="net_status_error_i2cp">Müştəri idarəçisinin I2CP xətası - girişi yoxla</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="net_status_error_skew">Saat əyriliyinin %s</string>
|
||||
<string name="net_status_error_unresolved_tcp">Həll edilməyən TCP ünvanı </string>
|
||||
<string name="net_status_error_private_tcp">Şəxsi TCP ünvanı</string>
|
||||
<string name="net_status_warn_firewalled_inbound_tcp">Qoruyucu divarı ilə TCP aktivləşdirildi</string>
|
||||
<string name="net_status_warn_firewalled_floodfill">Qoruyucu divar və floodfill</string>
|
||||
<string name="net_status_info_disconnected">Əlaqə kəsilib - şəbəkə əlaqəsini yoxlayın</string>
|
||||
<string name="net_status_error_udp_port">UDP portu istifadədir - tənzimləmələrdə dəyişiklik et və yenidən başlat</string>
|
||||
<string name="net_status_error_no_active_peers">Fəal bənzər yoxdur - şəbəkə əlaqəsi ilə qoruyucu divarı yoxla</string>
|
||||
<string name="net_status_error_udp_disabled_tcp_not_set">UDP sönüb və daxil olan TCP host/post quraşdırılmayıb</string>
|
||||
<string name="net_status_warn_firewalled_udp_disabled">UDP-li qoruyucu divar sönüb</string>
|
||||
<string name="shared_clients">Paylaşılan müştərilər</string>
|
||||
<string name="uptime">Xidmət dövrü</string>
|
||||
<string name="active_peers">Fəal bənzərlər</string>
|
||||
<string name="known_peers">Tanınan bənzərlər</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">S</string>
|
||||
<string name="no_tunnels_running">Hələlik heç bir tunel işləmir.</string>
|
||||
<string name="download">Endir</string>
|
||||
<string name="upload">Yüklə</string>
|
||||
<string name="configure_browser_title">Brauzer quraşdırılsın?</string>
|
||||
<string name="configure_browser_for_i2p">I2P saytlarına baxmaq üçün brauzerin quraşdırılmasını istəyirsinizmi? (Bunu daha sonra yardım menyusundan da edə bilərsiniz.)</string>
|
||||
<string name="first_start_title">I2P-i quraşdırdığınız üçün təbrik edirik!</string>
|
||||
<string name="first_start_welcome"><b>I2P-yə xoş gəlmisiz! </b>Xahiş edirik<b> bir qədər səbrli olun</b>, I2P yüklənir və bənzərləri axtarır.</string>
|
||||
<string name="first_start_read">Gözlədiyiniz müddətdə, zəhmət olmasa, buraxılış qeydlərini və salamlama səhifəsini oxuyun.</string>
|
||||
<string name="first_start_faq">Müştəri tunelləri olduqda, zəhmət olmasa <b>bizim FAQ-a</b> göz atın:</string>
|
||||
<string name="first_start_faq_nonanon">Yaxud tunelləri gözləmək istəmirsinizsə bu, anonim olmayan linkdən istifadə edin:</string>
|
||||
<string name="first_start_irc">IRC müştərinizi <b>localhost:6668</b>-ə gətirin və bizi salamlayın.</string>
|
||||
<string name="action_search">Axtar</string>
|
||||
<string name="action_add">Əlavə et</string>
|
||||
<string name="action_edit">Dəyiş</string>
|
||||
<string name="action_delete">Sil</string>
|
||||
<string name="action_i2ptunnel_start">Tuneli başla</string>
|
||||
<string name="action_i2ptunnel_stop">Tuneli dayandır</string>
|
||||
<string name="action_i2ptunnel_start_all">Bütün tunelləri başla</string>
|
||||
<string name="action_i2ptunnel_stop_all">Bütün tunelləri dayandır</string>
|
||||
<string name="action_i2ptunnel_restart_all">Bütün tunelləri yenidən başlat</string>
|
||||
<string name="action_reload">Yenidən yüklə</string>
|
||||
<string name="action_refresh">Yenilə</string>
|
||||
<string name="hint_search_addressbook">Ünvan kitabçasında axtar</string>
|
||||
<string name="action_reload_subscriptions">Abunələri yenidən yüklə</string>
|
||||
<string name="news_last_updated">Son xəbərlər %s əvvəl yeniləndi</string>
|
||||
<string name="news_last_checked">Xəbərlər %s əvvəl yoxlanılıb</string>
|
||||
<string name="news_updated">Xəbərlər yeniləndi</string>
|
||||
<string name="view_news">Son I2P xəbərlərini görmək üçün kliklə</string>
|
||||
<string name="router_not_running">İstiqamətləndirici işləmir. </string>
|
||||
<string name="router_shutting_down">İstiqamətləndirici bağlanır. </string>
|
||||
<string name="stats_not_ready">Statistika meneceri hələ hazır deyil. Bir daha sınayın.</string>
|
||||
<string name="select_an_address">Bir ünvan seç.</string>
|
||||
<string name="no_graphs_configured">Heç bir qrafik quraşdırılmadı. Qrafik üçün statistikanı quraşdırma menyusundan seçə bilərsiniz. Dəyişikliklər 60 saniyə sonra qüvvəyə minəcək.</string>
|
||||
<string name="configure_graphs">Qrafikləri quraşdır</string>
|
||||
<string name="graphs_not_ready">Qrafiklər hələlik hazır deyil. Bir daha sınayın.</string>
|
||||
<string name="statistics">Statistikalar</string>
|
||||
<string name="routers">İstiqamətləndiricilər</string>
|
||||
<string name="leasesets">LeaseSets</string>
|
||||
<string name="countries">Ölkələr</string>
|
||||
<string name="country">Ölkə</string>
|
||||
<string name="transport">Nəqliyyat</string>
|
||||
<string name="versions">Versiyalar</string>
|
||||
<string name="version">Versiya</string>
|
||||
<string name="count">Count</string>
|
||||
<string name="tname_0">Gizli və ya işə başlayır</string>
|
||||
<string name="netdb_routers_empty">NetDB-də istiqamətləndirici yoxdur.</string>
|
||||
<string name="netdb_leases_empty">NetDB-də LeaseSets yoxdur.</string>
|
||||
<string name="notification_status_starting">I2P başlayır</string>
|
||||
<string name="notification_status_restarting">I2P yenidən başlayır</string>
|
||||
<string name="notification_status_waiting">I2P şəbəkə əlaqəsini gözləyir</string>
|
||||
<string name="notification_status_starting_after_waiting">Şəbəkə qoşulub, I2P başlayır</string>
|
||||
<string name="notification_status_running">I2P işləyir</string>
|
||||
<string name="notification_status_client_ready">Müştəri tunelləri hazırdır</string>
|
||||
<string name="notification_status_client_down">Müştəri tunelləri bağlanıb</string>
|
||||
<string name="notification_status_graceful">I2P-ni %s dayandırmaq</string>
|
||||
<string name="notification_status_stopping">I2P-ni dayandırmaq</string>
|
||||
<string name="notification_status_stopping_after_net">Şəbəkə kəsildi, I2P dayandırıldı</string>
|
||||
<string name="notification_status_shutdown_cancelled">Söndürmə ləğv edildi</string>
|
||||
<string name="notification_status_shutting_down">I2P sönür</string>
|
||||
<string name="notification_status_bw">Ötürmə qabiliyyəti:%1$sBps aşağı /%2$sBps yuxarı</string>
|
||||
<string name="notification_status_peers">Bənzərlər: fəal%1$d, tanınan %2$d</string>
|
||||
<string name="notification_status_expl">Axtarış tunelləri: %1$d/%2$d</string>
|
||||
<string name="notification_status_client">Müştəri tunelləri: %1$d/%2$d</string>
|
||||
<string name="menu_settings">Tənzimləmələr</string>
|
||||
<string name="settings_enable">Aktivləşdir</string>
|
||||
<string name="settings_desc_subscriptions">Abunəliyin URL-ləri</string>
|
||||
<string name="settings_label_bandwidth_net">Ötürmə qabiliyyəti və şəbəkə</string>
|
||||
<string name="settings_label_startOnBoot">Android Açıldıqda I2P-ni Başlat</string>
|
||||
<string name="settings_desc_startOnBoot">Android cihazınız işə başladıqda I2P avtomatik olaraq başlansın</string>
|
||||
<string name="settings_label_bandwidth">Ötürmə qabiliyyəti </string>
|
||||
<string name="settings_label_bw_inbound">Daxil olan sürət</string>
|
||||
<string name="settings_desc_bw_inbound">Daxil olan maksimum sürət</string>
|
||||
<string name="settings_label_bw_outbound">Xaric olan sürət</string>
|
||||
<string name="settings_desc_bw_outbound">Çıxan maksimum sürət</string>
|
||||
<string name="settings_label_network">Şəbəkə</string>
|
||||
<string name="settings_label_hiddenMode">İştirak</string>
|
||||
<string name="settings_desc_hiddenMode">Gizli rejimi söndür</string>
|
||||
<string name="settings_label_maxPartTunnels"> İştirak edən maksimum tunellər</string>
|
||||
<string name="settings_desc_maxPartTunnels">Qatılmaq üçün maksimum tunel (standart= 20)</string>
|
||||
<string name="settings_dialog_maxPartTunnels">Qatılmaq üçün maksimum tunel</string>
|
||||
<string name="settings_label_sharePercent">Pay nisbəti</string>
|
||||
<string name="settings_desc_sharePercent">Ötürmə qabiliyyətinin payı (standart = 80)</string>
|
||||
<string name="settings_dialog_sharePercent">Ötürmə qabiliyyətinin payı</string>
|
||||
<string name="settings_desc_upnp">Qoruyucu divar portlarını avtomatik aç</string>
|
||||
<string name="settings_label_logging">Qeydiyyat aparılması</string>
|
||||
<string name="settings_label_default_log_level">Standart giriş səviyyəsi</string>
|
||||
<string name="settings_label_appearance">Görünüş</string>
|
||||
<string name="settings_label_language">Dil</string>
|
||||
<string name="settings_default">Standart</string>
|
||||
<string name="settings_label_advanced">Qabaqcıl</string>
|
||||
<string name="settings_label_showStats">İstiqamətləndirici statistikaları</string>
|
||||
<string name="settings_summ_showStats">Əsas konsolda qabaqcıl statistikanı göstər</string>
|
||||
<string name="settings_label_transports">Nəqliyyatlar</string>
|
||||
<string name="settings_label_maxConns">Maksimum əlaqələr</string>
|
||||
<string name="settings_label_i2cp">I2CP interfeysi</string>
|
||||
<string name="settings_label_exploratory_pool">Axtarış hovuzu</string>
|
||||
<string name="settings_desc_exploratory_pool">Tunel parametrləri</string>
|
||||
<string name="settings_label_expl_inbound">Daxil olan tunellər</string>
|
||||
<string name="settings_label_expl_outbound">Xaric olan tunellər</string>
|
||||
<string name="settings_label_expl_length">Uzunluq</string>
|
||||
<string name="settings_summ_expl_length">%ssıçrayış </string>
|
||||
<string name="settings_desc_expl_length">Istifadə etmək üçün neçə sıçrayış </string>
|
||||
<string name="settings_label_expl_lengthVariance">Sıçrayış dəyişikliyi</string>
|
||||
<string name="settings_summ_expl_lengthVariance">%s</string>
|
||||
<string name="settings_desc_expl_lengthVariance">Nizamsız əlavə etmək üçün neçə sıçrayış</string>
|
||||
<string name="settings_label_expl_quantity">Miqdar</string>
|
||||
<string name="settings_summ_expl_quantity">%sTunel </string>
|
||||
<string name="settings_desc_expl_quantity">Neçə tunel</string>
|
||||
<string name="settings_label_expl_backupQuantity">Yedək miqdarı</string>
|
||||
<string name="settings_summ_expl_backupQuantity">%sTunel </string>
|
||||
<string name="settings_desc_expl_backupQuantity">Neçə yedək tuneli</string>
|
||||
<string name="settings_need_transport_enabled">Ən azı bir nəqliyyatınız aktiv olmalıdır</string>
|
||||
<string name="settings_router_restart_required">Dəyişiklikləri tətbiq etmək üçün I2P-i yenidən başladın</string>
|
||||
<string name="menu_about">Haqqında</string>
|
||||
<string name="about_version">Versiya:</string>
|
||||
<string name="about_project">Layihənin ana səhifəsi:</string>
|
||||
<string name="about_bugs">Xətalar və dəstək:</string>
|
||||
<string name="about_helpwanted">Yardıma ehtiyac var!</string>
|
||||
<string name="about_volunteer">Proqramı yaxşılaşdırmaq istəyirsiniz? Android forumunda könüllü:</string>
|
||||
<string name="menu_help">Kömək</string>
|
||||
<string name="general">Əsas</string>
|
||||
<string name="label_router">İctimai ünvanlar</string>
|
||||
<string name="label_private">Şəxsi ünvanlar</string>
|
||||
<string name="addressbook_is_empty">Ünvan kitabçası boşdur</string>
|
||||
<string name="addressbook_search_header">%stapıldı</string>
|
||||
<string name="addressbook_add_wizard_k_name">Ad</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Təyinat yeri</string>
|
||||
<string name="addressbook_add_wizard_desc_name">Ad</string>
|
||||
<string name="addressbook_add_wizard_desc_destination">Təyinat yerinin B64-nü bura yapışdır. Əgər yüklənmiş Fayl Meneceriniz varsa, B64-ü olan mətn faylına baxa bilərsiniz.</string>
|
||||
<string name="nsu_iae_illegal_char">Host adı \"%1$s\" qanunsuz xarakter daşıyır %2$s</string>
|
||||
<string name="nsu_iae_cannot_start_with">Host adı \"%s\" ilə başlaya bilməz</string>
|
||||
<string name="nsu_iae_cannot_end_with">Host adı \"%s\" ilə bitə bilməz</string>
|
||||
<string name="nsu_iae_cannot_contain">Host adında \"%s\" ola bilməz</string>
|
||||
<string name="nsu_iae_requires_conversion">Host adı \"%s\" ASCII-yə çevrilməyi tələb edir, lakin Androidin bu versiyasında dönüşüm kitabxanası mövcud deyil</string>
|
||||
<string name="i2ptunnel_type_client">Standart müştəri</string>
|
||||
<string name="i2ptunnel_type_httpclient">HTTP müştəri</string>
|
||||
<string name="i2ptunnel_type_ircclient">IRC müştəri</string>
|
||||
<string name="i2ptunnel_type_server">Standart server</string>
|
||||
<string name="i2ptunnel_type_httpserver">HTTP serveri</string>
|
||||
<string name="i2ptunnel_type_sockstunnel">SOCKS 4/4a/5 proksi</string>
|
||||
<string name="i2ptunnel_type_socksirctunnel">SOCKS IRC proksi</string>
|
||||
<string name="i2ptunnel_type_connectclient">CONNECT/SSL/HTTPS proksi</string>
|
||||
<string name="i2ptunnel_type_ircserver">IRC serveri</string>
|
||||
<string name="i2ptunnel_type_streamrclient">Streamr müştəri</string>
|
||||
<string name="i2ptunnel_type_streamrserver">Streamr serveri</string>
|
||||
<string name="i2ptunnel_type_httpbidirserver">HTTP bidir</string>
|
||||
<string name="install_recommended_app">Tövsiyə olunan tətbiqetmələr quraşdırılsın?</string>
|
||||
<string name="app_needed_for_this_tunnel_type">Bu tuneldən istifadə etmək üçün tətbiqetmə yüklənməlidir. Tövsiyə olunan tətbiqetməni yükləmək istəyirsinizmi?</string>
|
||||
<string name="i2ptunnel_not_initialized">Tunellər hələlik başladılmayıb, iki dəqiqədən sonra yenidən yükləyin. </string>
|
||||
<string name="no_configured_client_tunnels">Quraşdırılmış müştəri tunelləri yoxdur.</string>
|
||||
<string name="no_configured_server_tunnels">Quraşdırılmış server tunelləri yoxdur. </string>
|
||||
<string name="i2ptunnel_new_tunnel">Yeni tunel</string>
|
||||
<string name="i2ptunnel_msg_config_saved">Quraşdırma dəyişiklikləri saxlandı</string>
|
||||
<string name="i2ptunnel_msg_config_save_failed">Quraşdırmanı saxlamaq alınmadı</string>
|
||||
<string name="i2ptunnel_msg_tunnel_starting">Tunelə başlanır</string>
|
||||
<string name="i2ptunnel_msg_tunnel_stopping">Tunel dayandırılır</string>
|
||||
<string name="i2ptunnel_delete_confirm_message">Tunel silinsin?</string>
|
||||
<string name="i2ptunnel_delete_confirm_button">Tuneli sil</string>
|
||||
<string name="i2ptunnel_no_tunnel_details">Tunel məlumatlarını yükləmək alınmadı</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">Müştəri yaxud server</string>
|
||||
<string name="i2ptunnel_wizard_v_client">Müştəri tunneli</string>
|
||||
<string name="i2ptunnel_wizard_v_server">Server tunneli</string>
|
||||
<string name="i2ptunnel_wizard_k_type">Tunel növü</string>
|
||||
<string name="i2ptunnel_wizard_k_name">Ad</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">Açıqlama</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">Təyinat yeri</string>
|
||||
<string name="i2ptunnel_wizard_k_outproxies">Outproxies </string>
|
||||
<string name="i2ptunnel_wizard_k_target_host">Məqsəd hostu</string>
|
||||
<string name="i2ptunnel_wizard_k_target_port">Məqsəd portu</string>
|
||||
<string name="i2ptunnel_wizard_k_reachable_on">Əlçatandır</string>
|
||||
<string name="i2ptunnel_wizard_k_binding_port">Bağlayıcı port</string>
|
||||
<string name="i2ptunnel_wizard_k_auto_start">Avtomatik başlama</string>
|
||||
<string name="next">Növbəti</string>
|
||||
<string name="prev">Əvvəlki</string>
|
||||
<string name="finish">Göndər</string>
|
||||
<string name="review">Baxış-icmal</string>
|
||||
<string name="enabled">Aktivdir</string>
|
||||
<string name="i2ptunnel_wizard_desc_name"> Tunel siyahısında müəyyənləşdirilməsi üçün tunel adı.</string>
|
||||
<string name="i2ptunnel_wizard_desc_desc">Tunelin təsviri. Bu, istəkdən asılıdır və tamamilə informativdir.</string>
|
||||
<string name="i2ptunnel_wizard_desc_outproxies">Bu növ tunel (HTTP və ya SOCKS) üçün hər hansı bir outproxies bilirsinizsə, onları doldurun. Proksiləri vergül vasitəsilə ayırın. </string>
|
||||
<string name="i2ptunnel_wizard_desc_target_host">Bu, xidmətinizin işlədiyi IP-dir, adətən eyni alətdə olduğundan 127.0.0.1 avtomatik olaraq doldurulur.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_port">Bu, xidmət əlaqələrini qəbul edən portdur.</string>
|
||||
<string name="i2ptunnel_wizard_desc_reachable_on">Bu, kompüter və ya smartfonların bu tuneldən istifadəsini məhdudlaşdırır.</string>
|
||||
<string name="i2ptunnel_wizard_desc_binding_port">Bu, müştəri tunelinə lokal olaraq çıxış əldə ediləcək portdur. Bu eyni zamanda, HTTP bidir server tuneli üçün müştəri portudur. </string>
|
||||
<string name="i2ptunnel_wizard_desc_auto_start">İstiqamətləndirici başlayanda tunel avtomatik olaraq başladılmalıdır?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">Tunel yaradılsın?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">Tunel yarat</string>
|
||||
<string name="i2ptunnel_view_target">Məqsəd</string>
|
||||
<string name="i2ptunnel_view_access_point">Giriş nöqtəsi</string>
|
||||
<string name="i2ptunnel_view_autostart">Avtomatik-başlama</string>
|
||||
<string name="address_copied_to_clipboard">Ünvan Mübadilə Buferinə kopyalandı</string>
|
||||
<string name="edit_tunnel">Tuneli dəyiş</string>
|
||||
<string name="name">Ad</string>
|
||||
<string name="description">Açıqlama</string>
|
||||
<string name="auto_start">Avtomatik-başlama</string>
|
||||
<string name="tunnel_summ_auto_start">İstiqamətləndirici başlayanda tuneli başla</string>
|
||||
<string name="tunnel_cat_ports">Yerli portlar</string>
|
||||
<string name="shared_client">Paylaşılan müştərilər</string>
|
||||
<string name="tunnel_summ_shared_client">Digər paylaşılan müştərilər kimi eyni Təyinat yeri və tunellərdən istifadə et</string>
|
||||
<string name="target_destination">Məqsəd hədəfi</string>
|
||||
<string name="persistent_key">Davamlı açar</string>
|
||||
<string name="persistent_key_conflict_title">Təkrar açmaq üçün yeni açarlar söndürülsün?</string>
|
||||
<string name="persistent_key_conflict_msg">Tunel, təkrar açmaq üçün yeni açarların yaradılmasına kökləndiyi zaman davamlı açarları aktivləşdirə bilməzsiniz. Təkrar açmaq üçün yeni düymələri söndürmək istəyirsiniz?</string>
|
||||
<string name="tunnel_summ_persistent_key">Yenidən başlandığında bu tunelin təyinat yerini saxlayın</string>
|
||||
<string name="reachable_on">Əlçatandır</string>
|
||||
<string name="listen_port">Portu dinlə</string>
|
||||
<string name="client_ssl">SSL müştəri</string>
|
||||
<string name="tunnel_summ_client_ssl">Müştəri əlaqə saxlamaq üçün SSL-dən istifadə etməlidir</string>
|
||||
<string name="outproxies">Outproxies </string>
|
||||
<string name="ssl_outproxies">SSL outproxies</string>
|
||||
<string name="irc">IRC</string>
|
||||
<string name="enable_dcc">DCC aktivləşdir</string>
|
||||
<string name="tunnel_summ_enable_dcc">İRC müştərilərinə DCC-dən isifadə etməyə icazə ver</string>
|
||||
<string name="website_domain_name">Saytın domen adı</string>
|
||||
<string name="target_host">Məqsəd host</string>
|
||||
<string name="target_port">Məqsəd port</string>
|
||||
<string name="use_ssl">SSL-dən istifadə et</string>
|
||||
<string name="tunnel_summ_use_ssl">Məqsədə qoşulmaq üçün SSL-dən istifadə edin</string>
|
||||
<string name="tunnel_parameters">Tunel parametrləri</string>
|
||||
<string name="profile">Profil</string>
|
||||
<string name="profile_bulk">Kütləvi bağlantılar (endirilənlər/saytlar/BT)</string>
|
||||
<string name="profile_interactive">İnteraktiv əlaqə</string>
|
||||
<string name="delay_connect">Bağlantının gecikməsi</string>
|
||||
<string name="tunnel_summ_delay_connect">Tələb/ cavab əlaqələri üçün aktivləşdir </string>
|
||||
<string name="access_control">Giriş kontrolu</string>
|
||||
<string name="restricted_access">Məhdud giriş</string>
|
||||
<string name="disabled">Söndürülüb</string>
|
||||
<string name="whitelist">Ağsiyahı</string>
|
||||
<string name="blacklist">Qarasiyahı</string>
|
||||
<string name="access_list">Giriş siyahısı</string>
|
||||
<string name="reject_inproxies">İnproxies-i qəbul etmə</string>
|
||||
<string name="tunnel_summ_reject_inproxies">Yalnız İ2P istifadəçilərinin qoşulmasına icazə ver</string>
|
||||
<string name="unique_local">Bənzərsiz yerli</string>
|
||||
<string name="tunnel_summ_unique_local">Hər bir müştəri üçün bənzərsiz İP yerlihostdan istifadə et </string>
|
||||
<string name="multihome">Multihome</string>
|
||||
<string name="tunnel_summ_multihome">Multihoming optimallaşdırmalarını aktivləşdirin</string>
|
||||
<string name="client_connection_limits">Müştəri əlaqəsi məhdudiyyətləri</string>
|
||||
<string name="connections_per_minute">Bir dəqiqə ərzindəki əlaqələr</string>
|
||||
<string name="connections_per_hour">Bir saat ərzindəki əlaqələr</string>
|
||||
<string name="connections_per_day">Gün ərzindəki əlaqələr</string>
|
||||
<string name="total_connection_limits">Ümumi əlaqə məhdudiyyətləri</string>
|
||||
<string name="total_connections_per_minute">Bir dəqiqə ərzindəki ümumi əlaqələr</string>
|
||||
<string name="total_connections_per_hour">Bir saat ərzindəki ümumi əlaqələr</string>
|
||||
<string name="total_connections_per_day">Bir gün ərzindəki ümumi əlaqələr</string>
|
||||
<string name="max_active_connections">Maksimum fəal əlaqələr</string>
|
||||
<string name="num_per_minute">%sbir dəqiqədə</string>
|
||||
<string name="num_per_hour">%s bir saatda</string>
|
||||
<string name="num_per_day">%sbir gündə</string>
|
||||
<string name="unlimited">Məhdudiyyətsiz</string>
|
||||
<string name="set_zero_for_unlimited">Limitsizlik üçün 0 təyin edin</string>
|
||||
<string name="post_limits">POST məhdudiyyətləri</string>
|
||||
<string name="limit_period">Limit dövrü</string>
|
||||
<string name="client_posts_per_period">Hər dövrə müştəri POST-ları</string>
|
||||
<string name="client_ban_length">Müştəri qadağasının uzunluğu</string>
|
||||
<string name="total_posts_per_period">Hər dövrə POST-ların ümumi sayı</string>
|
||||
<string name="total_ban_length">Qadağanın ümumi uzunluğu</string>
|
||||
<string name="power_saving">Enerjiyə qənaət</string>
|
||||
<string name="delay_open">Açılışın gecikməsi</string>
|
||||
<string name="tunnel_summ_delay_open">Tələb olunana qədər tunelin açılışını təxirə sal</string>
|
||||
<string name="reduce_quantity">Miqdarı azalt</string>
|
||||
<string name="tunnel_summ_reduce_quantity">Tunellərin miqdarını yubanma zamanı azaltmaq</string>
|
||||
<string name="idle_time">Idle zamanı</string>
|
||||
<string name="num_minutes">%sdəqiqə</string>
|
||||
<string name="reduced_tunnel_quantity">Azaldılmış tunel miqdarı</string>
|
||||
<string name="close_tunnels">Yubanma zamanı tunelləri bağlamaq</string>
|
||||
<string name="new_keys_on_reopen">Təkrar açmaq üçün yeni açarlar</string>
|
||||
<string name="new_keys_on_reopen_conflict_title">Davamlı açarlar söndürülsün?</string>
|
||||
<string name="new_keys_on_reopen_conflict_msg">Tunel davamlı açarlara sahip olacaq şəkildə quraşdırılmışkən təkrar açmaq üçün yeni açarları aktivləşdirə bilməzsiniz. Davamlı açarları söndürmək istəyirsiniz?</string>
|
||||
<string name="http_client">HTTP müştəri</string>
|
||||
<string name="tunnel_summ_user_agent">\"İstifadəçi agent\" başlığından keçid</string>
|
||||
<string name="tunnel_summ_referer">\'Referer\' başlığından keçid</string>
|
||||
<string name="tunnel_summ_accept">\'Accept-*\' başlığından keçid</string>
|
||||
<string name="tunnel_summ_allow_ssl">İ2P ünvanları üçün SSL-dən istifadəyə icazə ver</string>
|
||||
<string name="jump_url_list">URL siyahısına keç</string>
|
||||
<string name="proxy_auth">Proksi icazəsi</string>
|
||||
<string name="tunnel_summ_proxy_auth">Bu proksidən istifadə etmək üçün giriş tələb edin</string>
|
||||
<string name="username">İstifadəçi adı</string>
|
||||
<string name="password">Şifrə</string>
|
||||
<string name="outproxy_auth">Outproksi icazəsi</string>
|
||||
<string name="tunnel_summ_outproxy_auth">Outproksi üçün giriş tələb olunur</string>
|
||||
<string name="other">Digər</string>
|
||||
<string name="signature_type">İmza növü</string>
|
||||
<string name="custom_options">Fərdi seçimlər</string>
|
||||
<string name="all">Hamısı</string>
|
||||
<string name="no_messages">İsmarış yoxdur</string>
|
||||
<string name="no_error_messages">Xətalı ismarış yoxdur</string>
|
||||
<string name="log_entry">Jurnal qeydi</string>
|
||||
<string name="copy_logs">Jurnalları kopyala</string>
|
||||
<string name="i2p_android_error_logs">I2P Android xəta jurnalları</string>
|
||||
<string name="i2p_android_logs">I2P Android jurnalları</string>
|
||||
<string name="error_logs_copied_to_clipboard">Xəta jurnalları mübadilə buferinə kopyalandı</string>
|
||||
<string name="logs_copied_to_clipboard">Jurnallar mübadilə buferinə kopyalandı</string>
|
||||
<string name="label_browser_configuration">Səyyah quraşdırılması</string>
|
||||
<string name="no_market_app">Bazar tətbiqi tapılmadı, əl ilə yükləyin</string>
|
||||
<string name="unset">Əvvəlki vəziyyətə qaytarma </string>
|
||||
</resources>
|
@ -132,7 +132,6 @@
|
||||
<string name="settings_label_transports">Transports</string>
|
||||
<string name="settings_label_maxConns">Màx. connexions</string>
|
||||
<string name="settings_label_i2cp">Interfície I2CP</string>
|
||||
<string name="settings_desc_i2cp">Escoltar el port 7654</string>
|
||||
<string name="settings_label_exploratory_pool">Piscina exploratòria</string>
|
||||
<string name="settings_desc_exploratory_pool">Paràmetres del túnel</string>
|
||||
<string name="settings_label_expl_inbound">Túnels d\'entrada</string>
|
||||
@ -149,10 +148,12 @@
|
||||
<string name="settings_label_expl_backupQuantity">Quantitat de còpies de seguretat</string>
|
||||
<string name="settings_summ_expl_backupQuantity">%s túnels</string>
|
||||
<string name="settings_desc_expl_backupQuantity">Quantitat de còpies de seguretat del túnel</string>
|
||||
<string name="menu_about">Quant a</string>
|
||||
<string name="about_version">Versió:</string>
|
||||
<string name="about_helpwanted">Es necessita ajuda!</string>
|
||||
<string name="about_volunteer">Voleu ajudar a millorar l\'aplicació? Oferiu-vos voluntaris al fòrum Android:</string>
|
||||
<string name="menu_help">Ajuda</string>
|
||||
<string name="general">Generals</string>
|
||||
<string name="label_router">Adreces públiques</string>
|
||||
<string name="label_private">Adreces privades</string>
|
||||
<string name="addressbook_add_wizard_k_name">Nom</string>
|
||||
@ -176,6 +177,7 @@
|
||||
<string name="i2ptunnel_wizard_desc_desc">Una descripció del túnel. És opcional i purament informativa.</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">Voleu crear el túnel?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">Crea el túnel</string>
|
||||
<string name="i2ptunnel_view_target">Objectiu</string>
|
||||
<string name="i2ptunnel_view_access_point">Punt d\'accés</string>
|
||||
<string name="edit_tunnel">Edita el túnel</string>
|
||||
<string name="name">Nom</string>
|
||||
@ -190,6 +192,7 @@
|
||||
<string name="profile">Perfil</string>
|
||||
<string name="profile_interactive">Connexió interactiva</string>
|
||||
<string name="access_control">Control d\'accés</string>
|
||||
<string name="disabled">Desactivat</string>
|
||||
<string name="access_list">Llista d\'accés</string>
|
||||
<string name="client_connection_limits">Límit de connexions del client</string>
|
||||
<string name="connections_per_minute">Connexions per minut</string>
|
||||
@ -210,8 +213,10 @@
|
||||
<string name="http_client">Client HTTP</string>
|
||||
<string name="username">Nom d\'usuari</string>
|
||||
<string name="password">Contrasenya</string>
|
||||
<string name="other">Altres</string>
|
||||
<string name="signature_type">Tipus de signatura</string>
|
||||
<string name="custom_options">Opcions personalitzades</string>
|
||||
<string name="all">Tots</string>
|
||||
<string name="no_messages">Sense missatges</string>
|
||||
<string name="copy_logs">Copia registres</string>
|
||||
<string name="i2p_android_error_logs">Registres d\'error d\'I2P Android</string>
|
||||
|
377
app/src/main/res/values-cs/strings.xml
Normal file
377
app/src/main/res/values-cs/strings.xml
Normal file
@ -0,0 +1,377 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="app_name">I2P</string>
|
||||
<string name="desc_i2p_logo">I2P logo</string>
|
||||
<string name="choose_language">Vyberte jazyk</string>
|
||||
<string name="welcome_new_install">Vítejte v I2P! Tato aplikace je ALPHA software a neposkytuje silnou anonymitu. Prosím přečtěte si poznámky k verzi a informace o licenci.</string>
|
||||
<string name="welcome_new_version">Nová verze aktualizována. Prosím přečtěte si poznámky k verzi. Verze:</string>
|
||||
<string name="label_tunnels">Tunely</string>
|
||||
<string name="label_status">Status</string>
|
||||
<string name="label_console">Konzole</string>
|
||||
<string name="label_addresses">Adresy</string>
|
||||
<string name="label_addressbook">Adresář</string>
|
||||
<string name="label_i2ptunnel_client">Tunely klienta</string>
|
||||
<string name="label_i2ptunnel_server">Tunely serveru</string>
|
||||
<string name="label_logs">Záznamy</string>
|
||||
<string name="label_error_logs">Záznamy chyb</string>
|
||||
<string name="label_news">Novinky</string>
|
||||
<string name="label_peers_status">Peery</string>
|
||||
<string name="label_release_notes">Poznámky k verzi</string>
|
||||
<string name="label_licenses">Licence</string>
|
||||
<string name="label_browse">Procházet</string>
|
||||
<string name="label_graphs">Grafy</string>
|
||||
<string name="button_router_off">Dlouze stiskněte pro spuštění I2P</string>
|
||||
<string name="button_router_on">I2P běží (dlouze stiskněte pro zastavení)</string>
|
||||
<string name="button_router_graceful">I2P se vypne za %s</string>
|
||||
<string name="button_shutdown_now">Podržte pro zastavení</string>
|
||||
<string name="button_cancel_graceful">Podržte pro zrušení vypnutí</string>
|
||||
<string name="no_internet">Není dostupné žádné internetové připojení</string>
|
||||
<string name="hidden">Skryté</string>
|
||||
<string name="testing">Testování</string>
|
||||
<string name="firewalled">Za firewallem</string>
|
||||
<string name="symmetric_nat">Symetrický NAT</string>
|
||||
<string name="net_status_error_i2cp">I2CP chyba manažera klienta - zkontrolujte logy</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="net_status_error_skew">Časový rozdíl %s</string>
|
||||
<string name="net_status_error_unresolved_tcp">Nevyřešená/unresolved TCP adresa</string>
|
||||
<string name="net_status_error_private_tcp">Soukromá TCP adresa</string>
|
||||
<string name="net_status_warn_firewalled_inbound_tcp">Za firewallem, zapnutý příchozí TCP</string>
|
||||
<string name="net_status_warn_firewalled_floodfill">Za firewallem a floodfill</string>
|
||||
<string name="net_status_info_disconnected">Odpojeno - zkontrolujte síťové připojení</string>
|
||||
<string name="net_status_error_udp_port">UDP port je používán - změňte v nastavení a restartujte</string>
|
||||
<string name="net_status_error_no_active_peers">Žádní aktivní peeři - zkontrolujte síťové připojení a firewall</string>
|
||||
<string name="net_status_error_udp_disabled_tcp_not_set">UDP vypnuto a příchozí TCP hostitel/port nenastaven</string>
|
||||
<string name="net_status_warn_firewalled_udp_disabled">Za firewallem, vypnutý UDP</string>
|
||||
<string name="shared_clients">Sdílení klienti</string>
|
||||
<string name="uptime">Dostupnost</string>
|
||||
<string name="active_peers">Aktivní peeři</string>
|
||||
<string name="known_peers">Známí peeři</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">B</string>
|
||||
<string name="no_tunnels_running">Zatím neběží žádné tunely.</string>
|
||||
<string name="download">Stáhnout</string>
|
||||
<string name="upload">Nahrát</string>
|
||||
<string name="configure_browser_title">Nastavit prohlížeč?</string>
|
||||
<string name="configure_browser_for_i2p">Přejete si nastavit prohlížeč pro procházení I2P stránek? (Toto můžete udělat i později z menu nápovědy.)</string>
|
||||
<string name="configure_no_doze_title">Spravovat optimalizace baterie?</string>
|
||||
<string name="configure_no_doze">I2P funguje nejlépe, pokud ho necháte běžet. Abyste předešli jeho zavření Androidem ve snaze o úsporu energie, můžete I2P přidat do seznamu výjimek úspory baterie. Toto výrazně zvýší spolehlivost aplikace.\n\nNechat I2P běžet na pozadí? (doporučeno)</string>
|
||||
<string name="first_start_title">Gratulujeme k nainstalování I2P!</string>
|
||||
<string name="first_start_welcome"><b>Vítejte v I2P\'</b>Prosíme<b>buďte trpěliví</b> dokud I2P nenastartuje a najde peery.</string>
|
||||
<string name="first_start_read">Během čekání si prosím přečtěte poznámky k verzi a úvodní stránku.</string>
|
||||
<string name="first_start_faq">Jakmile budete mít klientské tunely, prosíme <b>podívejte se</b> na naše FAQ:</string>
|
||||
<string name="first_start_faq_nonanon">Nebo použijte neanonymní link pokud nechcete čekat na tunely:</string>
|
||||
<string name="first_start_irc">Nasměrujte svého IRC klienta na <b>localhost:6668</b> a pozdravte nás na:</string>
|
||||
<string name="action_search">Hledat</string>
|
||||
<string name="action_add">Přidat</string>
|
||||
<string name="action_edit">Editovat</string>
|
||||
<string name="action_delete">Smazat</string>
|
||||
<string name="action_i2ptunnel_start">Zapnout tunel</string>
|
||||
<string name="action_i2ptunnel_stop">Vypnout tunel</string>
|
||||
<string name="action_i2ptunnel_start_all">Zapnout všechny tunely</string>
|
||||
<string name="action_i2ptunnel_stop_all">Vypnout všechny tunely</string>
|
||||
<string name="action_i2ptunnel_restart_all">Restartovat všechny tunely</string>
|
||||
<string name="action_reload">Načíst znovu</string>
|
||||
<string name="action_refresh">Obnovit</string>
|
||||
<string name="hint_search_addressbook">Prohledat adresář</string>
|
||||
<string name="action_reload_subscriptions">Znovu načíst odběry</string>
|
||||
<string name="news_last_updated">Novinky naposledy aktualizovány před %s</string>
|
||||
<string name="news_last_checked">Novinky naposledy zkontrolovány před %s</string>
|
||||
<string name="news_updated">Novinky aktualizovány</string>
|
||||
<string name="view_news">Dotkněte se pro zobrazení posledních novinek I2P</string>
|
||||
<string name="router_not_running">Tento router nepracuje</string>
|
||||
<string name="router_shutting_down">Router se vypíná.</string>
|
||||
<string name="stats_not_ready">Manažer statistik ještě není připraven. Zkuste to prosím později.</string>
|
||||
<string name="select_an_address">Vyberte adresu.</string>
|
||||
<string name="no_graphs_configured">Žádné grafy nebyly konfigurovány. Můžete si vybrat převod statistik do grafů v menu nastavení. Jakékoliv změny se projeví po 60 sekundách.</string>
|
||||
<string name="configure_graphs">Konfigurovat grafy</string>
|
||||
<string name="graphs_not_ready">Grafy ještě nejsou připraveny. Zkuste to znovu později.</string>
|
||||
<string name="statistics">Statistiky</string>
|
||||
<string name="routers">Routery</string>
|
||||
<string name="leasesets">Sety pronájmu</string>
|
||||
<string name="countries">Země</string>
|
||||
<string name="country">Země</string>
|
||||
<string name="transport">Přenos</string>
|
||||
<string name="versions">Verze</string>
|
||||
<string name="version">Verze</string>
|
||||
<string name="count">Počet</string>
|
||||
<string name="tname_0">Skrytý nebo spouštějící se</string>
|
||||
<string name="netdb_routers_empty">Žádné routery ve vaší NetDB</string>
|
||||
<string name="netdb_leases_empty">Žádné sety pronájmu ve vaší NetDB</string>
|
||||
<string name="notification_status_starting">I2P startuje</string>
|
||||
<string name="notification_status_restarting">I2P se restartuje</string>
|
||||
<string name="notification_status_waiting">I2P čeká na síťové připojení</string>
|
||||
<string name="notification_status_starting_after_waiting">Síť připojena, I2P startuje</string>
|
||||
<string name="notification_status_running">I2P běží</string>
|
||||
<string name="notification_status_client_ready">Klientské tunely jsou připraveny</string>
|
||||
<string name="notification_status_client_down">Klientské tunely neběží</string>
|
||||
<string name="notification_status_graceful">Zastavuji I2P za %s</string>
|
||||
<string name="notification_status_stopping">Zastavuji I2P</string>
|
||||
<string name="notification_status_stopping_after_net">Síť odpojena, zastavuji I2P</string>
|
||||
<string name="notification_status_shutdown_cancelled">Vypnutí zrušeno</string>
|
||||
<string name="notification_status_shutting_down">I2P se vypíná</string>
|
||||
<string name="notification_status_bw">Datový přenos: %1$sBps stahování / %2$sBps nahrávání</string>
|
||||
<string name="notification_status_peers">Peeři: %1$d aktivní, %2$d známí</string>
|
||||
<string name="notification_status_expl">Průzkumné tunely: %1$d/%2$d</string>
|
||||
<string name="notification_status_client">Klientské tunely: %1$d/%2$d</string>
|
||||
<string name="stats_memory">Paměť využitá/max.</string>
|
||||
<string name="stats_lag">Zpoždění práce</string>
|
||||
<string name="stats_delay">Prodleva zprávy</string>
|
||||
<string name="copied_base32_system_notification_title">Base32 zkopírován do schránky</string>
|
||||
<string name="copied_base32_system_notification_body">Adresa vašeho I2P tunelu byla zkopírována do schránky.</string>
|
||||
<string name="menu_settings">Nastavení</string>
|
||||
<string name="settings_enable">Zapnout</string>
|
||||
<string name="settings_desc_subscriptions">URL odběrů</string>
|
||||
<string name="settings_label_bandwidth_net">Datový přenos a síť</string>
|
||||
<string name="settings_label_startOnBoot">Spustit I2P po startu OS</string>
|
||||
<string name="settings_desc_startOnBoot">Automaticky připojit k I2P, jakmile se spustí vaše zařízení Android</string>
|
||||
<string name="settings_label_bandwidth">Šířka pásma</string>
|
||||
<string name="settings_label_bw_inbound">Příchozí rychlost</string>
|
||||
<string name="settings_desc_bw_inbound">Maximální příchozí rychlost</string>
|
||||
<string name="settings_label_bw_outbound">Odchozí rychlost</string>
|
||||
<string name="settings_desc_bw_outbound">Maximální odchozí rychlost</string>
|
||||
<string name="settings_label_network">Síť</string>
|
||||
<string name="settings_label_hiddenMode">Spoluúčast</string>
|
||||
<string name="settings_desc_hiddenMode">Vypnout skrytý režim</string>
|
||||
<string name="settings_label_maxPartTunnels">Max. participujících tunelů</string>
|
||||
<string name="settings_desc_maxPartTunnels">Maximum tunelů na kterých participovat (výchozí=20)</string>
|
||||
<string name="settings_dialog_maxPartTunnels">Maximum tunelů na kterých participovat</string>
|
||||
<string name="settings_label_sharePercent">Procento sdílení</string>
|
||||
<string name="settings_desc_sharePercent">Procento datového přenosu ke sdílení (výchozí=80)</string>
|
||||
<string name="settings_dialog_sharePercent">Procento šířky pásma ke sdílení</string>
|
||||
<string name="settings_desc_upnp">Automatické otevření portů firewallu</string>
|
||||
<string name="settings_label_logging">Logování</string>
|
||||
<string name="settings_label_default_log_level">Výchozí úroveň logování</string>
|
||||
<string name="settings_label_appearance">Podoba</string>
|
||||
<string name="settings_label_language">Jazyk</string>
|
||||
<string name="settings_default">Výchozí</string>
|
||||
<string name="settings_label_advanced">Pokročilé</string>
|
||||
<string name="settings_label_showStats">Statistiky routeru</string>
|
||||
<string name="settings_summ_showStats">Zobrazit pokročilé statistiky na hlavní konzoli</string>
|
||||
<string name="settings_label_transports">Transporty</string>
|
||||
<string name="settings_label_maxConns">Max. připojení</string>
|
||||
<string name="settings_label_i2cp">I2CP rozhraní</string>
|
||||
<string name="settings_desc_i2cp">Povolit aplikacím třetích stran vytvářet tunely pomocí I2CP (vyžaduje restart routeru)</string>
|
||||
<string name="settings_label_sam">SAM rozhraní</string>
|
||||
<string name="settings_desc_sam">Povolit aplikacím třetích stran vytvářet tunely pomocí SAM (vyžaduje restart routeru)</string>
|
||||
<string name="settings_confirm_sam">Aplikace se pokouší navázat připojení SAM.</string>
|
||||
<string name="settings_confirm_sam_id">Název připojení/ID:</string>
|
||||
<string name="settings_confirm_allow_sam">Klepněte pro povolení</string>
|
||||
<string name="settings_confirm_deny_sam">Ignorujte pro zamítnutí</string>
|
||||
<string name="settings_label_exploratory_pool">Průzkumný zásobník</string>
|
||||
<string name="settings_desc_exploratory_pool">Parametry tunelu</string>
|
||||
<string name="settings_label_expl_inbound">Příchozí tunely</string>
|
||||
<string name="settings_label_expl_outbound">Odchozí tunely</string>
|
||||
<string name="settings_label_expl_length">Délka</string>
|
||||
<string name="settings_summ_expl_length">%s skoků</string>
|
||||
<string name="settings_desc_expl_length">Kolik skoků použít</string>
|
||||
<string name="settings_label_expl_lengthVariance">Rozptyl skoků</string>
|
||||
<string name="settings_summ_expl_lengthVariance">%s</string>
|
||||
<string name="settings_desc_expl_lengthVariance">Kolik skoků náhodně přidat</string>
|
||||
<string name="settings_label_expl_quantity">Množství</string>
|
||||
<string name="settings_summ_expl_quantity">%s tunelů</string>
|
||||
<string name="settings_desc_expl_quantity">Kolik tunelů</string>
|
||||
<string name="settings_label_expl_backupQuantity">Množství záloh</string>
|
||||
<string name="settings_summ_expl_backupQuantity">%s tunelů</string>
|
||||
<string name="settings_desc_expl_backupQuantity">Kolik záložních tunelů</string>
|
||||
<string name="settings_need_transport_enabled">Musíte mít zapnut nejméně jeden přenos</string>
|
||||
<string name="settings_router_restart_required">Prosím restartujte I2P pro použití změn</string>
|
||||
<string name="menu_about">O programu</string>
|
||||
<string name="about_version">Version:</string>
|
||||
<string name="about_project">Domov projektu:</string>
|
||||
<string name="about_bugs">Chyby a podpora:</string>
|
||||
<string name="about_helpwanted">Je potřeba pomoc!</string>
|
||||
<string name="about_volunteer">Chcete pomoci vylepšit aplikaci? Staňte se dobrovolníkem pomocí Android fóra:</string>
|
||||
<string name="about_gitlab">Chcete doporučit novou funkci nebo opravu chyby? Vytvořte požadavek na Android Gitlabu:</string>
|
||||
<string name="menu_help">Pomoc</string>
|
||||
<string name="general">Hlavní</string>
|
||||
<string name="label_router">Veřejné adresy</string>
|
||||
<string name="label_private">Soukromé adresy</string>
|
||||
<string name="addressbook_is_empty">Adresář je prázdný</string>
|
||||
<string name="addressbook_search_header">%s nalezeno</string>
|
||||
<string name="addressbook_add_wizard_k_name">Jméno</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Cíl</string>
|
||||
<string name="addressbook_add_wizard_desc_name">Název</string>
|
||||
<string name="addressbook_add_wizard_desc_destination">Sem vložte B64 cíle. Pokud máte nainstalován Správce souborů, můžete ho použít k nalezení souboru, který obsahuje B64.</string>
|
||||
<string name="nsu_iae_illegal_char">Jméno hostitele \"%1$s\" obsahuje nepovolený znak %2$s</string>
|
||||
<string name="nsu_iae_cannot_start_with">Jméno hostitele nemůže začínat \"%s\"</string>
|
||||
<string name="nsu_iae_cannot_end_with">Jméno hostitele nemůže končit \"%s\"</string>
|
||||
<string name="nsu_iae_cannot_contain">Jméno hostitele nemůže obsahovat \"%s\"</string>
|
||||
<string name="nsu_iae_requires_conversion">Jméno hostitele \"%s\" vyžaduje převod do ASCII, ale knihovna pro převod není v této verzi Android dostupná.</string>
|
||||
<string name="i2ptunnel_type_client">Standardní klient</string>
|
||||
<string name="i2ptunnel_type_httpclient">Klient pro HTTP</string>
|
||||
<string name="i2ptunnel_type_ircclient">Klient pro IRC</string>
|
||||
<string name="i2ptunnel_type_server">Standardní server</string>
|
||||
<string name="i2ptunnel_type_httpserver">HTTP server</string>
|
||||
<string name="i2ptunnel_type_sockstunnel">SOCKS 4/4a/5 proxy</string>
|
||||
<string name="i2ptunnel_type_socksirctunnel">SOCKS IRC proxy</string>
|
||||
<string name="i2ptunnel_type_connectclient">CONNECT/SSL/HTTPS proxy</string>
|
||||
<string name="i2ptunnel_type_ircserver">IRC server</string>
|
||||
<string name="i2ptunnel_type_streamrclient">Streamr klient</string>
|
||||
<string name="i2ptunnel_type_streamrserver">Streamr server</string>
|
||||
<string name="i2ptunnel_type_httpbidirserver">HTTP obousměrný</string>
|
||||
<string name="install_recommended_app">Nainstalovat doporučenou aplikaci?</string>
|
||||
<string name="app_needed_for_this_tunnel_type">Pro použití tohoto tunelu potřebujete nainstalovat aplikaci. Chcete nainstalovat doporučenou aplikaci?</string>
|
||||
<string name="i2ptunnel_not_initialized">Tunely nejsou ještě zprovozněny, prosím proveďte obnovu za dvě minuty.</string>
|
||||
<string name="no_configured_client_tunnels">Žádné nastavené klientské tunely.</string>
|
||||
<string name="no_configured_server_tunnels">Žádné nastavené serverové tunely.</string>
|
||||
<string name="i2ptunnel_new_tunnel">Nový tunel</string>
|
||||
<string name="i2ptunnel_msg_config_saved">Změny nastavení byly uloženy</string>
|
||||
<string name="i2ptunnel_msg_config_save_failed">Nepodařilo se uložit nastavení</string>
|
||||
<string name="i2ptunnel_msg_tunnel_starting">Startuji tunel</string>
|
||||
<string name="i2ptunnel_msg_tunnel_stopping">Zastavuji tunel</string>
|
||||
<string name="i2ptunnel_delete_confirm_message">Smazat tunel?</string>
|
||||
<string name="i2ptunnel_delete_confirm_button">Smazat tunel</string>
|
||||
<string name="i2ptunnel_no_tunnel_details">Nepodařilo se načíst detaily tunelu</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">Klient nebo Server</string>
|
||||
<string name="i2ptunnel_wizard_v_client">Klientský tunel</string>
|
||||
<string name="i2ptunnel_wizard_v_server">Serverový tunel</string>
|
||||
<string name="i2ptunnel_wizard_k_type">Typ tunelu</string>
|
||||
<string name="i2ptunnel_wizard_k_name">Jméno</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">Popis</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">Cíl</string>
|
||||
<string name="i2ptunnel_wizard_k_outproxies">Výstupní proxy (Outproxies)</string>
|
||||
<string name="i2ptunnel_wizard_k_target_host">Cílový hostitel</string>
|
||||
<string name="i2ptunnel_wizard_k_target_port">Cílový port</string>
|
||||
<string name="i2ptunnel_wizard_k_reachable_on">Dosažitelné na</string>
|
||||
<string name="i2ptunnel_wizard_k_binding_port">Port pro binding/spojení</string>
|
||||
<string name="i2ptunnel_wizard_k_auto_start">Automatický start</string>
|
||||
<string name="next">Další</string>
|
||||
<string name="prev">Předchozí</string>
|
||||
<string name="finish">Předložit</string>
|
||||
<string name="review">Revidovat</string>
|
||||
<string name="enabled">Povoleno</string>
|
||||
<string name="i2ptunnel_wizard_desc_name">Název tunelu pro rozpoznání v seznamu tunelů.</string>
|
||||
<string name="i2ptunnel_wizard_desc_desc">Popis tunelu. Toto je volitelné a pouze informativní.</string>
|
||||
<string name="i2ptunnel_wizard_desc_dest">Zde stanovte .i2p adresu nebo cíl (jmenohostitele.i2p, b32 nebo b64) tunelu.</string>
|
||||
<string name="i2ptunnel_wizard_desc_outproxies">Pokud víte o jakýchkoli outproxies pro tento typ tunelu (buď HTTP nebo SOCKS), vyplňte je. V případě několika proxies je oddělte čárkami.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_host">Toto je IP, na které běží vaše služba, obvykle je na stejném zařízení, takže je automaticky vyplněna 127.0.0.1.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_port">Toto je port, na kterém služba přijímá připojení.</string>
|
||||
<string name="i2ptunnel_wizard_desc_reachable_on">Toto omezuje které počítače/chytré telefony mohou přistupovat k tomuto tunelu.</string>
|
||||
<string name="i2ptunnel_wizard_desc_binding_port">Toto je port, ze kterého bude lokálně přistupováno ke klientskému tunelu. Je to také klientský port pro obousměrný serverový tunel HTTP.</string>
|
||||
<string name="i2ptunnel_wizard_desc_auto_start">Měl by být tunel automaticky spuštěn při startu routeru?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">Vytvořit tunel?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">Vytvořit tunel</string>
|
||||
<string name="i2ptunnel_view_target">Cíl</string>
|
||||
<string name="i2ptunnel_view_access_point">Přístupový bod</string>
|
||||
<string name="i2ptunnel_view_autostart">Automatické spuštění</string>
|
||||
<string name="address_copied_to_clipboard">Adresa zkopírována do schránky</string>
|
||||
<string name="edit_tunnel">Upravit tunel</string>
|
||||
<string name="name">Jméno</string>
|
||||
<string name="description">Popis</string>
|
||||
<string name="auto_start">Automatické spuštění</string>
|
||||
<string name="tunnel_summ_auto_start">Spustit tunel při startu routeru.</string>
|
||||
<string name="tunnel_cat_ports">Místní porty</string>
|
||||
<string name="shared_client">Sdílený klient</string>
|
||||
<string name="tunnel_summ_shared_client">Použijte stejný cíl a tunely jako ostatní sdílení klienti</string>
|
||||
<string name="target_destination">Cílové umístění</string>
|
||||
<string name="persistent_key">Trvalý klíč</string>
|
||||
<string name="persistent_key_conflict_title">Vypnout nové klíče při opětovném otevření?</string>
|
||||
<string name="persistent_key_conflict_msg">Nemůžete zapnout trvalé klíče když je tunel nastaven pro vygenerování nových klíčů při opětovném otevření. Chcete vypnout nové klíče při opětovném otevření?</string>
|
||||
<string name="tunnel_summ_persistent_key">Uchovat toto cílové umístění při restartu</string>
|
||||
<string name="reachable_on">Dosažitelné na</string>
|
||||
<string name="listen_port">Port naslouchání</string>
|
||||
<string name="client_ssl">SSL klienta</string>
|
||||
<string name="tunnel_summ_client_ssl">Klient musí k připojení používat SSL</string>
|
||||
<string name="outproxies">Výstupní proxy (Outproxies)</string>
|
||||
<string name="ssl_outproxies">SSL outproxies</string>
|
||||
<string name="irc">IRC</string>
|
||||
<string name="enable_dcc">Zapnout DCC</string>
|
||||
<string name="tunnel_summ_enable_dcc">Povolit IRC klientům používat DCC</string>
|
||||
<string name="website_domain_name">Doména webové stránky</string>
|
||||
<string name="target_host">Cílový hostitel</string>
|
||||
<string name="target_port">Cílový port</string>
|
||||
<string name="use_ssl">Použít SSL</string>
|
||||
<string name="tunnel_summ_use_ssl">Použít SSL pro připojení k cíli</string>
|
||||
<string name="tunnel_parameters">Parametry tunelu</string>
|
||||
<string name="profile">Profil</string>
|
||||
<string name="profile_bulk">Hromadné připojení (stahování/webové stránky/BT)</string>
|
||||
<string name="profile_interactive">Interaktivní připojení</string>
|
||||
<string name="delay_connect">Pozdržet připojení</string>
|
||||
<string name="tunnel_summ_delay_connect">Zapnout pro připojení požadavek/odpověď</string>
|
||||
<string name="access_control">Řízení přístupu</string>
|
||||
<string name="restricted_access">Omezený přístup</string>
|
||||
<string name="disabled">Vypnuto</string>
|
||||
<string name="whitelist">Seznam povolených (whitelist)</string>
|
||||
<string name="blacklist">Seznam zakázaných (blacklist)</string>
|
||||
<string name="access_list">Přístupový seznam</string>
|
||||
<string name="reject_inproxies">Odmítnout inproxies</string>
|
||||
<string name="tunnel_summ_reject_inproxies">Povolit připojení jen uživatelům I2P</string>
|
||||
<string name="unique_local">Unikátní místní</string>
|
||||
<string name="tunnel_summ_unique_local">Použít pro každého klienta unikátní místní IP</string>
|
||||
<string name="multihome">Multihome</string>
|
||||
<string name="tunnel_summ_multihome">Zapnout multihoming optimalizace</string>
|
||||
<string name="client_connection_limits">Klientské limity připojení</string>
|
||||
<string name="connections_per_minute">Připojení za minutu</string>
|
||||
<string name="connections_per_hour">Připojení za hodinu</string>
|
||||
<string name="connections_per_day">Připojení za den</string>
|
||||
<string name="total_connection_limits">Celkové limity připojení</string>
|
||||
<string name="total_connections_per_minute">Celkem připojení za minutu</string>
|
||||
<string name="total_connections_per_hour">Celkem připojení za hodinu</string>
|
||||
<string name="total_connections_per_day">Celkem připojení za den</string>
|
||||
<string name="max_active_connections">Maximum aktivních připojení</string>
|
||||
<string name="num_per_minute">%s za minutu</string>
|
||||
<string name="num_per_hour">%s za hodinu</string>
|
||||
<string name="num_per_day">%s za den</string>
|
||||
<string name="unlimited">Neomezeně</string>
|
||||
<string name="set_zero_for_unlimited">Nastavte 0 pro neomezeně</string>
|
||||
<string name="post_limits">POST limity</string>
|
||||
<string name="limit_period">Omezení periody</string>
|
||||
<string name="client_posts_per_period">Požadavky POST klienta za periodu</string>
|
||||
<string name="client_ban_length">Délka zákazu klienta</string>
|
||||
<string name="total_posts_per_period">Celkový počet požadavků POST za periodu</string>
|
||||
<string name="total_ban_length">Celková délka zákazu</string>
|
||||
<string name="power_saving">Úspora energie</string>
|
||||
<string name="delay_open">Prodleva otevření</string>
|
||||
<string name="tunnel_summ_delay_open">Zpozdit otevření tunelu dokud není vyžadováno</string>
|
||||
<string name="reduce_quantity">Snížit množství</string>
|
||||
<string name="tunnel_summ_reduce_quantity">Snížit množství tunelů při nečinnosti</string>
|
||||
<string name="idle_time">Čas nečinnosti</string>
|
||||
<string name="num_minutes">%s minut</string>
|
||||
<string name="reduced_tunnel_quantity">Snížit množství tunelů</string>
|
||||
<string name="close_tunnels">Zavřít tunely při nečinnosti</string>
|
||||
<string name="new_keys_on_reopen">Nové klíče při opětovném otevření</string>
|
||||
<string name="new_keys_on_reopen_conflict_title">Vypnout trvalé klíče</string>
|
||||
<string name="new_keys_on_reopen_conflict_msg">Nemůžete zapnout použití nových klíčů při opětovném otevření, když je tunel nastaven na trvalé klíče. Chcete vypnout trvalé klíče?</string>
|
||||
<string name="http_client">Klient pro HTTP</string>
|
||||
<string name="tunnel_summ_user_agent">Předání hlavičky \'User-Agent\'</string>
|
||||
<string name="tunnel_summ_referer">Předání hlavičky \'Referent\'</string>
|
||||
<string name="tunnel_summ_accept">Předání hlavičky \'Accept-*\'</string>
|
||||
<string name="tunnel_summ_allow_ssl">Povolit SSL I2P adresám</string>
|
||||
<string name="jump_url_list">Seznam Jump URL</string>
|
||||
<string name="proxy_auth">Proxy autorizace</string>
|
||||
<string name="tunnel_summ_proxy_auth">Vyžadovat přihlášení pro použití této proxy</string>
|
||||
<string name="username">Uživatelské jméno</string>
|
||||
<string name="password">Heslo</string>
|
||||
<string name="outproxy_auth">Outproxy autorizace</string>
|
||||
<string name="tunnel_summ_outproxy_auth">Přihlášení vyžadované pro outproxy</string>
|
||||
<string name="other">Další</string>
|
||||
<string name="signature_type">Typ podpisu</string>
|
||||
<string name="custom_options">Vlastní možnosti</string>
|
||||
<string name="all">Vše</string>
|
||||
<string name="no_messages">Žádné zprávy</string>
|
||||
<string name="no_error_messages">Žádné chybové zprávy</string>
|
||||
<plurals name="log_error_messages">
|
||||
<item quantity="one">Jedna chybová zpráva</item>
|
||||
<item quantity="few">%d chybové zprávy, nejnovější nahoře</item>
|
||||
<item quantity="many">%d chybových zpráv, nejnovější nahoře</item>
|
||||
<item quantity="other">%d chybových zpráv, nejnovější nahoře</item>
|
||||
</plurals>
|
||||
<plurals name="log_messages">
|
||||
<item quantity="one">Jedna zpráva</item>
|
||||
<item quantity="few">%d zprávy, nejnovější nahoře</item>
|
||||
<item quantity="many">%d zpráv, nejnovější nahoře</item>
|
||||
<item quantity="other">%d zpráv, nejnovější nahoře</item>
|
||||
</plurals>
|
||||
<string name="log_entry">Záznam logu</string>
|
||||
<string name="copy_logs">Kopírovat logy</string>
|
||||
<string name="i2p_android_error_logs">Chybové logy I2P Android</string>
|
||||
<string name="i2p_android_logs">Logy I2P Android</string>
|
||||
<string name="error_logs_copied_to_clipboard">Chybové logy zkopírovány do schránky</string>
|
||||
<string name="logs_copied_to_clipboard">Logy zkopírovány do schránky</string>
|
||||
<string name="label_browser_configuration">Nastavení prohlížeče</string>
|
||||
<string name="no_market_app">Nenalezena žádná aplikace obchodu, prosím proveďte ruční instalaci</string>
|
||||
<string name="unset">Zrušit nastavení</string>
|
||||
<string name="running_background">I2P běží na pozadí</string>
|
||||
</resources>
|
95
app/src/main/res/values-da/strings.xml
Normal file
95
app/src/main/res/values-da/strings.xml
Normal file
@ -0,0 +1,95 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="label_tunnels">Tunneler</string>
|
||||
<string name="label_status">Status</string>
|
||||
<string name="label_addressbook">Adressebog</string>
|
||||
<string name="label_logs">Logs</string>
|
||||
<string name="label_news">Nyheder</string>
|
||||
<string name="label_peers_status">Peers</string>
|
||||
<string name="label_release_notes">Udgivelsesnoter</string>
|
||||
<string name="label_browse">Brows</string>
|
||||
<string name="label_graphs">Grafer</string>
|
||||
<string name="hidden">Gemt</string>
|
||||
<string name="testing">Tester</string>
|
||||
<string name="firewalled">Firewalled</string>
|
||||
<string name="symmetric_nat">Symmetric NAT</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="uptime">Oppetid</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">S</string>
|
||||
<string name="download">Hente</string>
|
||||
<string name="upload">Upload</string>
|
||||
<string name="action_search">Søg</string>
|
||||
<string name="action_add">Tilføje</string>
|
||||
<string name="action_edit">Ændre</string>
|
||||
<string name="action_delete">Slet</string>
|
||||
<string name="action_reload">Genindlæs</string>
|
||||
<string name="action_refresh">Genopfrisk</string>
|
||||
<string name="statistics">Statistik</string>
|
||||
<string name="routers">Routere</string>
|
||||
<string name="leasesets">LeaseSets</string>
|
||||
<string name="country">Land</string>
|
||||
<string name="transport">Transport</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="count">Antal</string>
|
||||
<string name="tname_0">Gemt eller under opstart</string>
|
||||
<string name="menu_settings">Indstillinger</string>
|
||||
<string name="settings_enable">Aktiver</string>
|
||||
<string name="settings_label_bandwidth">Båndbredde</string>
|
||||
<string name="settings_label_network">Netværk</string>
|
||||
<string name="settings_label_logging">Logning</string>
|
||||
<string name="settings_label_default_log_level">Standard log niveau</string>
|
||||
<string name="settings_label_appearance">Udseende</string>
|
||||
<string name="settings_label_language">Sprog</string>
|
||||
<string name="settings_default">Standard</string>
|
||||
<string name="settings_label_advanced">Avanceret</string>
|
||||
<string name="settings_label_transports">Transporter</string>
|
||||
<string name="settings_label_expl_length">Længde</string>
|
||||
<string name="settings_label_expl_quantity">Mængde</string>
|
||||
<string name="settings_label_expl_backupQuantity">Reserve mængde</string>
|
||||
<string name="menu_about">Om</string>
|
||||
<string name="about_version">Version:</string>
|
||||
<string name="menu_help">Hjælp</string>
|
||||
<string name="general">Genarelt </string>
|
||||
<string name="addressbook_add_wizard_k_name">Navn</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Destination</string>
|
||||
<string name="i2ptunnel_type_client">Standard klient</string>
|
||||
<string name="i2ptunnel_type_httpclient">HTTP klient</string>
|
||||
<string name="i2ptunnel_type_ircclient">Klient for IRC</string>
|
||||
<string name="i2ptunnel_type_server">Standard server</string>
|
||||
<string name="i2ptunnel_type_httpserver">HTTP server</string>
|
||||
<string name="i2ptunnel_type_sockstunnel">SOCKS 4/4a/5 proxy</string>
|
||||
<string name="i2ptunnel_type_socksirctunnel">SOCKS IRC proxy</string>
|
||||
<string name="i2ptunnel_type_connectclient">CONNECT/SSL/HTTPS proxy</string>
|
||||
<string name="i2ptunnel_type_ircserver">Server for IRC</string>
|
||||
<string name="i2ptunnel_type_streamrclient">Klient for Streamr</string>
|
||||
<string name="i2ptunnel_type_streamrserver">Server for Streamr</string>
|
||||
<string name="i2ptunnel_type_httpbidirserver">HTTP bidir</string>
|
||||
<string name="i2ptunnel_new_tunnel">Ny Tunnel</string>
|
||||
<string name="i2ptunnel_msg_config_saved">Konfiguration ændringer gemt</string>
|
||||
<string name="i2ptunnel_msg_config_save_failed">Det mislykkedes at gemme konfigurationen</string>
|
||||
<string name="i2ptunnel_msg_tunnel_starting">Starter tunnel</string>
|
||||
<string name="i2ptunnel_msg_tunnel_stopping">Stopper tunnel</string>
|
||||
<string name="i2ptunnel_wizard_k_name">Navn</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">Beskrivelse</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">Destination</string>
|
||||
<string name="next">Næste</string>
|
||||
<string name="prev">Foregående</string>
|
||||
<string name="finish">Indsend</string>
|
||||
<string name="review">Gennemgå</string>
|
||||
<string name="enabled">Aktiveret</string>
|
||||
<string name="i2ptunnel_view_target">Mål</string>
|
||||
<string name="name">Navn</string>
|
||||
<string name="description">Beskrivelse</string>
|
||||
<string name="use_ssl">Brug SSL</string>
|
||||
<string name="profile">Profil</string>
|
||||
<string name="access_control">Adgangskontrol</string>
|
||||
<string name="disabled">Deaktiveret</string>
|
||||
<string name="http_client">HTTP klient</string>
|
||||
<string name="username">Brugernavn</string>
|
||||
<string name="password">Adgangskode</string>
|
||||
<string name="other">Andet</string>
|
||||
<string name="all">Alle</string>
|
||||
</resources>
|
@ -10,7 +10,7 @@
|
||||
<string name="label_console">Konsole</string>
|
||||
<string name="label_addresses">Adressen</string>
|
||||
<string name="label_addressbook">Adressbuch</string>
|
||||
<string name="label_i2ptunnel_client">Client Tunnel</string>
|
||||
<string name="label_i2ptunnel_client">Clienttunnel</string>
|
||||
<string name="label_i2ptunnel_server">Servertunnel</string>
|
||||
<string name="label_logs">Statusberichte</string>
|
||||
<string name="label_error_logs">Fehlerprotokolle</string>
|
||||
@ -30,7 +30,7 @@
|
||||
<string name="testing">Im Test</string>
|
||||
<string name="firewalled">Durch Firewall geschützt</string>
|
||||
<string name="symmetric_nat">Symmetrisches NAT</string>
|
||||
<string name="net_status_error_i2cp">Klientenmanager I2CP Fehler - bitte Fehlerberichte überprüfen</string>
|
||||
<string name="net_status_error_i2cp">Clientmanager I2CP Fehler - bitte Fehlerberichte überprüfen</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="net_status_error_skew">Zeitabweichung von %s</string>
|
||||
<string name="net_status_error_unresolved_tcp">Nicht aufgelöste TCP-Adresse</string>
|
||||
@ -42,7 +42,7 @@
|
||||
<string name="net_status_error_no_active_peers">Keine aktiven Teilnehmer - überprüfen Sie die Netzwerkverbindung und Firewall</string>
|
||||
<string name="net_status_error_udp_disabled_tcp_not_set">UDP deaktiviert und eingehender TCP-Host/Port nicht festgelegt</string>
|
||||
<string name="net_status_warn_firewalled_udp_disabled">Mit Firewall und deaktiviertem UDP</string>
|
||||
<string name="shared_clients">Mehrere Klienten</string>
|
||||
<string name="shared_clients">Mehrere Clients</string>
|
||||
<string name="uptime">Betriebszeit</string>
|
||||
<string name="active_peers">Aktive Teilnehmer</string>
|
||||
<string name="known_peers">Bekannte Teilnehmer</string>
|
||||
@ -55,12 +55,14 @@
|
||||
<string name="upload">Hochladen</string>
|
||||
<string name="configure_browser_title">Browser konfigurieren?</string>
|
||||
<string name="configure_browser_for_i2p">Möchten Sie einen Browser zum Betrachten von I2P-Seiten einrichten? (Sie können dieses auch später noch im Hilfe-Menü erledigen).</string>
|
||||
<string name="configure_no_doze_title">Batterie Optimierung managen?</string>
|
||||
<string name="configure_no_doze">I2P funktioniert am besten, wenn es dauerhaft läuft. Um Android davon abzuhalten, I2P zu schließen, um Energie zu sparen, solltest du es zur Ausnahmeliste der Energiesparfunktionen hinzufügen. Dies sollte die Zuverlässigkeit des Programms \n\nKeep I2P massgeblich verbessern (empfohlen).</string>
|
||||
<string name="first_start_title">Herzlichen Glückwunsch, Sie haben I2P installiert!</string>
|
||||
<string name="first_start_welcome"><b>Willkommen im I2P</b> Bitte <b>haben Sie Geduld</b>, während I2P startet und Teilnehmer findet.</string>
|
||||
<string name="first_start_read">Lesen Sie bitte die Veröffentlichungshinweise und die Startseite während Sie warten.</string>
|
||||
<string name="first_start_faq">Sobald Sie Kliententunnels haben, <b>lesen</b> Sie bitte unsere FAQ:</string>
|
||||
<string name="first_start_faq_nonanon">Oder verwenden Sie unsere nicht-anonymen Links, wenn Sie nicht auf die Tunnel warten wollen.</string>
|
||||
<string name="first_start_irc">Verbinden Sie Ihren IRC-Klienten mit <b>localhost:6668</b> und schauen Sie bei uns vorbei:</string>
|
||||
<string name="first_start_faq">Sobald Sie Clienttunnel haben, <b>lesen</b> Sie bitte unsere FAQ:</string>
|
||||
<string name="first_start_faq_nonanon">Oder verwenden Sie unseren nicht-anonymen Link, wenn Sie nicht auf die Tunnel warten wollen:</string>
|
||||
<string name="first_start_irc">Verbinden Sie Ihren IRC-Client mit <b>localhost:6668</b> und schauen Sie bei uns vorbei:</string>
|
||||
<string name="action_search">Suche</string>
|
||||
<string name="action_add">Hinzufügen</string>
|
||||
<string name="action_edit">Bearbeiten</string>
|
||||
@ -102,8 +104,8 @@
|
||||
<string name="notification_status_waiting">I2P wartet auf eine Netzwerkverbindung</string>
|
||||
<string name="notification_status_starting_after_waiting">Netzwerk verbunden, I2P wird gestartet</string>
|
||||
<string name="notification_status_running">I2P läuft</string>
|
||||
<string name="notification_status_client_ready">Client-Tunnel sind bereit</string>
|
||||
<string name="notification_status_client_down">Client-Tunnel sind außer Betrieb</string>
|
||||
<string name="notification_status_client_ready">Clienttunnel sind bereit</string>
|
||||
<string name="notification_status_client_down">Clienttunnel sind außer Betrieb</string>
|
||||
<string name="notification_status_graceful">I2P wird in %s gestoppt</string>
|
||||
<string name="notification_status_stopping">I2P wird gestoppt</string>
|
||||
<string name="notification_status_stopping_after_net">Netzwerk getrennt, I2P wird gestoppt</string>
|
||||
@ -112,13 +114,16 @@
|
||||
<string name="notification_status_bw">Bandbreite: %1$sB/s eingehend / %2$sB/s ausgehend</string>
|
||||
<string name="notification_status_peers">Teilnehmer: %1$d aktiv, %2$d bekannt</string>
|
||||
<string name="notification_status_expl">Erkundungstunnel: %1$d/%2$d</string>
|
||||
<string name="notification_status_client">Kliententunnel: %1$d/%2$d</string>
|
||||
<string name="notification_status_client">Clienttunnel: %1$d/%2$d</string>
|
||||
<string name="stats_delay">Nachrichtenverzögerung</string>
|
||||
<string name="copied_base32_system_notification_title">Base32 in die Zwischenablage kopiert</string>
|
||||
<string name="copied_base32_system_notification_body">Die Adresse Ihres I2P-Tunnels wurde in die Zwischenablage kopiert.</string>
|
||||
<string name="menu_settings">Einstellungen</string>
|
||||
<string name="settings_enable">Erlauben</string>
|
||||
<string name="settings_desc_subscriptions">Abonnements-URLs</string>
|
||||
<string name="settings_label_bandwidth_net">Bandbreite und Netzwerk</string>
|
||||
<string name="settings_label_startOnBoot">Beim booten I2P starten</string>
|
||||
<string name="settings_desc_startOnBoot">Automatisch zu I2P verbinden wenn dieses Android Gerät startet</string>
|
||||
<string name="settings_label_startOnBoot">Beim Booten I2P starten</string>
|
||||
<string name="settings_desc_startOnBoot">Automatisch zu I2P verbinden wenn dieses Android-Gerät startet</string>
|
||||
<string name="settings_label_bandwidth">Bandbreite</string>
|
||||
<string name="settings_label_bw_inbound">Eingehende Übertragungsgeschwindigkeit</string>
|
||||
<string name="settings_desc_bw_inbound">Maximale eingehende Übertragungsgeschwindigkeit</string>
|
||||
@ -145,7 +150,13 @@
|
||||
<string name="settings_label_transports">Übertragungen</string>
|
||||
<string name="settings_label_maxConns">Max. Verbindungen</string>
|
||||
<string name="settings_label_i2cp">I2CP-Benutzeroberfläche</string>
|
||||
<string name="settings_desc_i2cp">Auf Port 7654 lauschen</string>
|
||||
<string name="settings_desc_i2cp">Apps von Drittanbietern die Erstellung von Tunneln über I2CP erlauben (erfordert einen Neustart des Routers)</string>
|
||||
<string name="settings_label_sam">SAM-Schnittstelle</string>
|
||||
<string name="settings_desc_sam">Apps von Drittanbietern die Erstellung von Tunneln mit SAM erlauben (erfordert einen Neustart des Routers)</string>
|
||||
<string name="settings_confirm_sam">Eine Anwendung versucht, eine SAM-Verbindung herzustellen.</string>
|
||||
<string name="settings_confirm_sam_id">Verbindungsname/-kennung:</string>
|
||||
<string name="settings_confirm_allow_sam">Zum Erlauben antippen</string>
|
||||
<string name="settings_confirm_deny_sam">Zum Verweigern ignorieren</string>
|
||||
<string name="settings_label_exploratory_pool">Satz an Erkundungstunneln</string>
|
||||
<string name="settings_desc_exploratory_pool">Tunnelparameter</string>
|
||||
<string name="settings_label_expl_inbound">Eingehende Tunnel</string>
|
||||
@ -170,7 +181,6 @@
|
||||
<string name="about_bugs">Fehlermeldungen und Unterstützung:</string>
|
||||
<string name="about_helpwanted">Unterstützer gesucht!!</string>
|
||||
<string name="about_volunteer">Sie wollen mithelfen, die App besser zu machen? Dann schauen Sie in das Android-Forum:</string>
|
||||
<string name="about_donate">Sie wollen Geld oder Bitcoins spenden, damit wir mehr Android-Geräte zum Entwickeln und Testen kaufen können? Gehen Sie auf:</string>
|
||||
<string name="menu_help">Hilfe</string>
|
||||
<string name="general">Allgemein</string>
|
||||
<string name="label_router">Öffentliche Adressen</string>
|
||||
@ -186,22 +196,22 @@
|
||||
<string name="nsu_iae_cannot_end_with">Hostnamen dürfen nicht auf \"%s\" enden</string>
|
||||
<string name="nsu_iae_cannot_contain">Hostnamen dürfen kein \"%s\" beinhalten</string>
|
||||
<string name="nsu_iae_requires_conversion">Hostname \"%s\" muss nach ASCII konvertiert werden, aber die Konvertierungsbibliothek ist in deiner Android-Version nicht verfügbar.</string>
|
||||
<string name="i2ptunnel_type_client">Standardklient</string>
|
||||
<string name="i2ptunnel_type_httpclient">HTTP-Klient</string>
|
||||
<string name="i2ptunnel_type_ircclient">IRC-Klient</string>
|
||||
<string name="i2ptunnel_type_client">Standardclient</string>
|
||||
<string name="i2ptunnel_type_httpclient">HTTP-Client</string>
|
||||
<string name="i2ptunnel_type_ircclient">IRC-Client</string>
|
||||
<string name="i2ptunnel_type_server">Standard-Server</string>
|
||||
<string name="i2ptunnel_type_httpserver">HTTP-Server</string>
|
||||
<string name="i2ptunnel_type_sockstunnel">SOCKS-4/4a/5-Proxy</string>
|
||||
<string name="i2ptunnel_type_socksirctunnel">SOCKS IRC-Proxy</string>
|
||||
<string name="i2ptunnel_type_connectclient">CONNECT/SSL/HTTPS-Proxy</string>
|
||||
<string name="i2ptunnel_type_ircserver">IRC-Server</string>
|
||||
<string name="i2ptunnel_type_streamrclient">Streamr-Klient</string>
|
||||
<string name="i2ptunnel_type_streamrclient">Streamr-Client</string>
|
||||
<string name="i2ptunnel_type_streamrserver">Streamr-Server</string>
|
||||
<string name="i2ptunnel_type_httpbidirserver">HTTP bidirektional</string>
|
||||
<string name="install_recommended_app">Empfohlene App installieren?</string>
|
||||
<string name="app_needed_for_this_tunnel_type">Sie müssen eine App installieren, um diesen Tunnel nutzen zu können. Möchten Sie die empfohlene App installieren?</string>
|
||||
<string name="i2ptunnel_not_initialized">Tunnel sind noch nicht initialisiert. Bitte laden Sie die Seite in zwei Minuten erneut.</string>
|
||||
<string name="no_configured_client_tunnels">Keine konfigurierten Client-Tunnel.</string>
|
||||
<string name="no_configured_client_tunnels">Keine konfigurierten Clienttunnel.</string>
|
||||
<string name="no_configured_server_tunnels">Keine konfigurierten Server-Tunnel.</string>
|
||||
<string name="i2ptunnel_new_tunnel">Neuer Tunnel</string>
|
||||
<string name="i2ptunnel_msg_config_saved">Änderungen gespeichert</string>
|
||||
@ -211,8 +221,8 @@
|
||||
<string name="i2ptunnel_delete_confirm_message">Tunnel löschen?</string>
|
||||
<string name="i2ptunnel_delete_confirm_button">Tunnel löschen</string>
|
||||
<string name="i2ptunnel_no_tunnel_details">Tunneldetails konnten nicht geladen werden</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">Klient oder Server</string>
|
||||
<string name="i2ptunnel_wizard_v_client">Kliententunnel</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">Client oder Server</string>
|
||||
<string name="i2ptunnel_wizard_v_client">Clienttunnel</string>
|
||||
<string name="i2ptunnel_wizard_v_server">Servertunnel</string>
|
||||
<string name="i2ptunnel_wizard_k_type">Tunneltyp</string>
|
||||
<string name="i2ptunnel_wizard_k_name">Name</string>
|
||||
@ -231,12 +241,11 @@
|
||||
<string name="enabled">Aktiviert</string>
|
||||
<string name="i2ptunnel_wizard_desc_name">Der Name des Tunnels zur Erkennung in der Tunnelliste.</string>
|
||||
<string name="i2ptunnel_wizard_desc_desc">Eine optionale, aber für Sie aussagekräftige Beschreibung des Tunnels.</string>
|
||||
<string name="i2ptunnel_wizard_desc_dest">Tragen Sie das I2P Ziel des Dienstes ein, zu welchem sich dieser Klient-Tunnel verbinden soll. Dies kann ein kompletter Base 64 Ziel-Schlüssel oder ein I2P Hostname von Ihrem Adressbuch sein.</string>
|
||||
<string name="i2ptunnel_wizard_desc_outproxies">Falls Sie Ausgangsproxies für diese Tunnelart kennen (entweder HTTP oder SOCKS), geben Sie sie hier ein. Trennen Sie mehrere Proxies mit Kommas.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_host">Das ist die IP, unter der der Dienst erreichbar ist. Normalerweise ist er auf der gleichen Maschine, also wird 127.0.0.1 automatisch ausgefüllt.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_port">Dies ist der Port, unter dem der Dienst erreichbar ist.</string>
|
||||
<string name="i2ptunnel_wizard_desc_reachable_on">Dies legt fest, welche Computer oder Smartphones den Tunnel erreichen können.</string>
|
||||
<string name="i2ptunnel_wizard_desc_binding_port">Dies ist der Port, über den der Klient den Tunnel lokal erreichen kann. Das ist auch der Klient-Port des bidirektionalen HTTP-Server-Tunnels.</string>
|
||||
<string name="i2ptunnel_wizard_desc_binding_port">Dies ist der Port, auf dem der Client auf den Tunnel lokal zugreifen kann. Das ist auch der Client-Port des bidirektionalen HTTP-Servertunnels.</string>
|
||||
<string name="i2ptunnel_wizard_desc_auto_start">Soll der Tunnel automatisch mit dem Router starten?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">Tunnel erstellen?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">Tunnel erstellen</string>
|
||||
@ -250,8 +259,8 @@
|
||||
<string name="auto_start">Automatischer Start</string>
|
||||
<string name="tunnel_summ_auto_start">Tunnel mit dem Router starten.</string>
|
||||
<string name="tunnel_cat_ports">Lokale Ports</string>
|
||||
<string name="shared_client">Gemeinsamer Klient</string>
|
||||
<string name="tunnel_summ_shared_client">Benutzt die selbe Destiantion und Tunnel wie andere geteilte Klienten </string>
|
||||
<string name="shared_client">Gemeinsamer Client</string>
|
||||
<string name="tunnel_summ_shared_client">Benutzt dasselbe Ziel und denselben Tunnel wie andere geteilte Clients</string>
|
||||
<string name="target_destination">Zielort</string>
|
||||
<string name="persistent_key">Persistenter Schlüssel</string>
|
||||
<string name="persistent_key_conflict_title">Neue Schlüssel beim erneuten Öffnen deaktivieren?</string>
|
||||
@ -259,13 +268,13 @@
|
||||
<string name="tunnel_summ_persistent_key">Ziel des Tunnels bei einem Neustart beibehalten</string>
|
||||
<string name="reachable_on">Erreichbarkeit ein</string>
|
||||
<string name="listen_port">Lauschport</string>
|
||||
<string name="client_ssl">Klient-SSL</string>
|
||||
<string name="tunnel_summ_client_ssl">Klienten müssen SSL zum Verbinden verwenden</string>
|
||||
<string name="client_ssl">Client-SSL</string>
|
||||
<string name="tunnel_summ_client_ssl">Clients müssen mit SSL verbinden</string>
|
||||
<string name="outproxies">Ausgangsproxies</string>
|
||||
<string name="ssl_outproxies">SSL-Ausgangsproxies</string>
|
||||
<string name="irc">IRC</string>
|
||||
<string name="enable_dcc">DCC aktivieren</string>
|
||||
<string name="tunnel_summ_enable_dcc">IRC-Klienten die Verwendung von DCC erlauben</string>
|
||||
<string name="tunnel_summ_enable_dcc">IRC-Clients die Verwendung von DCC erlauben</string>
|
||||
<string name="website_domain_name">Webseiten-Domainname</string>
|
||||
<string name="target_host">Zielhost</string>
|
||||
<string name="target_port">Zielport</string>
|
||||
@ -289,7 +298,7 @@
|
||||
<string name="tunnel_summ_unique_local">Verwenden Sie eindeutige localhost-IPs für jeden Client</string>
|
||||
<string name="multihome">Multihome</string>
|
||||
<string name="tunnel_summ_multihome">Aktiviere Optimierungen fürs Multihoming</string>
|
||||
<string name="client_connection_limits">Klient-Verbindungsbegrenzungen</string>
|
||||
<string name="client_connection_limits">Client-Verbindungsbegrenzungen</string>
|
||||
<string name="connections_per_minute">Verbindungen pro Minute</string>
|
||||
<string name="connections_per_hour">Verbindungen pro Stunde</string>
|
||||
<string name="connections_per_day">Verbindungen pro Tag</string>
|
||||
@ -306,7 +315,7 @@
|
||||
<string name="post_limits">POST-Begrenzungen</string>
|
||||
<string name="limit_period">Zeitabschnitt begrenzen</string>
|
||||
<string name="client_posts_per_period">Client-POSTs pro Zeitabschnitt</string>
|
||||
<string name="client_ban_length">Länge der Bannzeit für Klienten</string>
|
||||
<string name="client_ban_length">Länge der Bannzeit für Clients</string>
|
||||
<string name="total_posts_per_period">Gesamte POSTs pro Zeitabschnitt</string>
|
||||
<string name="total_ban_length">Totale Bannzeit</string>
|
||||
<string name="power_saving">Energie sparen</string>
|
||||
@ -321,7 +330,7 @@
|
||||
<string name="new_keys_on_reopen">Neue Schlüssel beim erneuten Öffnen</string>
|
||||
<string name="new_keys_on_reopen_conflict_title">Permanente Schlüssel deaktivieren?</string>
|
||||
<string name="new_keys_on_reopen_conflict_msg">Sie können die Funktion \"Neue Schlüssel beim Start des Tunnels\" nicht nutzen während \"dauerhafter Schlüssel\" aktiviert ist. Möchten Sie \"dauerhafter Schlüssel\" deaktivieren?</string>
|
||||
<string name="http_client">HTTP-Klient</string>
|
||||
<string name="http_client">HTTP-Client</string>
|
||||
<string name="tunnel_summ_user_agent">\"Benutzer-Agent\"-Kopfzeile durchleiten</string>
|
||||
<string name="tunnel_summ_referer">\"Referer\"-Kopfzeile durchleiten</string>
|
||||
<string name="tunnel_summ_accept">\"Accept-*\"-Kopfzeilen durchleiten</string>
|
||||
@ -354,5 +363,7 @@
|
||||
<string name="error_logs_copied_to_clipboard">Fehlerprotokolle in die Zwischenablage kopiert</string>
|
||||
<string name="logs_copied_to_clipboard">Protokolle in die Zwischenablage kopiert</string>
|
||||
<string name="label_browser_configuration">Browserkonfiguration</string>
|
||||
<string name="no_market_app">Keine angebotene App gefunden, bitte manuell installieren.</string>
|
||||
<string name="unset">Deaktivieren</string>
|
||||
<string name="running_background">I2P läuft im Hintergrund</string>
|
||||
</resources>
|
||||
|
102
app/src/main/res/values-el/strings.xml
Normal file
102
app/src/main/res/values-el/strings.xml
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="app_name">I2P</string>
|
||||
<string name="desc_i2p_logo">I2P λογότυπο</string>
|
||||
<string name="choose_language">Επιλογή Γλώσσας</string>
|
||||
<string name="label_tunnels">Τούνελ</string>
|
||||
<string name="label_status">Κατάσταση</string>
|
||||
<string name="label_console">Κονσόλα</string>
|
||||
<string name="label_addresses">Διεύθυνσεις</string>
|
||||
<string name="label_addressbook">Βιβλίο Διεθύνσεων</string>
|
||||
<string name="label_logs">Εγγραφές</string>
|
||||
<string name="label_error_logs">Λάθη Εγγραφών</string>
|
||||
<string name="label_news">Νέα</string>
|
||||
<string name="label_peers_status">Ομότιμοι</string>
|
||||
<string name="label_release_notes">Σημειώσεις έκδοσης</string>
|
||||
<string name="label_licenses">Αδειες</string>
|
||||
<string name="label_browse">Περιήγηση</string>
|
||||
<string name="label_graphs">Γραφήματα</string>
|
||||
<string name="hidden">κρυμμένο</string>
|
||||
<string name="testing">Δοκιμάζει</string>
|
||||
<string name="symmetric_nat">Συμμετρικό NAT</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="net_status_info_disconnected">Αποσυνδέθηκε-ελένξετε την σύνδεση Δικτύου</string>
|
||||
<string name="uptime">Χρόνος λειτουργίας δικτύου</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">S</string>
|
||||
<string name="download">Κατέβασμα</string>
|
||||
<string name="upload">Ανέβασμα</string>
|
||||
<string name="first_start_title">Συνχαριτήρια για την εγκατάσταση του I2P!</string>
|
||||
<string name="action_search">Αναζήτηση</string>
|
||||
<string name="action_add">Προσθήκη</string>
|
||||
<string name="action_edit">Επεξεργασία</string>
|
||||
<string name="action_delete">Διαγραφή</string>
|
||||
<string name="action_i2ptunnel_start">Εκκίνηση τούνελ</string>
|
||||
<string name="action_i2ptunnel_stop">Σταματημα τούνελ</string>
|
||||
<string name="action_i2ptunnel_start_all">Εκκίνηση όλων των τούνελ</string>
|
||||
<string name="action_i2ptunnel_stop_all">Σταματημα όλων των τούνελ</string>
|
||||
<string name="action_i2ptunnel_restart_all">Επανεκκίνηση όλων των τούνελ</string>
|
||||
<string name="action_reload">Επαναφόρτωση</string>
|
||||
<string name="action_refresh">Ανανέωση</string>
|
||||
<string name="hint_search_addressbook">Αναζήτηση βιβλίου διευθήνσεων</string>
|
||||
<string name="news_updated">Νέα ανανεώθηκαν</string>
|
||||
<string name="router_not_running">Ο ρούτερ δέν τρέχει.</string>
|
||||
<string name="select_an_address">Επιλέξτε μια διεύθυνση.</string>
|
||||
<string name="statistics">Στατιστικά</string>
|
||||
<string name="routers">Δρομολογητές</string>
|
||||
<string name="countries">Χώρες</string>
|
||||
<string name="country">Χώρα</string>
|
||||
<string name="transport">Transport</string>
|
||||
<string name="versions">Εκδόσεις</string>
|
||||
<string name="version">Εκδοση</string>
|
||||
<string name="count">Υπολογισμός</string>
|
||||
<string name="tname_0">Κρυμμένο κατά την εκκίνηση</string>
|
||||
<string name="menu_settings">Ρυθμίσεις</string>
|
||||
<string name="settings_enable">Ενεργοποίηση </string>
|
||||
<string name="settings_label_bandwidth">Εύρος Ζώνης</string>
|
||||
<string name="settings_label_network">Δίκτυο</string>
|
||||
<string name="settings_label_hiddenMode">Συμμετοχή</string>
|
||||
<string name="settings_label_logging">Συνδέεται </string>
|
||||
<string name="settings_label_appearance">Εμφάνιση</string>
|
||||
<string name="settings_label_language">Γλώσσα</string>
|
||||
<string name="settings_default">Εξ\'ορισμού</string>
|
||||
<string name="settings_label_advanced">Προχωρημένα</string>
|
||||
<string name="settings_label_expl_length">Μήκος</string>
|
||||
<string name="settings_summ_expl_lengthVariance">%s</string>
|
||||
<string name="settings_label_expl_quantity">Ποσότητα</string>
|
||||
<string name="menu_about">Σχετικά με</string>
|
||||
<string name="about_version">Έκδοση</string>
|
||||
<string name="about_project">Project Home:</string>
|
||||
<string name="menu_help">Βοήθεια</string>
|
||||
<string name="general">Γενικά</string>
|
||||
<string name="addressbook_add_wizard_k_name">Όνομα</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Προορισμός</string>
|
||||
<string name="addressbook_add_wizard_desc_name">Το όνομα</string>
|
||||
<string name="i2ptunnel_type_httpserver">Διακομιστής HTTP</string>
|
||||
<string name="i2ptunnel_new_tunnel">Νέο Τούνελ</string>
|
||||
<string name="i2ptunnel_wizard_k_name">Όνομα</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">Περιγραφή</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">Προορισμός</string>
|
||||
<string name="next">Επόμενο</string>
|
||||
<string name="prev">Προηγούμενο</string>
|
||||
<string name="finish">Υποβολή</string>
|
||||
<string name="review">Ανασκόπηση</string>
|
||||
<string name="enabled">Ενεργοποιημένο</string>
|
||||
<string name="i2ptunnel_view_target">Στόχος</string>
|
||||
<string name="name">Όνομα</string>
|
||||
<string name="description">Περιγραφή</string>
|
||||
<string name="use_ssl">Χρήση SSL</string>
|
||||
<string name="profile">Προφίλ</string>
|
||||
<string name="access_control">Έλεγχος πρόσβασης</string>
|
||||
<string name="disabled">Απενεργοποιημένο</string>
|
||||
<string name="whitelist">Λίστα Επιτρεπόμενων</string>
|
||||
<string name="unlimited">Απεριόριστο</string>
|
||||
<string name="username">Όνομα χρήστη</string>
|
||||
<string name="password">Κωδικός</string>
|
||||
<string name="other">Άλλ</string>
|
||||
<string name="all">Όλοι</string>
|
||||
<string name="no_messages">Κανένα μήνυμα</string>
|
||||
<string name="logs_copied_to_clipboard">Τα αρχεία καταγραφής αντιγράφηκαν στο πρόχειρο</string>
|
||||
</resources>
|
375
app/src/main/res/values-es-rAR/strings.xml
Normal file
375
app/src/main/res/values-es-rAR/strings.xml
Normal file
@ -0,0 +1,375 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="app_name">I2P</string>
|
||||
<string name="desc_i2p_logo">Logotipo de I2P</string>
|
||||
<string name="choose_language">Escoger idioma</string>
|
||||
<string name="welcome_new_install">¡Bienvenido a I2P! Esta aplicación es un software en versión ALFA y no proporciona un anonimato fuerte. Por favor, lea las notas de las versiones y la información sobre la licencia.</string>
|
||||
<string name="welcome_new_version">Nueva versión instalada. Por favor, lea las notas de las versiones. Versión:</string>
|
||||
<string name="label_tunnels">Túneles</string>
|
||||
<string name="label_status">Estado</string>
|
||||
<string name="label_console">Consola</string>
|
||||
<string name="label_addresses">Direcciones</string>
|
||||
<string name="label_addressbook">Libreta de direcciones</string>
|
||||
<string name="label_i2ptunnel_client">Túneles de cliente</string>
|
||||
<string name="label_i2ptunnel_server">Túneles de servidor</string>
|
||||
<string name="label_logs">Registros (log)</string>
|
||||
<string name="label_error_logs">Registros (logs) de errores</string>
|
||||
<string name="label_news">Noticias</string>
|
||||
<string name="label_peers_status">Pares (peers)</string>
|
||||
<string name="label_release_notes">Notas de Versión</string>
|
||||
<string name="label_licenses">Licencias</string>
|
||||
<string name="label_browse">Navegar</string>
|
||||
<string name="label_graphs">Gráficas</string>
|
||||
<string name="button_router_off">Mantenga pulsado para iniciar I2P</string>
|
||||
<string name="button_router_on">I2P está en marcha (mantenga pulsado para detenerlo)</string>
|
||||
<string name="button_router_graceful">I2P se cerrará en %s</string>
|
||||
<string name="button_shutdown_now">Mantenga pulsado para detener ahora</string>
|
||||
<string name="button_cancel_graceful">Mantenga pulsado para cancelar cierre</string>
|
||||
<string name="no_internet">No hay ninguna conexión a Internet disponible</string>
|
||||
<string name="hidden">Oculto</string>
|
||||
<string name="testing">Probando</string>
|
||||
<string name="firewalled">Bloqueado por cortafuegos (firewall)</string>
|
||||
<string name="symmetric_nat">NAT simétrico</string>
|
||||
<string name="net_status_error_i2cp">Error de I2CP del administrador de clientes - compruebe los registros (logs)</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="net_status_error_skew">Desincronización de reloj de %s</string>
|
||||
<string name="net_status_error_unresolved_tcp">Direcciones TCP no resueltas</string>
|
||||
<string name="net_status_error_private_tcp">Direcciones TCP privadas</string>
|
||||
<string name="net_status_warn_firewalled_inbound_tcp">Bloqueado por cortafuegos (firewall) con TCP entrante habilitado</string>
|
||||
<string name="net_status_warn_firewalled_floodfill">Bloqueado por cortafuegos (firewall) y es router I2P de inundación (floodfill)</string>
|
||||
<string name="net_status_info_disconnected">Desconectado - compruebe la conexión a la red</string>
|
||||
<string name="net_status_error_udp_port">Puerto UDP en uso - cámbielo en la configuración y reinicie</string>
|
||||
<string name="net_status_error_no_active_peers">No hay pares (peers) activos - compruebe la conexión a la red y el cortafuegos (firewall)</string>
|
||||
<string name="net_status_error_udp_disabled_tcp_not_set">UDP deshabilitado y nodo/puerto-TCP de entrada no establecido</string>
|
||||
<string name="net_status_warn_firewalled_udp_disabled">Bloqueado por cortafuegos (firewall) con UDP deshabilitado</string>
|
||||
<string name="shared_clients">Clientes compartidos</string>
|
||||
<string name="uptime">Duración de la conexión</string>
|
||||
<string name="active_peers">Pares activos</string>
|
||||
<string name="known_peers">Pares conocidos</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">K</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">G</string>
|
||||
<string name="no_tunnels_running">Aún no hay túneles en marcha.</string>
|
||||
<string name="download">Descargar</string>
|
||||
<string name="upload">Subir</string>
|
||||
<string name="configure_browser_title">¿Configurar navegador?</string>
|
||||
<string name="configure_browser_for_i2p">¿Desea configurar un navegador para ver sitios I2P? (también puede hacer esto más tarde desde el menú de ayuda).</string>
|
||||
<string name="configure_no_doze_title">¿Gestionar las Optimizaciones de la Batería?</string>
|
||||
<string name="configure_no_doze">I2P funciona mejor si sigue funcionando. Para evitar que Android cierre I2P cuando intente ahorrar energía, puede agregarlo a la lista de excepciones de batería. Esto mejorará sustancialmente la fiabilidad de la aplicación. (recomendado)</string>
|
||||
<string name="first_start_title">¡Felicidades por conseguir instalar I2P!</string>
|
||||
<string name="first_start_welcome"><b>¡Bienvenido a I2P!</b> Por favor, <b>tenga paciencia</b> mientras I2P se inicia y busca pares (peers).</string>
|
||||
<string name="first_start_read">Mientras espera, por favor, lea las notas de la versión y la página de bienvenida.</string>
|
||||
<string name="first_start_faq">Una vez tenga túneles de cliente, por favor, <b>eche un vistazo</b> a nuestras preguntas frecuentes (FAQ):</string>
|
||||
<string name="first_start_faq_nonanon">O utilice este enlace no-anónimo si no quiere esperar a los túneles:</string>
|
||||
<string name="first_start_irc">Dirija su cliente IRC hacia <b>localhost:6668</b> y pase a saludarnos en:</string>
|
||||
<string name="action_search">Búsqueda</string>
|
||||
<string name="action_add">Agregar</string>
|
||||
<string name="action_edit">Editar</string>
|
||||
<string name="action_delete">Borrar</string>
|
||||
<string name="action_i2ptunnel_start">Iniciar túnel</string>
|
||||
<string name="action_i2ptunnel_stop">Detener túnel</string>
|
||||
<string name="action_i2ptunnel_start_all">Iniciar todos los túneles</string>
|
||||
<string name="action_i2ptunnel_stop_all">Detener todos los túneles</string>
|
||||
<string name="action_i2ptunnel_restart_all">Reiniciar todos los túneles</string>
|
||||
<string name="action_reload">Recargar</string>
|
||||
<string name="action_refresh">Actualizar</string>
|
||||
<string name="hint_search_addressbook">Buscar en la libreta de direcciones</string>
|
||||
<string name="action_reload_subscriptions">Volver a cargar suscripciones</string>
|
||||
<string name="news_last_updated">Última actualización de las noticias hace %s</string>
|
||||
<string name="news_last_checked">Última comprobación de las noticias hace %s</string>
|
||||
<string name="news_updated">Se han actualizado las noticias</string>
|
||||
<string name="view_news">Pulse para ver las últimas noticias de I2P</string>
|
||||
<string name="router_not_running">El router I2P no está en marcha.</string>
|
||||
<string name="router_shutting_down">El router I2P se está cerrando.</string>
|
||||
<string name="stats_not_ready">El administrador de estadísticas aún no está listo. Inténtelo de nuevo más tarde.</string>
|
||||
<string name="select_an_address">Seleccione una dirección.</string>
|
||||
<string name="no_graphs_configured">No se ha configurado ninguna gráfica. Puede escoger las estadísticas a graficar en el menú de configuración. Cualquier cambio tendrá efecto después de 60 segundos.</string>
|
||||
<string name="configure_graphs">Configurar gráficas</string>
|
||||
<string name="graphs_not_ready">Las gráficas aún no están listas. Inténtelo de nuevo más tarde.</string>
|
||||
<string name="statistics">Estadísticas</string>
|
||||
<string name="routers">Routers I2P</string>
|
||||
<string name="leasesets">LeaseSets</string>
|
||||
<string name="countries">Países </string>
|
||||
<string name="country">País </string>
|
||||
<string name="transport">Transporte</string>
|
||||
<string name="versions">Versiones</string>
|
||||
<string name="version">Versión</string>
|
||||
<string name="count">Conteo</string>
|
||||
<string name="tname_0">Oculto al iniciarse</string>
|
||||
<string name="netdb_routers_empty">No hay routers I2P en su NetDB.</string>
|
||||
<string name="netdb_leases_empty">No hay LeaseSets (túneles al mismo destino I2P) en su NetDB.</string>
|
||||
<string name="notification_status_starting">I2P se está iniciando</string>
|
||||
<string name="notification_status_restarting">I2P se está reiniciando</string>
|
||||
<string name="notification_status_waiting">I2P está esperando una conexión de red</string>
|
||||
<string name="notification_status_starting_after_waiting">Red conectada, I2P se está iniciando</string>
|
||||
<string name="notification_status_running">I2P está en marcha</string>
|
||||
<string name="notification_status_client_ready">Los túneles de cliente están listos</string>
|
||||
<string name="notification_status_client_down">Los túneles de cliente están caídos</string>
|
||||
<string name="notification_status_graceful">Deteniendo I2P en %s</string>
|
||||
<string name="notification_status_stopping">Deteniendo I2P</string>
|
||||
<string name="notification_status_stopping_after_net">Red desconectada, deteniendo I2P</string>
|
||||
<string name="notification_status_shutdown_cancelled">Cierre cancelado</string>
|
||||
<string name="notification_status_shutting_down">I2P se está cerrando</string>
|
||||
<string name="notification_status_bw">Ancho de banda: %1$sBps bajada / %2$sBps subida</string>
|
||||
<string name="notification_status_peers">Pares: %1$d activos, %2$d conocidos</string>
|
||||
<string name="notification_status_expl">Túneles exploratorios: %1$d/%2$d</string>
|
||||
<string name="notification_status_client">Túneles de cliente: %1$d/%2$d</string>
|
||||
<string name="stats_memory">Memoria usada/max</string>
|
||||
<string name="stats_lag">Demora de tareas</string>
|
||||
<string name="stats_delay">Demora de mensajes</string>
|
||||
<string name="copied_base32_system_notification_title">Base32 copiado al portapapeles</string>
|
||||
<string name="copied_base32_system_notification_body">La dirección de su túnel I2P se ha copiado en el portapapeles.</string>
|
||||
<string name="menu_settings">Ajustes</string>
|
||||
<string name="settings_enable">habilitar</string>
|
||||
<string name="settings_desc_subscriptions">URLs de suscripción</string>
|
||||
<string name="settings_label_bandwidth_net">Red y ancho de banda</string>
|
||||
<string name="settings_label_startOnBoot">Iniciar I2P en el arranque</string>
|
||||
<string name="settings_desc_startOnBoot">Conecta automáticamente a I2P cuando arranca su dispositivo Android</string>
|
||||
<string name="settings_label_bandwidth">Ancho de banda</string>
|
||||
<string name="settings_label_bw_inbound">Velocidad de bajada</string>
|
||||
<string name="settings_desc_bw_inbound">Velocidad máxima de bajada</string>
|
||||
<string name="settings_label_bw_outbound">Velocidad de subida</string>
|
||||
<string name="settings_desc_bw_outbound">Velocidad máxima de subida</string>
|
||||
<string name="settings_label_network">Red</string>
|
||||
<string name="settings_label_hiddenMode">Participación</string>
|
||||
<string name="settings_desc_hiddenMode">Desactivar modo oculto</string>
|
||||
<string name="settings_label_maxPartTunnels">Máximo de túneles participantes</string>
|
||||
<string name="settings_desc_maxPartTunnels">Máximo de túneles en los que participar (por defecto=20)</string>
|
||||
<string name="settings_dialog_maxPartTunnels">Máximo de túneles en los que participar</string>
|
||||
<string name="settings_label_sharePercent">Porcentaje de participación</string>
|
||||
<string name="settings_desc_sharePercent">Porcentaje de ancho de banda a compartir (por defecto=80)</string>
|
||||
<string name="settings_dialog_sharePercent">Porcentaje de ancho de banda a compartir</string>
|
||||
<string name="settings_desc_upnp">Abrir los puertos del cortafuegos (firewall) automáticamente</string>
|
||||
<string name="settings_label_logging">Registro (log)</string>
|
||||
<string name="settings_label_default_log_level">Nivel de registro predeterminado</string>
|
||||
<string name="settings_label_appearance">Apariencia</string>
|
||||
<string name="settings_label_language">Idioma</string>
|
||||
<string name="settings_default">Por defecto</string>
|
||||
<string name="settings_label_advanced">Avanzado</string>
|
||||
<string name="settings_label_showStats">Estadísticas del router I2P</string>
|
||||
<string name="settings_summ_showStats">Muestra estadísticas avanzadas en la consola principal</string>
|
||||
<string name="settings_label_transports">Transportes</string>
|
||||
<string name="settings_label_maxConns">Conexiones máximas</string>
|
||||
<string name="settings_label_i2cp">Interfaz de I2CP</string>
|
||||
<string name="settings_desc_i2cp">Permitir que las aplicaciones de terceros creen túneles usando I2CP (requiere el reinicio del enrutador)</string>
|
||||
<string name="settings_label_sam">Interfaz SAM</string>
|
||||
<string name="settings_desc_sam">Permitir que las aplicaciones de terceros creen túneles usando SAM (requiere el reinicio del enrutador)</string>
|
||||
<string name="settings_confirm_sam">Una aplicación está intentando establecer una conexión SAM.</string>
|
||||
<string name="settings_confirm_sam_id">Nombre de conexión/ID:</string>
|
||||
<string name="settings_confirm_allow_sam">Toca para permitir</string>
|
||||
<string name="settings_confirm_deny_sam">Ignorar para negar</string>
|
||||
<string name="settings_label_exploratory_pool">Grupo exploratorio</string>
|
||||
<string name="settings_desc_exploratory_pool">Parámetros de túnel</string>
|
||||
<string name="settings_label_expl_inbound">Túneles de entrada</string>
|
||||
<string name="settings_label_expl_outbound">Túneles de salida</string>
|
||||
<string name="settings_label_expl_length">Longitud</string>
|
||||
<string name="settings_summ_expl_length">%s saltos</string>
|
||||
<string name="settings_desc_expl_length">Cuántos saltos usar</string>
|
||||
<string name="settings_label_expl_lengthVariance">Variabilidad del salto</string>
|
||||
<string name="settings_summ_expl_lengthVariance">%s</string>
|
||||
<string name="settings_desc_expl_lengthVariance">Cuántos saltos se añadirán aleatoriamente.</string>
|
||||
<string name="settings_label_expl_quantity">Cantidad</string>
|
||||
<string name="settings_summ_expl_quantity">%s túneles</string>
|
||||
<string name="settings_desc_expl_quantity">Cuántos túneles</string>
|
||||
<string name="settings_label_expl_backupQuantity">Cantidad de respaldo</string>
|
||||
<string name="settings_summ_expl_backupQuantity">%s túneles</string>
|
||||
<string name="settings_desc_expl_backupQuantity">Cuántos túneles de respaldo</string>
|
||||
<string name="settings_need_transport_enabled">Debe tener al menos un transporte habilitado</string>
|
||||
<string name="settings_router_restart_required">Reinicie I2P para aplicar los cambios</string>
|
||||
<string name="menu_about">Acerca de</string>
|
||||
<string name="about_version">Versión:</string>
|
||||
<string name="about_project">Página principal del proyecto:</string>
|
||||
<string name="about_bugs">Fallos y soporte:</string>
|
||||
<string name="about_helpwanted">¡Buscamos ayuda!</string>
|
||||
<string name="about_volunteer">¿Quiere ayudar a hacer mejor la aplicación? Ofrézcase voluntario en el foro de Android:</string>
|
||||
<string name="about_gitlab">¿Quiere sugerir una función o corregir un error? haga una solicitud de fusión en Android Gitlab:</string>
|
||||
<string name="menu_help">Ayuda</string>
|
||||
<string name="general">General</string>
|
||||
<string name="label_router">Direcciones públicas</string>
|
||||
<string name="label_private">Direcciones privadas</string>
|
||||
<string name="addressbook_is_empty">La libreta de direcciones está vacía</string>
|
||||
<string name="addressbook_search_header">%s encontrados</string>
|
||||
<string name="addressbook_add_wizard_k_name">Nombre</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Destino I2P</string>
|
||||
<string name="addressbook_add_wizard_desc_name">El nombre</string>
|
||||
<string name="addressbook_add_wizard_desc_destination">Pegue la B64 del destino I2P aquí. Si tiene un administrador de ficheros instalado, puede navegar hasta el fichero de texto que contenga la B64.</string>
|
||||
<string name="nsu_iae_illegal_char">El nombre del nodo \"%1$s\" contiene un caracter no permitido %2$s</string>
|
||||
<string name="nsu_iae_cannot_start_with">El nombre del nodo no puede comenzar con \"%s\"</string>
|
||||
<string name="nsu_iae_cannot_end_with">El nombre del nodo no puede finalizar con \"%s\"</string>
|
||||
<string name="nsu_iae_cannot_contain">El nombre del nodo no puede contener \"%s\"</string>
|
||||
<string name="nsu_iae_requires_conversion">El nombre del nodo \"%s\" requiere la conversión a ASCII, pero la librería de conversión no está disponible en esta versión de Android.</string>
|
||||
<string name="i2ptunnel_type_client">Cliente estándar</string>
|
||||
<string name="i2ptunnel_type_httpclient">Cliente HTTP</string>
|
||||
<string name="i2ptunnel_type_ircclient">Cliente IRC</string>
|
||||
<string name="i2ptunnel_type_server">Servidor estándar</string>
|
||||
<string name="i2ptunnel_type_httpserver">Servidor HTTP</string>
|
||||
<string name="i2ptunnel_type_sockstunnel">Proxy SOCKS 4/4a/5</string>
|
||||
<string name="i2ptunnel_type_socksirctunnel">Proxy SOCKS IRC</string>
|
||||
<string name="i2ptunnel_type_connectclient">Proxy CONNECT/SSL/HTTPS</string>
|
||||
<string name="i2ptunnel_type_ircserver">Servidor IRC</string>
|
||||
<string name="i2ptunnel_type_streamrclient">Cliente Streamr</string>
|
||||
<string name="i2ptunnel_type_streamrserver">Servidor Streamr</string>
|
||||
<string name="i2ptunnel_type_httpbidirserver">HTTP bidir</string>
|
||||
<string name="install_recommended_app">¿Instalar aplicación recomendada?</string>
|
||||
<string name="app_needed_for_this_tunnel_type">Tiene que instalar una aplicación para usar este túnel. ¿Desea instalar la aplicación recomendada?</string>
|
||||
<string name="i2ptunnel_not_initialized">Los túneles aún no están inicializados, por favor, vuelva a cargar en dos minutos.</string>
|
||||
<string name="no_configured_client_tunnels">No hay túneles de cliente configurados.</string>
|
||||
<string name="no_configured_server_tunnels">No hay túneles de servidor configurados.</string>
|
||||
<string name="i2ptunnel_new_tunnel">Nuevo túnel</string>
|
||||
<string name="i2ptunnel_msg_config_saved">Se guardaron los cambios en la configuración </string>
|
||||
<string name="i2ptunnel_msg_config_save_failed">No se pudo guardar la configuración</string>
|
||||
<string name="i2ptunnel_msg_tunnel_starting">Iniciando el túnel</string>
|
||||
<string name="i2ptunnel_msg_tunnel_stopping">Deteniendo túnel</string>
|
||||
<string name="i2ptunnel_delete_confirm_message">¿Eliminar túnel?</string>
|
||||
<string name="i2ptunnel_delete_confirm_button">Eliminar túnel</string>
|
||||
<string name="i2ptunnel_no_tunnel_details">No se pudieron cargar los detalles del túnel</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">Cliente o servidor</string>
|
||||
<string name="i2ptunnel_wizard_v_client">Túnel de cliente</string>
|
||||
<string name="i2ptunnel_wizard_v_server">Túnel de servidor</string>
|
||||
<string name="i2ptunnel_wizard_k_type">Tipo de túnel</string>
|
||||
<string name="i2ptunnel_wizard_k_name">Nombre</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">Descripción</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">Destino I2P</string>
|
||||
<string name="i2ptunnel_wizard_k_outproxies">Proxys de salida a Internet</string>
|
||||
<string name="i2ptunnel_wizard_k_target_host">Nodo objetivo</string>
|
||||
<string name="i2ptunnel_wizard_k_target_port">Puerto objetivo</string>
|
||||
<string name="i2ptunnel_wizard_k_reachable_on">Alcanzable en</string>
|
||||
<string name="i2ptunnel_wizard_k_binding_port">Puerto de asociación</string>
|
||||
<string name="i2ptunnel_wizard_k_auto_start">Auto iniciar</string>
|
||||
<string name="next">Siguiente</string>
|
||||
<string name="prev">Anterior</string>
|
||||
<string name="finish">Enviar</string>
|
||||
<string name="review">Revisar</string>
|
||||
<string name="enabled">Activo</string>
|
||||
<string name="i2ptunnel_wizard_desc_name">El nombre del túnel, para su identificación en la lista de túneles.</string>
|
||||
<string name="i2ptunnel_wizard_desc_desc">Una descripción del túnel. Esto es opcional y puramente informativo.</string>
|
||||
<string name="i2ptunnel_wizard_desc_dest">Especifique aquí la dirección .i2p o destino (hostname.i2p, b32 o b64) del túnel.</string>
|
||||
<string name="i2ptunnel_wizard_desc_outproxies">Si sabe de cualquier proxy de salida para este tipo de túnel (bien HTTP o SOCKS), introdúzcalo. Separe los proxys con comas.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_host">Esta es la IP sobre la que su servicio está ejecutándose, como este normalmente está en la misma máquina, se autorellena con 127.0.0.1</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_port">Este es el puerto sobre el que el servicio está aceptando conexiones.</string>
|
||||
<string name="i2ptunnel_wizard_desc_reachable_on">Esto limita qué computadoras o smartphones pueden acceder a este túnel según su alcance.</string>
|
||||
<string name="i2ptunnel_wizard_desc_binding_port">Este es el puerto desde el que se accederá localmente al túnel de cliente. Este también es el puerto del cliente para el túnel de servidor HTTP bidireccional.</string>
|
||||
<string name="i2ptunnel_wizard_desc_auto_start">¿Debe iniciarse automáticamente el túnel cuando se inicia el router I2P?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">¿Crear túnel?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">Crear túnel</string>
|
||||
<string name="i2ptunnel_view_target">Servicio Objetivo</string>
|
||||
<string name="i2ptunnel_view_access_point">Punto de acceso</string>
|
||||
<string name="i2ptunnel_view_autostart">Auto-iniciar</string>
|
||||
<string name="address_copied_to_clipboard">Dirección copiada al portapapeles</string>
|
||||
<string name="edit_tunnel">Editar túnel</string>
|
||||
<string name="name">Nombre</string>
|
||||
<string name="description">Descripción</string>
|
||||
<string name="auto_start">Auto-iniciar</string>
|
||||
<string name="tunnel_summ_auto_start">Inicia el túnel al iniciarse el router I2P.</string>
|
||||
<string name="tunnel_cat_ports">Puertos locales</string>
|
||||
<string name="shared_client">Cliente compartido</string>
|
||||
<string name="tunnel_summ_shared_client">Usa el mismo destino I2P y túneles que otros clientes compartidos</string>
|
||||
<string name="target_destination">Destino I2P objetivo</string>
|
||||
<string name="persistent_key">Clave persistente</string>
|
||||
<string name="persistent_key_conflict_title">¿Deshabilitar generación de nuevas claves al reabrir?</string>
|
||||
<string name="persistent_key_conflict_msg">No puede habilitar claves persistentes mientras el túnel está configurado para generar nuevas claves al reabrir ¿Quiere deshabilitar la generación de nuevas claves al reabrir?</string>
|
||||
<string name="tunnel_summ_persistent_key">Conserva este destino I2P del túnel cuando se reinicie</string>
|
||||
<string name="reachable_on">Alcanzable en</string>
|
||||
<string name="listen_port">Escuchar puerto</string>
|
||||
<string name="client_ssl">SSL de cliente</string>
|
||||
<string name="tunnel_summ_client_ssl">Los clientes tienen que usar SSL para conectar</string>
|
||||
<string name="outproxies">Proxys de salida a Internet</string>
|
||||
<string name="ssl_outproxies">Proxys SSL de salida a Internet</string>
|
||||
<string name="irc">IRC</string>
|
||||
<string name="enable_dcc">Habilitar DCC</string>
|
||||
<string name="tunnel_summ_enable_dcc">Permite usar DCC (conexión directa) a los clientes de IRC</string>
|
||||
<string name="website_domain_name">Nombre de dominio del sitio web</string>
|
||||
<string name="target_host">Nodo objetivo</string>
|
||||
<string name="target_port">Puerto objetivo</string>
|
||||
<string name="use_ssl">Usar SSL</string>
|
||||
<string name="tunnel_summ_use_ssl">Usa SSL para conectar al objetivo</string>
|
||||
<string name="tunnel_parameters">Parámetros de túnel</string>
|
||||
<string name="profile">Perfil</string>
|
||||
<string name="profile_bulk">Conexión masiva (descargas/sitios-web/bittorrent)</string>
|
||||
<string name="profile_interactive">Conexión interactiva</string>
|
||||
<string name="delay_connect">Retardar conexión</string>
|
||||
<string name="tunnel_summ_delay_connect">Habilítelo para conexiones de petición/respuesta</string>
|
||||
<string name="access_control">Control de acceso</string>
|
||||
<string name="restricted_access">Acceso restringido</string>
|
||||
<string name="disabled">Deshabilitado</string>
|
||||
<string name="whitelist">Lista blanca</string>
|
||||
<string name="blacklist">Lista negra</string>
|
||||
<string name="access_list">Lista de acceso</string>
|
||||
<string name="reject_inproxies">Rechazar proxys de entrada desde Internet</string>
|
||||
<string name="tunnel_summ_reject_inproxies">Permite conectar sólo a usuarios de I2P</string>
|
||||
<string name="unique_local">Direcciones locales únicas</string>
|
||||
<string name="tunnel_summ_unique_local">Usa IPs únicas de nodo local (localhost) para cada cliente</string>
|
||||
<string name="multihome">Alojamiento redundante</string>
|
||||
<string name="tunnel_summ_multihome">Habilita optimizaciones de alojamiento redundante (multihoming)</string>
|
||||
<string name="client_connection_limits">Límites de conexiones de los clientes</string>
|
||||
<string name="connections_per_minute">Conexiones por minuto</string>
|
||||
<string name="connections_per_hour">Conexiones por hora</string>
|
||||
<string name="connections_per_day">Conexiones por día</string>
|
||||
<string name="total_connection_limits">Límites totales de conexión</string>
|
||||
<string name="total_connections_per_minute">Conexiones totales por minuto</string>
|
||||
<string name="total_connections_per_hour">Conexiones totales por hora</string>
|
||||
<string name="total_connections_per_day">Conexiones totales por día</string>
|
||||
<string name="max_active_connections">Máximo de conexiones activas</string>
|
||||
<string name="num_per_minute">%s por minuto</string>
|
||||
<string name="num_per_hour">%s por hora</string>
|
||||
<string name="num_per_day">%s por día</string>
|
||||
<string name="unlimited">Ilimitado</string>
|
||||
<string name="set_zero_for_unlimited">Establezca 0 para ilimitado</string>
|
||||
<string name="post_limits">Límites de peticiones POST (HTTP)</string>
|
||||
<string name="limit_period">Periodo límite</string>
|
||||
<string name="client_posts_per_period">POSTs de cliente por periodo</string>
|
||||
<string name="client_ban_length">Duración de la exclusión de cliente</string>
|
||||
<string name="total_posts_per_period">POSTs totales por periodo</string>
|
||||
<string name="total_ban_length">Duración total de las exclusiones</string>
|
||||
<string name="power_saving">Ahorro de energía</string>
|
||||
<string name="delay_open">Retardar apertura</string>
|
||||
<string name="tunnel_summ_delay_open">Retarda la apertura del túnel hasta que sea requerida</string>
|
||||
<string name="reduce_quantity">Reducir cantidad</string>
|
||||
<string name="tunnel_summ_reduce_quantity">Reduce el número de túneles cuando estén desocupados</string>
|
||||
<string name="idle_time">Tiempo desocupado</string>
|
||||
<string name="num_minutes">%s minutos</string>
|
||||
<string name="reduced_tunnel_quantity">Se redujo la cantidad de túneles</string>
|
||||
<string name="close_tunnels">Cerrar túneles cuando estén desocupados</string>
|
||||
<string name="new_keys_on_reopen">Nuevas claves al reabrir</string>
|
||||
<string name="new_keys_on_reopen_conflict_title">¿Deshabilitar claves persistentes?</string>
|
||||
<string name="new_keys_on_reopen_conflict_msg">No puede habilitar nuevas claves al reabrir mientras el túnel está configurado para tener claves persistentes. ¿Quiere deshabilitar claves persistentes?</string>
|
||||
<string name="http_client">Cliente HTTP</string>
|
||||
<string name="tunnel_summ_user_agent">Hace pasar la cabecera \'User-Agent\' (agente del usuario)</string>
|
||||
<string name="tunnel_summ_referer">Hace pasar la cabecera \'Referer\' (procedencia)</string>
|
||||
<string name="tunnel_summ_accept">Hace pasar las cabeceras \'Accept-*\' (tipos de ficheros aceptados)</string>
|
||||
<string name="tunnel_summ_allow_ssl">Permite SSL para direcciones I2P</string>
|
||||
<string name="jump_url_list">Lista de URLs de servicios de salto (jump)</string>
|
||||
<string name="proxy_auth">Autorización del proxy</string>
|
||||
<string name="tunnel_summ_proxy_auth">Se requiere iniciar sesión para usar este proxy</string>
|
||||
<string name="username">Nombre de usuario</string>
|
||||
<string name="password">Contraseña</string>
|
||||
<string name="outproxy_auth">Autorización del proxy de salida a Internet</string>
|
||||
<string name="tunnel_summ_outproxy_auth">Se requiere iniciar sesión para el proxy de salida a Internet</string>
|
||||
<string name="other">Otro</string>
|
||||
<string name="signature_type">Tipo de firma</string>
|
||||
<string name="custom_options">Opciones personalizadas</string>
|
||||
<string name="all">Todos</string>
|
||||
<string name="no_messages">No hay mensajes</string>
|
||||
<string name="no_error_messages">No hay mensajes de error</string>
|
||||
<plurals name="log_error_messages">
|
||||
<item quantity="one">Un mensaje de error</item>
|
||||
<item quantity="many">%d mensajes de error, los más recientes primero</item>
|
||||
<item quantity="other">%d mensajes de error, los más recientes primero</item>
|
||||
</plurals>
|
||||
<plurals name="log_messages">
|
||||
<item quantity="one">Un mensaje</item>
|
||||
<item quantity="many">%d mensajes, los más recientes primero</item>
|
||||
<item quantity="other">%d mensajes, los más recientes primero</item>
|
||||
</plurals>
|
||||
<string name="log_entry">Entrada de registro (log)</string>
|
||||
<string name="copy_logs">Copiar registros (logs)</string>
|
||||
<string name="i2p_android_error_logs">Registros (logs) de errores de I2P Android</string>
|
||||
<string name="i2p_android_logs">Registros (logs) de I2P Android</string>
|
||||
<string name="error_logs_copied_to_clipboard">Los registros (logs) de errores se copiaron al portapapeles</string>
|
||||
<string name="logs_copied_to_clipboard">Registros copiados al portapapeles</string>
|
||||
<string name="label_browser_configuration">Configuración del navegador</string>
|
||||
<string name="no_market_app">No se encontró la aplicación en Android market, por favor, instálela manualmente</string>
|
||||
<string name="unset">No configurado</string>
|
||||
<string name="running_background">I2P se ejecuta en segundo plano</string>
|
||||
</resources>
|
@ -55,6 +55,8 @@
|
||||
<string name="upload">Subida</string>
|
||||
<string name="configure_browser_title">¿Configurar navegador?</string>
|
||||
<string name="configure_browser_for_i2p">¿Desea configurar un navegador para ver sitios I2P? (también puede hacer esto más tarde desde el menú de ayuda).</string>
|
||||
<string name="configure_no_doze_title">¿Gestionar las Optimizaciones de la Batería?</string>
|
||||
<string name="configure_no_doze">I2P funciona mejor si sigue funcionando. Para evitar que Android cierre I2P cuando intente ahorrar energía, puede agregarlo a la lista de excepciones de batería. Esto mejorará sustancialmente la fiabilidad de la aplicación. (recomendado)</string>
|
||||
<string name="first_start_title">¡Felicidades por conseguir instalar I2P!</string>
|
||||
<string name="first_start_welcome"><b>¡Bienvenido a I2P!</b> Por favor, <b>tenga paciencia</b> mientras I2P se inicia y busca pares (peers).</string>
|
||||
<string name="first_start_read">Mientras espera, por favor, lea las notas de la versión y la página de bienvenida.</string>
|
||||
@ -113,6 +115,11 @@
|
||||
<string name="notification_status_peers">Pares: %1$d activos, %2$d conocidos</string>
|
||||
<string name="notification_status_expl">Túneles exploratorios: %1$d/%2$d</string>
|
||||
<string name="notification_status_client">Túneles de cliente: %1$d/%2$d</string>
|
||||
<string name="stats_memory">Memoria usada/max</string>
|
||||
<string name="stats_lag">Demora de tareas</string>
|
||||
<string name="stats_delay">Demora de mensajes</string>
|
||||
<string name="copied_base32_system_notification_title">Base32 copiado al portapapeles</string>
|
||||
<string name="copied_base32_system_notification_body">La dirección de su túnel I2P se ha copiado en el portapapeles.</string>
|
||||
<string name="menu_settings">Configuración</string>
|
||||
<string name="settings_enable">Activar</string>
|
||||
<string name="settings_desc_subscriptions">URLs de suscripción</string>
|
||||
@ -145,7 +152,13 @@
|
||||
<string name="settings_label_transports">Transportes</string>
|
||||
<string name="settings_label_maxConns">Conexiones máximas</string>
|
||||
<string name="settings_label_i2cp">Interfaz de I2CP</string>
|
||||
<string name="settings_desc_i2cp">Escuchar el puerto 7654</string>
|
||||
<string name="settings_desc_i2cp">Permitir que las aplicaciones de terceros creen túneles usando I2CP (requiere el reinicio del enrutador)</string>
|
||||
<string name="settings_label_sam">Interfaz SAM</string>
|
||||
<string name="settings_desc_sam">Permitir que las aplicaciones de terceros creen túneles usando SAM (requiere el reinicio del enrutador)</string>
|
||||
<string name="settings_confirm_sam">Una aplicación está intentando establecer una conexión SAM.</string>
|
||||
<string name="settings_confirm_sam_id">Nombre de conexión/ID:</string>
|
||||
<string name="settings_confirm_allow_sam">Toca para permitir</string>
|
||||
<string name="settings_confirm_deny_sam">Ignorar para negar</string>
|
||||
<string name="settings_label_exploratory_pool">Grupo exploratorio</string>
|
||||
<string name="settings_desc_exploratory_pool">Parámetros de túneles</string>
|
||||
<string name="settings_label_expl_inbound">Túneles de entrada</string>
|
||||
@ -170,7 +183,7 @@
|
||||
<string name="about_bugs">Fallos y soporte:</string>
|
||||
<string name="about_helpwanted">¡Buscamos ayuda!</string>
|
||||
<string name="about_volunteer">¿Quiere ayudar a hacer mejor la aplicación? Ofrézcase voluntario en el foro de Android:</string>
|
||||
<string name="about_donate">¿Quiere donar dinero o bitcoins para la compra de más dispositivos Android para el desarrollo y puesta a prueba? Vaya a:</string>
|
||||
<string name="about_gitlab">¿Quiere sugerir una función o corregir un error? haga una solicitud de fusión en Android Gitlab:</string>
|
||||
<string name="menu_help">Ayuda</string>
|
||||
<string name="general">General</string>
|
||||
<string name="label_router">Direcciones públicas</string>
|
||||
@ -231,7 +244,7 @@
|
||||
<string name="enabled">Habilitado</string>
|
||||
<string name="i2ptunnel_wizard_desc_name">El nombre del túnel, para su identificación en la lista de túneles.</string>
|
||||
<string name="i2ptunnel_wizard_desc_desc">Una descripción del túnel. Esto es opcional y puramente informativo.</string>
|
||||
<string name="i2ptunnel_wizard_desc_dest">Escriba el destino I2P del servicio al que este túnel de cliente debe conectarse. Este podría ser la clave base 64 completa del destino I2P, o un nombre de nodo I2P de su libreta de direcciones.</string>
|
||||
<string name="i2ptunnel_wizard_desc_dest">Especifique aquí la dirección .i2p o destino (hostname.i2p, b32 o b64) del túnel.</string>
|
||||
<string name="i2ptunnel_wizard_desc_outproxies">Si sabe de cualquier proxy de salida para este tipo de túnel (bien HTTP o SOCKS), introdúzcalo. Separe los proxys con comas.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_host">Esta es la IP sobre la que su servicio está ejecutándose, como este normalmente está en la misma máquina, se autorellena con 127.0.0.1</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_port">Este es el puerto sobre el que el servicio está aceptando conexiones.</string>
|
||||
@ -341,10 +354,12 @@
|
||||
<string name="no_error_messages">No hay mensajes de error</string>
|
||||
<plurals name="log_error_messages">
|
||||
<item quantity="one">Un mensaje de error</item>
|
||||
<item quantity="many">%d mensajes de error, los más recientes primero</item>
|
||||
<item quantity="other">%d mensajes de error, los más recientes primero</item>
|
||||
</plurals>
|
||||
<plurals name="log_messages">
|
||||
<item quantity="one">Un mensaje</item>
|
||||
<item quantity="many">%d mensajes, los más recientes primero</item>
|
||||
<item quantity="other">%d mensajes, los más recientes primero</item>
|
||||
</plurals>
|
||||
<string name="log_entry">Entrada de registro (log)</string>
|
||||
@ -356,4 +371,5 @@
|
||||
<string name="label_browser_configuration">Configuración del navegador</string>
|
||||
<string name="no_market_app">No se encontró la aplicación en Android market, por favor, instálela manualmente</string>
|
||||
<string name="unset">No configurado</string>
|
||||
<string name="running_background">I2P se ejecuta en segundo plano</string>
|
||||
</resources>
|
||||
|
227
app/src/main/res/values-fa/strings.xml
Normal file
227
app/src/main/res/values-fa/strings.xml
Normal file
@ -0,0 +1,227 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="app_name">I2P</string>
|
||||
<string name="desc_i2p_logo">لوگو I2P</string>
|
||||
<string name="choose_language">انتخاب زبان</string>
|
||||
<string name="welcome_new_install">به I2P خوش آمدید! این اپلیکیشن برنامه ی ALPHA است و نامحسوسی را بطور کامل پیاده نمیکند.
|
||||
لطفا توضیحات انتشار و توضیحات گواهینامه را مطالعه کنید.</string>
|
||||
<string name="welcome_new_version">نسخه جدید نصب شد. لطفا توضیحات انتشار را مطالعه کنید. نسخه :</string>
|
||||
<string name="label_tunnels">تونل ها</string>
|
||||
<string name="label_status">وضعیت</string>
|
||||
<string name="label_console">کنسول</string>
|
||||
<string name="label_addresses">آدرسها</string>
|
||||
<string name="label_addressbook">دفتر آدرس ها</string>
|
||||
<string name="label_i2ptunnel_client">تونل های کاربر</string>
|
||||
<string name="label_i2ptunnel_server">تونل های سرور</string>
|
||||
<string name="label_logs">گزارش ها</string>
|
||||
<string name="label_error_logs">گزارش خطاها</string>
|
||||
<string name="label_news">اخبار</string>
|
||||
<string name="label_peers_status">همتایان</string>
|
||||
<string name="label_release_notes">توضیحات انتشار</string>
|
||||
<string name="label_licenses">گواهینامه ها</string>
|
||||
<string name="label_browse">جستجو</string>
|
||||
<string name="label_graphs">گراف ها</string>
|
||||
<string name="button_router_off">لمس طولانی برای اجرای I2P</string>
|
||||
<string name="button_router_on">I2P در حال اجرا است (لمس طولانی برای توقف)</string>
|
||||
<string name="button_router_graceful">I2P در %s خاموش خواهد شد</string>
|
||||
<string name="no_internet">هیچ اتصال اینترنتی موجود نمی باشد</string>
|
||||
<string name="hidden">پنهان</string>
|
||||
<string name="testing">در حال تست</string>
|
||||
<string name="symmetric_nat">NAT همگام</string>
|
||||
<!--Parameter is a time, e.g. 32s or 2m-->
|
||||
<string name="net_status_error_unresolved_tcp">آدرس های TCP حل نشده</string>
|
||||
<string name="net_status_error_private_tcp">آدرس TCP خصوصی</string>
|
||||
<string name="shared_clients">کلاینت های به اشتراک گذاشته شده</string>
|
||||
<string name="active_peers">همتایان فعال</string>
|
||||
<string name="known_peers">همتایان شناخته شده</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">S</string>
|
||||
<string name="download">بارگذاری</string>
|
||||
<string name="upload">آپلود</string>
|
||||
<string name="configure_browser_title">پیکربندی مرورگر؟</string>
|
||||
<string name="first_start_title">تبریک بابت نصب I2P!</string>
|
||||
<string name="action_search">جستجو</string>
|
||||
<string name="action_add">اضافه کردن</string>
|
||||
<string name="action_edit">ویرایش </string>
|
||||
<string name="action_delete">پاک کردن</string>
|
||||
<string name="action_i2ptunnel_start">شروع تونل</string>
|
||||
<string name="action_i2ptunnel_stop">توقف تونل</string>
|
||||
<string name="action_i2ptunnel_start_all">شروع تمام تونل ها</string>
|
||||
<string name="action_i2ptunnel_stop_all">توقف تمام تونل ها</string>
|
||||
<string name="action_i2ptunnel_restart_all">راه اندازی مجدد تمام تونل ها</string>
|
||||
<string name="action_reload">بارگذاری مجدد</string>
|
||||
<string name="action_refresh">تازه کردن</string>
|
||||
<string name="hint_search_addressbook">جستجو دفتر آدرس ها</string>
|
||||
<string name="action_reload_subscriptions">بارگذاری مجدد اشتراک ها</string>
|
||||
<string name="news_last_updated">اخبار آخرین بار %s پیش به روز رسانی شد</string>
|
||||
<string name="news_last_checked">اخبار آخرین بار %s پیش بررسی شد</string>
|
||||
<string name="news_updated">اخبار به روز رسانی شد</string>
|
||||
<string name="view_news">برای دیدن آخرین اخبار I2P کلیک کنید</string>
|
||||
<string name="router_not_running">روتر در حال اجرا نیست.</string>
|
||||
<string name="router_shutting_down">روتر در حال خاموش شدن است.</string>
|
||||
<string name="select_an_address">یک آدرس انتخاب کنید.</string>
|
||||
<string name="configure_graphs">پیکربندی گراف ها</string>
|
||||
<string name="graphs_not_ready">گراف ها هنوز آماده نیستند. لطفا بعدا تلاش کنید.</string>
|
||||
<string name="statistics">آمار</string>
|
||||
<string name="routers">روترها</string>
|
||||
<string name="countries">کشورها</string>
|
||||
<string name="country">کشور</string>
|
||||
<string name="transport">انتقال</string>
|
||||
<string name="versions">نسخه ها</string>
|
||||
<string name="version">نسخه</string>
|
||||
<string name="count">شمارش</string>
|
||||
<string name="notification_status_starting">I2P در حال شروع می باشد</string>
|
||||
<string name="notification_status_restarting">I2P در حال راه اندازی مجدد است</string>
|
||||
<string name="notification_status_starting_after_waiting">شبکه اتصال یافت، I2P در حال آغاز است</string>
|
||||
<string name="notification_status_running">I2P در حال اجراست</string>
|
||||
<string name="notification_status_client_ready">تونل های کلاینت آماده می باشند</string>
|
||||
<string name="notification_status_graceful">توقف سازی I2P در %s</string>
|
||||
<string name="notification_status_stopping">در حال توقف I2P</string>
|
||||
<string name="notification_status_stopping_after_net">اتصال شبکه قطع شد، در حال توقف سازی I2P</string>
|
||||
<string name="notification_status_shutdown_cancelled">خاموش کردن لغو شد</string>
|
||||
<string name="notification_status_shutting_down">I2P در حال خاموش شدن است</string>
|
||||
<string name="notification_status_peers">همتایان: %1$d فعال، %2$d شناخته شده</string>
|
||||
<string name="notification_status_client">تونل های کلاینت: %1$d/%2$d</string>
|
||||
<string name="menu_settings">تنظیمات</string>
|
||||
<string name="settings_enable">فعّال</string>
|
||||
<string name="settings_desc_subscriptions">آدرس های اینترنتی اشتراک</string>
|
||||
<string name="settings_label_bandwidth_net">پهنای باند و شبکه</string>
|
||||
<string name="settings_label_startOnBoot">شروع I2P در هنگام بوت</string>
|
||||
<string name="settings_label_bandwidth">پهنای باند</string>
|
||||
<string name="settings_label_bw_inbound">سرعت ورودی</string>
|
||||
<string name="settings_label_bw_outbound">سرعت خروجی</string>
|
||||
<string name="settings_label_network">شبکه</string>
|
||||
<string name="settings_label_hiddenMode">مشارکت</string>
|
||||
<string name="settings_desc_hiddenMode">خاموش کردن حالت پنهان</string>
|
||||
<string name="settings_label_sharePercent">اشتراک گذاری درصد</string>
|
||||
<string name="settings_desc_upnp">باز کردن درگاه های دیوار آتشین به صورت خودکار</string>
|
||||
<string name="settings_label_logging">ثبت وقایع</string>
|
||||
<string name="settings_label_appearance">ظاهر</string>
|
||||
<string name="settings_label_language">زبان</string>
|
||||
<string name="settings_default">پیش فرض</string>
|
||||
<string name="settings_label_advanced">پیشرفته </string>
|
||||
<string name="settings_label_showStats">آمار های روتر</string>
|
||||
<string name="settings_summ_showStats">نمایش آمار های پیشرفته در کنسول اصلی</string>
|
||||
<string name="settings_label_transports">انتقال ها</string>
|
||||
<string name="settings_label_maxConns">اتصالات بیشینه</string>
|
||||
<string name="settings_label_i2cp">رابط I2CP</string>
|
||||
<string name="settings_desc_exploratory_pool">پارامتر های تونل</string>
|
||||
<string name="settings_label_expl_length">طول</string>
|
||||
<string name="settings_summ_expl_length">%s واسطه</string>
|
||||
<string name="settings_summ_expl_lengthVariance">%s</string>
|
||||
<string name="settings_label_expl_quantity">تعداد</string>
|
||||
<string name="settings_summ_expl_quantity">%s تونل</string>
|
||||
<string name="settings_summ_expl_backupQuantity">%s تونل</string>
|
||||
<string name="menu_about">درباره</string>
|
||||
<string name="about_version">نسخه:</string>
|
||||
<string name="about_project">خانه پروژه:</string>
|
||||
<string name="about_bugs">باگ ها و پشتیبانی:</string>
|
||||
<string name="about_helpwanted">نیاز به کمک داریم!</string>
|
||||
<string name="about_volunteer">آیا میخواهید کمک کنید تا برنامه را بهبود ببخشید؟ روی انجمن اندروید داوطلب شوید:</string>
|
||||
<string name="menu_help">راهنمایی</string>
|
||||
<string name="general">عمومی</string>
|
||||
<string name="label_router">آدرس های عمومی</string>
|
||||
<string name="label_private">آدرس های خصوصی</string>
|
||||
<string name="addressbook_is_empty">دفتر آدرس ها خالی می باشد</string>
|
||||
<string name="addressbook_search_header">%s یافت شد</string>
|
||||
<string name="addressbook_add_wizard_k_name">نام</string>
|
||||
<string name="addressbook_add_wizard_k_destination">مقصد</string>
|
||||
<string name="addressbook_add_wizard_desc_name">نام</string>
|
||||
<string name="nsu_iae_cannot_contain">نام میزبان نمی تواند حاوی \"%s\" باشد</string>
|
||||
<string name="i2ptunnel_type_client">کلاینت استاندارد</string>
|
||||
<string name="i2ptunnel_type_httpclient">کلاینت HTTP</string>
|
||||
<string name="i2ptunnel_type_ircclient">کلاینت IRC</string>
|
||||
<string name="i2ptunnel_type_server">سرور استاندارد</string>
|
||||
<string name="i2ptunnel_type_httpserver">سرور HTTP</string>
|
||||
<string name="i2ptunnel_type_ircserver">سرور IRC</string>
|
||||
<string name="i2ptunnel_type_streamrclient">کلاینت Streamr</string>
|
||||
<string name="i2ptunnel_type_streamrserver">سرور Streamr</string>
|
||||
<string name="install_recommended_app">نصب برنامه پیشنهاد شده؟</string>
|
||||
<string name="i2ptunnel_not_initialized">تونل ها فعلا مقداردهی اولیه نشده اند، لطفا در 2 دقیقه دیگر بارگذاری مجدد کنید.</string>
|
||||
<string name="i2ptunnel_new_tunnel">تونل جدید</string>
|
||||
<string name="i2ptunnel_msg_config_saved">تغییرات پیکربندی ذخیره شد</string>
|
||||
<string name="i2ptunnel_msg_config_save_failed">ناموفقیت در ذخیره سازی پیکربندی</string>
|
||||
<string name="i2ptunnel_msg_tunnel_starting">شروع تونل</string>
|
||||
<string name="i2ptunnel_msg_tunnel_stopping">توقف تونل</string>
|
||||
<string name="i2ptunnel_delete_confirm_message">حذف تونل؟</string>
|
||||
<string name="i2ptunnel_delete_confirm_button">حذف تونل</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">کلاینت یا سرور</string>
|
||||
<string name="i2ptunnel_wizard_v_client">تونل کلاینت</string>
|
||||
<string name="i2ptunnel_wizard_v_server">تونل سرور</string>
|
||||
<string name="i2ptunnel_wizard_k_type">نوع تونل</string>
|
||||
<string name="i2ptunnel_wizard_k_name">نام</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">شرح</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">مقصد</string>
|
||||
<string name="i2ptunnel_wizard_k_target_host">میزبان هدف</string>
|
||||
<string name="i2ptunnel_wizard_k_target_port">درگاه هدف</string>
|
||||
<string name="i2ptunnel_wizard_k_reachable_on">قابل دسترس روی</string>
|
||||
<string name="i2ptunnel_wizard_k_auto_start">شروع خودکار</string>
|
||||
<string name="next">بعدی</string>
|
||||
<string name="prev">قبلی</string>
|
||||
<string name="finish">ثبت کردن</string>
|
||||
<string name="review">مرور کنید.</string>
|
||||
<string name="enabled">فعال است</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">ایجاد تونل؟</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">ایجاد تونل</string>
|
||||
<string name="i2ptunnel_view_target">هدف</string>
|
||||
<string name="i2ptunnel_view_access_point">نقطه دسترسی</string>
|
||||
<string name="i2ptunnel_view_autostart">شروع-خودکار</string>
|
||||
<string name="address_copied_to_clipboard">آدرس به کلیپ بورد کپی شد</string>
|
||||
<string name="edit_tunnel">ویرایش تونل</string>
|
||||
<string name="name">نام</string>
|
||||
<string name="description">شرح</string>
|
||||
<string name="auto_start">شروع-خودکار</string>
|
||||
<string name="tunnel_summ_auto_start">شروع تونل در هنگام شروع روتر.</string>
|
||||
<string name="tunnel_cat_ports">پورت های محلی</string>
|
||||
<string name="shared_client">کلاینت به اشتراک گذاشته شده</string>
|
||||
<string name="target_destination">مقصد هدف</string>
|
||||
<string name="persistent_key">کلید مداوم</string>
|
||||
<string name="reachable_on">قابل دسترس روی</string>
|
||||
<string name="listen_port">پورت شنود</string>
|
||||
<string name="client_ssl">SSL کلاینت</string>
|
||||
<string name="tunnel_summ_client_ssl">کلاینت ها باید از SSL برای اتصال استفاده کنند</string>
|
||||
<string name="irc">IRC</string>
|
||||
<string name="enable_dcc">فعال سازی DCC</string>
|
||||
<string name="tunnel_summ_enable_dcc">اجازه به کلاینت های IRC برای استفاده از DCC</string>
|
||||
<string name="website_domain_name">نام دامنه وبسایت</string>
|
||||
<string name="target_host">میزبان هدف</string>
|
||||
<string name="target_port">درگاه هدف</string>
|
||||
<string name="use_ssl">از SSL استفاده کن</string>
|
||||
<string name="tunnel_summ_use_ssl">استفاده از SSL برای اتصال به هدف</string>
|
||||
<string name="tunnel_parameters">پارامتر های تونل</string>
|
||||
<string name="profile">پروفایل</string>
|
||||
<string name="access_control">کنترل دسترسی</string>
|
||||
<string name="restricted_access">دسترسی محدود</string>
|
||||
<string name="disabled">غیر فعال شد</string>
|
||||
<string name="whitelist">لیست سفید</string>
|
||||
<string name="blacklist">لیست سیاه</string>
|
||||
<string name="access_list">لیست دسترسی</string>
|
||||
<string name="unique_local">محل یکتا</string>
|
||||
<string name="client_connection_limits">محدودیت های اتصال کلاینت</string>
|
||||
<string name="connections_per_minute">اتصال ها در دقیقه</string>
|
||||
<string name="connections_per_hour">اتصال ها در ساعت</string>
|
||||
<string name="connections_per_day">اتصال ها در روز</string>
|
||||
<string name="num_per_minute">%s در دقیقه</string>
|
||||
<string name="num_per_hour">%s در ساعت</string>
|
||||
<string name="num_per_day">%s در روز</string>
|
||||
<string name="unlimited">نامحدود</string>
|
||||
<string name="post_limits">محدودیت های POST</string>
|
||||
<string name="limit_period">دوره محدودیت</string>
|
||||
<string name="reduce_quantity">کاهش تعداد</string>
|
||||
<string name="num_minutes">%s دقیقه</string>
|
||||
<string name="new_keys_on_reopen_conflict_title">غیرفعال سازی کلید های مداوم؟</string>
|
||||
<string name="http_client">کلاینت HTTP</string>
|
||||
<string name="jump_url_list">پرش لیست آدرس اینترنتی</string>
|
||||
<string name="proxy_auth">احراز هویت پراکسی</string>
|
||||
<string name="username">نام کاربری</string>
|
||||
<string name="password">رمز عبور</string>
|
||||
<string name="other">دیگر</string>
|
||||
<string name="signature_type">نوع امضا</string>
|
||||
<string name="custom_options">گزینه های سفارشی</string>
|
||||
<string name="all">همه</string>
|
||||
<string name="no_messages">هیچ پیام</string>
|
||||
<string name="no_error_messages">هیچ پیام خطا</string>
|
||||
<string name="label_browser_configuration">پیکربندی مرورگر</string>
|
||||
</resources>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user