Compare commits

..

93 Commits

Author SHA1 Message Date
6352cd9412 Client library 0.5
i2p.i2p tag: i2p-0.9.18
2015-03-02 00:51:30 +00:00
db6c74b4b8 Updated translations 2015-03-02 00:02:40 +00:00
a8d699bea2 (Hopefully) prevent NPE 2015-03-01 23:49:13 +00:00
5d9cb0029f Fixed style API bug 2015-03-01 23:28:11 +00:00
51f7fca1ea Updated translations 2015-03-01 11:08:55 +00:00
c61ccd32ba UDP and NTCP ports, part 2 2015-02-28 12:36:59 +00:00
1debd64bc3 Pull property definitions into one location 2015-02-28 10:19:42 +00:00
561bcfe3fa New translations 2015-02-28 04:59:15 +00:00
1c1f77f5c5 Updated translations 2015-02-28 04:58:27 +00:00
420526a7c4 Updated changelog 2015-02-28 04:57:10 +00:00
99496be412 Settings options for UDP and NTCP ports 2015-02-28 04:49:18 +00:00
b6f1cdc769 Enable Java 1.7 features 2015-02-28 00:46:49 +00:00
75e4153f4e Fix stringOptionsRequiringRestart handling; add NTCP and SSU port parsing 2015-02-27 23:28:01 +00:00
eefa5b8064 Prep work for supporting removal of router.config properties 2015-02-27 22:52:39 +00:00
9d32e44547 Logger: Configurable flush interval
From i2p.i2p rev 2f451e3579eb5df2d316c1b507950d119d59a8da
2015-02-27 11:04:03 +00:00
42a0d552c7 Fixed potential leak 2015-02-27 10:45:42 +00:00
65848dd22b Fix NPE in AddressEntryLoader 2015-02-27 10:20:00 +00:00
610de188a4 Downgrade to Gradle tools 1.0.1
1.1.* cause "Cannot resolve symbol" errors in Android Studio, even though Gradle
can build the app.
2015-02-27 09:50:34 +00:00
f1cd3032c5 Updated FAB library 2015-02-27 01:54:29 +00:00
1a922ba04a Updated build tools 2015-02-27 01:54:17 +00:00
bdd59734ec Updated Android support libraries 2015-02-26 23:34:49 +00:00
fe162e4f5c Updated Android Gradle build tools 2015-02-26 23:34:31 +00:00
69e30e97b8 Updated TODO 2015-02-26 23:33:53 +00:00
513fbe0c9f Updated translations 2015-01-15 10:34:13 +00:00
de23a76e6b Option to start I2P on boot 2015-01-15 10:31:25 +00:00
c9936894d8 Updated TODO 2015-01-15 05:47:01 +00:00
cb6efd9ed8 Updated translations 2015-01-01 23:18:19 +00:00
ad245003bf Updated browser config instructions for Firefox and Orfox 2014-12-29 11:40:04 +00:00
9f27aedc49 Added postman's tunnels to default i2ptunnel.config 2014-12-27 21:43:00 +00:00
d8f883dce8 Feedback from zzz 2014-12-25 09:48:26 +00:00
7db1fbac94 Updated translations 2014-12-23 23:39:13 +00:00
19464124d6 Fixed NPE on browser refresh 2014-12-23 22:30:04 +00:00
5ba616facc Updated TODO (thx for testing zzz) 2014-12-22 00:22:54 +00:00
590a8183aa Fix settings menu Intents in debug build 2014-12-17 02:42:13 +00:00
9a45bbd18c 0.9.17.1
i2p.i2p tag: i2p-0.9.17
2014-12-14 05:15:16 +00:00
c5eedc0a5e Updated translations 2014-12-14 04:28:50 +00:00
715302c813 Upgraded floatingactionbutton to 1.3.0, dropped unused cardview-v7 2014-12-14 04:26:38 +00:00
3327ed722a I2PTunnel: Ask to install app for tunnel, if none are installed when opening 2014-12-12 13:59:02 +00:00
40afd69a54 Enable debug versions to be installed alongside release versions 2014-12-12 13:55:31 +00:00
241381c7fa Fix copy tasks to run every time 2014-12-12 13:17:48 +00:00
7a7ba093db Added CHANGELOG 2014-12-12 06:03:41 +00:00
f0e6744760 Prevent NPE 2014-12-10 12:03:34 +00:00
99002c1c5c Updated translations 2014-12-10 11:51:41 +00:00
605a6c1cf4 Bumped support-v4 dependency in client library to 21.0.2 2014-12-09 21:43:26 +00:00
954a9cc46b Bumped gradle plugin to 1.0.0 2014-12-09 11:56:19 +00:00
1ef838b966 Fixed NPE 2014-12-04 06:56:52 +00:00
c672ca05f5 0.9.17
i2p.i2p tag: i2p-0.9.17
2014-12-02 00:40:17 +00:00
c493e73889 Client library 0.4
i2p.i2p tag: i2p-0.9.17
2014-12-01 08:40:48 +00:00
2b7c280f5b Tunnel details 2014-12-01 08:39:25 +00:00
23eab8a90a FloatingActionButton for I2PTunnel and addressbook 2014-12-01 03:57:21 +00:00
c59103eb76 Comments 2014-12-01 03:14:55 +00:00
f00a35ee09 Move versionCode and versionName definitions to build.gradle 2014-11-30 21:24:47 +00:00
af93725c01 Binding for Services 2014-11-30 11:35:15 +00:00
3953301c57 Fix intent generation 2014-11-30 10:55:34 +00:00
2dab9d5d4f Upgraded support libraries to 21.0.2 2014-11-27 11:42:48 +00:00
b77666fa26 New client library translations for ro 2014-11-25 11:44:46 +00:00
eca931c1b5 Updated translations 2014-11-25 11:44:22 +00:00
86ae77701f 0.9.16-rc1
i2p.i2p: cb66382d9716f7d9cd9441830face910705253e0
2014-11-25 04:48:48 +00:00
c1ee0c4d9e Updated Gradle Witness
Source: https://github.com/WhisperSystems/gradle-witness
Git commit: 10f1269c0aafdc1d478efc005ed48f3a47d44278
2014-11-25 03:51:52 +00:00
e632b35862 Bind to IRouterState using explicit intents (required for API 21 and up) 2014-11-16 18:49:11 +00:00
20d2dcd891 Updated translations 2014-11-16 03:06:29 +00:00
61d5ba5a7c Toolbar back navigation 2014-11-10 11:59:54 +00:00
339f688b7c I2PTunnel help 2014-11-10 11:55:33 +00:00
fed11e703a Don't start new activity if we are already there 2014-11-10 11:33:36 +00:00
438df8142a Settings back navigation 2014-11-10 11:27:11 +00:00
7b3730be24 Updated i2ptunnel.config, dropped Telecomix and Nameless 2014-11-10 10:43:11 +00:00
d6c20bafb3 Material design: one-line text lists 2014-11-10 10:42:05 +00:00
b8998db3a3 Revert to general Intent for selected addressbook entries 2014-11-10 05:39:48 +00:00
9ab1c84878 Material design: settings 2014-11-10 03:41:49 +00:00
2f3335d361 Material design: list items 2014-11-10 02:30:00 +00:00
0e8d900ed4 I2PTunnel secondary action to open linkable tunnels 2014-11-10 01:56:35 +00:00
2c7ce0b7c6 News fragment margins 2014-11-09 12:24:59 +00:00
3e2bdacf89 Material design: I2PTunnel list 2014-11-09 12:13:32 +00:00
64c32076a1 Show correct browser config activity 2014-11-08 07:50:50 +00:00
4d75ce7de1 Missing files 2014-11-08 07:50:30 +00:00
269ae2f569 Help details back nav in toolbar 2014-11-08 06:46:04 +00:00
a42a4b2c99 Reworked help navigation 2014-11-08 03:41:14 +00:00
96f5c2b488 Change property names to match original script (better interop with other repos) 2014-11-08 03:40:48 +00:00
09ab9779aa Addressbook doesn't use two columns yet 2014-11-05 00:50:55 +00:00
97ed0a3a8f NPE fix 2014-11-04 12:18:56 +00:00
ec6d225dc6 Icons for uninstalled supported browsers 2014-11-04 12:07:41 +00:00
800a332691 Swap Orfox with Firefox in supported browsers (no official Orfox release yet) 2014-11-04 12:02:02 +00:00
45eae17561 Simplify browser list UX 2014-11-04 11:54:22 +00:00
092365cab2 Help twopane view 2014-11-04 03:06:03 +00:00
c98c2f101d Updated TODO 2014-11-04 02:46:20 +00:00
8e86634a41 Recommended browsers, Orfox config, link to app store from browser list 2014-11-04 02:43:34 +00:00
7424e5b707 Browser configuration guides for embedded, Orweb, unknown and unsupported 2014-11-04 01:03:59 +00:00
5175c937a9 Help: List browsers, detect ones we know can (not) be configured for I2P 2014-11-03 12:26:58 +00:00
2692a567ab BetterAsyncTaskLoader from Bote 2014-11-03 12:23:24 +00:00
2de971fb52 New translations 2014-11-03 11:46:17 +00:00
403b2e8cd9 Material design: toolbar for help screen 2014-11-03 03:22:29 +00:00
22141e723a Fix back button when drawer indicator disabled 2014-11-02 23:20:13 +00:00
419758125e Updated translations 2014-11-02 12:42:44 +00:00
128 changed files with 2860 additions and 726 deletions

27
CHANGELOG Normal file
View File

@ -0,0 +1,27 @@
0.9.18
* I2P can start automatically when phone boots (configure in Setting)
* Updated browser configuration guides for Orfox and Firefox
* Tunnels for postman's mail server added to defaults (for new installs)
* Settings options for configuring UDP and TCP ports
* Bug fixes and translation updates
0.9.17.1 /2014-12-14 / cd8bb5e3ac4238efac12179c78c4fa517fcaabec
* Fixed crashes in addressbook and netDb status page
* Fixed crash when opening an IRC client tunnel
* Updated translations
0.9.17 / 2014-12-01 / bcf947f433876f643e0f6dff81aac88848b797d3
* Migrated to the new Material design from Android Lollipop
* Added a browser configuration guide
* Improved the help screen
* Upgraded the I2P router to 0.9.17
* Various bug fixes and translation updates
0.9.15.1 / 2014-10-16 / 9cc4e80134cf9becb3838ed3cc78e0bed1363165
* Fixed a configuration bug
0.9.15 / 2014-10-16 / 9b51f78b791c28a580d57f1a5019c94493de6231
* Upgraded the I2P router to 0.9.15
* Added a help screen with some basic information
* Logs can now be copied to the clipboard
* Various user interface improvements and fixes

26
TODO
View File

@ -1,16 +1,34 @@
# Fixes
- Better addressbook column widths
- Better twopane column widths
<zzz> on the i2ptunnel and addressbook pages on the tablet, the columns are too skinny, they aren't as wide as the tab
<zzz> only a few addressbook entries wrap but on i2ptunnel everything is wrapped and most of the screen is empty
- Create tunnel wizard
<zzz> in the tunnel create wizard:
<zzz> 'this could be the full base 64 destination key, or an i2p url from your address book"
<zzz> 'host name' better than 'URL'. Technically speaking, a host name is not a URL
<zzz> hmm would be nice if they could be shared-client or have an option
<zzz> was setting up email tunnels
- I2PTunnel details
<zzz> on the i2ptunnel details, it lists both a 'target' and 'access point' for clients, with the same info
<zzz> generally we use 'target' for servers and 'access point' for clients, never both
- Browser
<zzzccc> Bug report: i2p browser treats 302 as an error
<zzzccc> Bug 2: rotate screen in i2p browser seems to go back one page
# Short-term
- Graceful shutdown option
<zzzccc> Request: graceful shutdown
- Disable uPnP when on cell networks
<zzz> spewing UPnP out into cell networks is a waste of time at best and a security risk at worst, but you really want it for wifi
- I2PTunnel
- Show all messages somewhere
- Improve detail page, expose advanced settings
- Add edit page
- Progress feedback for addressbook subscriptions reload
- Display release notes directly on new router version
- Fill out help pages
- Proper browser configuration page
- Rewrite release notes to be release-specific
- Fix release notes UI, either make back button use clear or add buttons
- NetDB tablet view fixes
@ -32,10 +50,6 @@
- Show fixed x range, not only available data
- Think about pan/zoom
- How to persist data across restarts?
- I2PTunnel
- Show all messages somewhere
- Improve detail page, expose advanced settings
- Add edit page
# Long-term

View File

@ -5,6 +5,8 @@ android {
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
defaultConfig {
versionCode 4745225
versionName '0.9.17.1'
minSdkVersion 9
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
}
@ -14,9 +16,17 @@ android {
buildTypes {
release {
signingConfig signingConfigs.release
runProguard false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
lintOptions {
abortOnError false
@ -37,19 +47,19 @@ android {
dependencies {
compile project(':routerjars')
compile project(':client')
compile 'com.android.support:support-v4:21.0.0'
compile 'com.android.support:appcompat-v7:21.0.0'
compile 'com.android.support:recyclerview-v7:21.0.0'
compile 'com.android.support:cardview-v7:21.0.0'
compile 'com.android.support:support-v4:21.0.3'
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.android.support:recyclerview-v7:21.0.3'
compile 'net.i2p.android.ext:floatingactionbutton:1.8.0'
compile files('libs/androidplot-core-0.6.1.jar')
}
dependencyVerification {
verify = [
'com.android.support:support-v4:199ef7bb169386c80b4836354df6747ce2ae3d24434db923c22439e47106a1e2',
'com.android.support:appcompat-v7:45e999dda55fe81d9cc1c7342b7b70480ff3f307baa8da0df767f92fc5c52cd1',
'com.android.support:recyclerview-v7:ab2390d688601b65e2f3a0718b3d25487e61546c4e20f81eb0b033f30ca15b31',
'com.android.support:cardview-v7:7b724eb46efc98eee70c333cd0e9c34ca89b1a4456c3e40cfcc33501c43570bf',
'com.android.support:support-v4:703572d3015a088cc5604b7e38885af3d307c829d0c5ceaf8654ff41c71cd160',
'com.android.support:appcompat-v7:5dbeb5316d0a6027d646ae552804c3baa5e3bd53f7f33db50904d51505c8a0e5',
'com.android.support:recyclerview-v7:e525ad3f33c84bb12b73d2dc975b55364a53f0f2d0697e043efba59ba73e22d2',
'net.i2p.android.ext:floatingactionbutton:a20d1f0cae15f8965b81486ba31245937968ae6ee5fa6e8a3ea21d7f6c6243ab',
]
}
@ -70,68 +80,65 @@ if (propFile.canRead()) {
println 'local.properties not found'
}
task copyDrawableResources(type: Copy) {
from file(i2pbase + '/installer/resources/themes/console/images/i2plogo.png')
into 'src/main/res/drawable'
}
task certificatesZip(type: Zip) {
archiveName = 'certificates_zip'
from files('' + i2pbase + '/installer/resources/certificates')
}
task copyRawResources(type:Copy) {
from(i2pbase + '/installer/resources/blocklist.txt') { rename { 'blocklist_txt' } }
from(i2pbase + '/installer/resources/hosts.txt') { rename { 'hosts_txt' } }
from('../LICENSE.txt') { rename { 'license_app_txt' } }
from('../licenses/LICENSE-Apache2.0.txt') { rename { 'license_apache20_txt' } }
from(i2pbase + '/licenses') {
include { elem ->
elem.name in [
'LICENSE-ElGamalDSA.txt',
'LICENSE-SHA256.txt',
'LICENSE-BSD.txt',
'LICENSE-SNTP.txt',
'LICENSE-LGPLv2.1.txt',
'LICENSE-InstallCert.txt',
'LICENSE-BlockFile.txt',
'LICENSE-GPLv2.txt',
'LICENSE-GPLv3.txt',
'LICENSE-LGPLv3.txt',
'LICENSE-FatCowIcons.txt',
'LICENSE-Addressbook.txt',
]
}
rename { String name ->
String part = name.substring(8, name.lastIndexOf('.txt'))
String.format('license_%s_txt',
part.toLowerCase(Locale.US).replace('.', '_'))
}
task copyI2PResources(type: Copy) {
// Force this to always run: Copy only detects source changes, not if missing in destination
outputs.upToDateWhen { false }
into 'src/main/res'
into('drawable') {
from file(i2pbase + '/installer/resources/themes/console/images/i2plogo.png')
}
into('raw') {
from(i2pbase + '/installer/resources/blocklist.txt') { rename { 'blocklist_txt' } }
from(i2pbase + '/installer/resources/hosts.txt') { rename { 'hosts_txt' } }
from('../LICENSE.txt') { rename { 'license_app_txt' } }
from('../licenses/LICENSE-Apache2.0.txt') { rename { 'license_apache20_txt' } }
from(i2pbase + '/licenses') {
include { elem ->
elem.name in [
'LICENSE-ElGamalDSA.txt',
'LICENSE-SHA256.txt',
'LICENSE-BSD.txt',
'LICENSE-SNTP.txt',
'LICENSE-LGPLv2.1.txt',
'LICENSE-InstallCert.txt',
'LICENSE-BlockFile.txt',
'LICENSE-GPLv2.txt',
'LICENSE-GPLv3.txt',
'LICENSE-LGPLv3.txt',
'LICENSE-FatCowIcons.txt',
'LICENSE-Addressbook.txt',
]
}
rename { String name ->
String part = name.substring(8, name.lastIndexOf('.txt'))
String.format('license_%s_txt',
part.toLowerCase(Locale.US).replace('.', '_'))
}
}
from certificatesZip
}
from certificatesZip
into 'src/main/res/raw'
}
task copyI2PResources
copyI2PResources.dependsOn copyDrawableResources
copyI2PResources.dependsOn copyRawResources
// For peers WebView
task copyConsoleImagesAssets(type: Copy) {
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')
into 'src/main/assets/themes/console/images'
task copyI2PAssets(type: Copy) {
// Force this to always run: Copy only detects source changes, not if missing in destination
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')
}
into('light') {
from file(i2pbase + '/installer/resources/themes/console/light/console.css')
}
into('light/images') {
from file(i2pbase + '/installer/resources/themes/console/light/images/header.png')
}
}
task copyConsoleLightAssets(type: Copy) {
from file(i2pbase + '/installer/resources/themes/console/light/console.css')
into 'src/main/assets/themes/console/light'
}
task copyConsoleLightImagesAssets(type: Copy) {
from file(i2pbase + '/installer/resources/themes/console/light/images/header.png')
into 'src/main/assets/themes/console/light/images'
}
task copyI2PAssets
copyI2PAssets.dependsOn copyConsoleImagesAssets
copyI2PAssets.dependsOn copyConsoleLightAssets
copyI2PAssets.dependsOn copyConsoleLightImagesAssets
preBuild.dependsOn copyI2PResources
preBuild.dependsOn copyI2PAssets

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">I2P DEBUG</string>
</resources>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/settings_label_bandwidth_net">
<extra
android:name="settings"
android:value="net" />
</header>
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/label_graphs">
<extra
android:name="settings"
android:value="graphs" />
</header>
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/settings_label_logging">
<extra
android:name="settings"
android:value="logging" />
</header>
<header
android:title="@string/label_addressbook">
<intent
android:targetPackage="net.i2p.android.debug"
android:targetClass="net.i2p.android.router.addressbook.AddressbookSettingsActivity" />
</header>
<header
android:fragment="net.i2p.android.router.SettingsActivity$SettingsFragment"
android:title="@string/settings_label_advanced">
<extra
android:name="settings"
android:value="advanced" />
</header>
</preference-headers>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<Preference android:title="@string/settings_label_bandwidth_net">
<intent
android:targetPackage="net.i2p.android.debug"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_NET" />
</Preference>
<Preference android:title="@string/label_graphs">
<intent
android:targetPackage="net.i2p.android.debug"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_GRAPHS" />
</Preference>
<Preference android:title="@string/settings_label_logging">
<intent
android:targetPackage="net.i2p.android.debug"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_LOGGING" />
</Preference>
<Preference android:title="@string/label_addressbook">
<intent
android:targetPackage="net.i2p.android.debug"
android:targetClass="net.i2p.android.router.addressbook.AddressbookSettingsActivity" />
</Preference>
<Preference android:title="@string/settings_label_advanced">
<intent
android:targetPackage="net.i2p.android.debug"
android:targetClass="net.i2p.android.router.SettingsActivity"
android:action="net.i2p.android.router.PREFS_ADVANCED" />
</Preference>
</PreferenceScreen>

View File

@ -1,16 +1,11 @@
<?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:versionCode="4745222"
android:versionName="0.9.15.1">
android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:icon="@drawable/ic_launcher_itoopie"
@ -26,7 +21,12 @@
</service>
<provider
android:name=".provider.CacheProvider"
android:authorities="net.i2p.android" />
android:authorities="${applicationId}.provider" />
<receiver android:name=".receiver.OnBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
@ -59,6 +59,14 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name="net.i2p.android.help.BrowserConfigActivity"
android:label="Browser Configuration"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="net.i2p.android.router.MainActivity" />
</activity>
<activity
android:name=".LicenseActivity"
android:label="I2P License Information"
@ -94,7 +102,7 @@
</activity>
<activity
android:name=".addressbook.AddressbookSettingsActivity"
android:label="I2P Addressbook Settings"
android:label="Addressbook Settings"
android:launchMode="singleTop"
android:parentActivityName=".addressbook.AddressbookActivity">
<meta-data

View File

@ -0,0 +1,82 @@
package net.i2p.android.help;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
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;
/**
* A browser that we don't know about.
*
* @param pm the PackageManager used to find the browser
* @param browser the browser
*/
public Browser(PackageManager pm, ResolveInfo browser) {
this(
browser.activityInfo.packageName,
browser.loadLabel(pm),
browser.loadIcon(pm),
true, false, false, false
);
}
/**
* A browser that we know about.
*
* @param pm the PackageManager used to find the browser
* @param browser the browser
* @param supported can this browser be used with I2P?
*/
public Browser(PackageManager pm, ResolveInfo browser, boolean supported, boolean recommended) {
this(
browser.activityInfo.packageName,
browser.loadLabel(pm),
browser.loadIcon(pm),
true, true, supported, recommended
);
}
public Browser(String pn, CharSequence l, Drawable ic, boolean i, boolean k, boolean s, boolean r) {
packageName = pn;
label = l;
icon = ic;
isInstalled = i;
isKnown = k;
isSupported = s;
isRecommended = r;
}
@Override
public int compareTo(Browser browser) {
// Sort order: supported -> unknown -> unsupported
int a = getOrder(this);
int b = getOrder(browser);
if (a < b)
return -1;
else if (a > b)
return 1;
return label.toString().compareTo(browser.label.toString());
}
private static int getOrder(Browser browser) {
if (browser.isKnown) {
if (browser.isRecommended)
return 0;
else if (browser.isSupported)
return 1;
else
return 3;
} else
return 2;
}
}

View File

@ -0,0 +1,117 @@
package net.i2p.android.help;
import android.content.Context;
import android.content.Intent;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import net.i2p.android.router.R;
public class BrowserAdapter extends RecyclerView.Adapter<BrowserAdapter.ViewHolder> {
private Context mCtx;
private Browser[] mBrowsers;
private OnBrowserSelectedListener mListener;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView mIcon;
public TextView mLabel;
public ImageView mStatus;
public ViewHolder(View v) {
super(v);
mIcon = (ImageView) v.findViewById(R.id.browser_icon);
mLabel = (TextView) v.findViewById(R.id.browser_label);
mStatus = (ImageView) v.findViewById(R.id.browser_status_icon);
}
}
public static interface OnBrowserSelectedListener {
public void onBrowserSelected(Browser browser);
}
public BrowserAdapter(Context ctx, OnBrowserSelectedListener listener) {
mCtx = ctx;
mListener = listener;
}
public void setBrowsers(Browser[] browsers) {
mBrowsers = browsers;
notifyDataSetChanged();
}
public void clear() {
mBrowsers = null;
notifyDataSetChanged();
}
// Create new views (invoked by the layout manager)
@Override
public BrowserAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listitem_browser, parent, false);
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Browser browser = mBrowsers[position];
holder.mIcon.setImageDrawable(browser.icon);
holder.mLabel.setText(browser.label);
if (browser.isKnown) {
if (browser.isRecommended && browser.isInstalled) {
holder.mStatus.setImageDrawable(
mCtx.getResources().getDrawable(R.drawable.ic_stars_white_24dp));
holder.mStatus.setVisibility(View.VISIBLE);
} else if (browser.isSupported && !browser.isInstalled) {
holder.mStatus.setImageDrawable(
mCtx.getResources().getDrawable(R.drawable.ic_shop_white_24dp));
holder.mStatus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String uriMarket = "market://search?q=pname:" + browser.packageName;
Uri uri = Uri.parse(uriMarket);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
mCtx.startActivity(intent);
}
});
holder.mStatus.setVisibility(View.VISIBLE);
} else if (!browser.isSupported) {
// Make the icon gray-scale to show it is unsupported
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
holder.mIcon.setColorFilter(filter);
holder.mLabel.setTextColor(
mCtx.getResources().getColor(R.color.primary_text_disabled_material_dark));
}
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onBrowserSelected(browser);
}
});
}
// Return the size of the dataset (invoked by the layout manager)
@Override
public int getItemCount() {
if (mBrowsers != null)
return mBrowsers.length;
return 0;
}
}

View File

@ -0,0 +1,94 @@
package net.i2p.android.help;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import net.i2p.android.router.R;
import java.lang.reflect.Field;
public class BrowserConfigActivity extends ActionBarActivity implements
BrowserAdapter.OnBrowserSelectedListener {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
// Set the action bar
Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (findViewById(R.id.detail_fragment) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
}
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.main_fragment, new BrowserListFragment())
.commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// BrowserAdapter.OnBrowserSelected
@Override
public void onBrowserSelected(Browser browser) {
int file;
if (browser.isKnown) {
if (browser.isSupported) {
// Check for embedded browser
if (browser.packageName.startsWith("net.i2p.android"))
file = R.raw.help_embedded_browser;
else {
// Load the configuration guide for this browser
try {
String name = "help_" + browser.packageName.replace('.', '_');
Class res = R.raw.class;
Field field = res.getField(name);
file = field.getInt(null);
} catch (Exception e) {
file = R.raw.help_unknown_browser;
}
}
} else
file = R.raw.help_unsupported_browser;
} else
file = R.raw.help_unknown_browser;
HelpHtmlFragment configFrag = HelpHtmlFragment.newInstance(file);
if (mTwoPane) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.detail_fragment, configFrag)
.commit();
} else {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_fragment, configFrag)
.addToBackStack("config" + browser.packageName)
.commit();
}
}
}

View File

@ -0,0 +1,187 @@
package net.i2p.android.help;
import android.app.Activity;
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.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import net.i2p.android.router.R;
import net.i2p.android.router.util.BetterAsyncTaskLoader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BrowserListFragment extends Fragment implements
LoaderManager.LoaderCallbacks<List<Browser>> {
private static final int BROWSER_LOADER_ID = 1;
private BrowserAdapter.OnBrowserSelectedListener mCallback;
private BrowserAdapter mAdapter;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (BrowserAdapter.OnBrowserSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnBrowserSelectedListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_help_browsers, container, false);
RecyclerView mRecyclerView = (RecyclerView) v.findViewById(R.id.browser_list);
// use a linear layout manager
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new BrowserAdapter(getActivity(), mCallback);
mRecyclerView.setAdapter(mAdapter);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(BROWSER_LOADER_ID, null, this);
}
// LoaderManager.LoaderCallbacks<List<Browser>>
@Override
public Loader<List<Browser>> onCreateLoader(int id, Bundle args) {
return new BrowserLoader(getActivity());
}
public static class BrowserLoader extends BetterAsyncTaskLoader<List<Browser>> {
private List<String> recommended;
private List<String> recommendedLabels;
private List<String> supported;
private List<String> supportedLabels;
private List<String> unsupported;
public BrowserLoader(Context context) {
super(context);
recommended = Arrays.asList(
getContext().getResources().getStringArray(R.array.recommended_browsers));
recommendedLabels = Arrays.asList(
getContext().getResources().getStringArray(R.array.recommended_browser_labels));
supported = Arrays.asList(
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));
}
@Override
public List<Browser> loadInBackground() {
List<Browser> browsers = new ArrayList<Browser>();
Map<String, String> recommendedMap = new HashMap<String, String>();
for (int i = 0; i < recommended.size(); i++) {
recommendedMap.put(recommended.get(i), recommendedLabels.get(i));
}
Map<String, String> supportedMap = new HashMap<String, String>();
for (int i = 0; i < supported.size(); i++) {
supportedMap.put(supported.get(i), supportedLabels.get(i));
}
// 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 = getContext().getPackageManager();
List<ResolveInfo> installedBrowsers = pm.queryIntentActivities(intent, 0);
for (ResolveInfo browser : installedBrowsers) {
if (recommended.contains(browser.activityInfo.packageName)) {
browsers.add(new Browser(pm, browser, true, true));
recommendedMap.remove(browser.activityInfo.packageName);
} else if (supported.contains(browser.activityInfo.packageName) ||
browser.activityInfo.packageName.startsWith("net.i2p.android")) {
browsers.add(new Browser(pm, browser, true, false));
supportedMap.remove(browser.activityInfo.packageName);
} else if (unsupported.contains(browser.activityInfo.packageName))
browsers.add(new Browser(pm, browser, false, false));
else
browsers.add(new Browser(pm, browser));
}
// Now add the remaining recommended and supported browsers
for (Map.Entry<String, String> browser : recommendedMap.entrySet()) {
browsers.add(new Browser(browser.getKey(), browser.getValue(),
getDrawableForPackage(browser.getKey()),
false, true, true, true));
}
for (Map.Entry<String, String> browser : supportedMap.entrySet()) {
browsers.add(new Browser(browser.getKey(), browser.getValue(),
getDrawableForPackage(browser.getKey()),
false, true, true, false));
}
Collections.sort(browsers);
return browsers;
}
private Drawable getDrawableForPackage(String packageName) {
try {
String name = "icon_" + packageName.replace('.', '_');
Class res = R.drawable.class;
Field field = res.getField(name);
int drawable = field.getInt(null);
return getContext().getResources().getDrawable(drawable);
} catch (Exception e) {
return null;
}
}
@Override
protected void onStartMonitoring() {
}
@Override
protected void onStopMonitoring() {
}
@Override
protected void releaseResources(List<Browser> data) {
}
}
@Override
public void onLoadFinished(Loader<List<Browser>> listLoader, List<Browser> browsers) {
if (listLoader.getId() == BROWSER_LOADER_ID)
mAdapter.setBrowsers(browsers.toArray(new Browser[browsers.size()]));
}
@Override
public void onLoaderReset(Loader<List<Browser>> listLoader) {
if (listLoader.getId() == BROWSER_LOADER_ID)
mAdapter.clear();
}
}

View File

@ -2,27 +2,17 @@ package net.i2p.android.help;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ScrollView;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import net.i2p.android.router.LicenseActivity;
import net.i2p.android.router.R;
import net.i2p.android.router.dialog.TextResourceDialog;
import org.sufficientlysecure.htmltextview.HtmlTextView;
public class HelpActivity extends ActionBarActivity {
public class HelpActivity extends ActionBarActivity implements
HelpListFragment.OnEntrySelectedListener {
public static final String CATEGORY = "help_category";
public static final int CAT_MAIN = 0;
public static final int CAT_CONFIGURE_BROWSER = 1;
@ -40,30 +30,10 @@ public class HelpActivity extends ActionBarActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(this,
R.array.help_categories, android.R.layout.simple_spinner_dropdown_item);
ActionBar.OnNavigationListener navigationListener = new ActionBar.OnNavigationListener() {
@Override
public boolean onNavigationItemSelected(int i, long l) {
showCategory(i);
return true;
}
};
actionBar.setListNavigationCallbacks(spinnerAdapter, navigationListener);
if (savedInstanceState == null) {
int category = getIntent().getIntExtra(CATEGORY, CAT_MAIN);
// TODO remove when addressbook and I2PTunnel help added
if (category > CAT_CONFIGURE_BROWSER)
category = CAT_MAIN;
actionBar.setSelectedNavigationItem(category);
showCategory(category);
}
// Set the action bar
Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (findViewById(R.id.detail_fragment) != null) {
// The detail container view will be present only in the
@ -72,59 +42,16 @@ public class HelpActivity extends ActionBarActivity {
// activity should be in two-pane mode.
mTwoPane = true;
}
}
private void showCategory(int category) {
Fragment f;
switch (category) {
case CAT_CONFIGURE_BROWSER:
//f = new BrowserConfigFragment();
f = HelpHtmlFragment.newInstance(R.raw.help_configure_browser);
break;
case CAT_ADDRESSBOOK:
f = HelpHtmlFragment.newInstance(R.raw.help_addressbook);
break;
case CAT_I2PTUNNEL:
f = HelpHtmlFragment.newInstance(R.raw.help_i2ptunnel);
break;
case CAT_MAIN:
default:
f = HelpHtmlFragment.newInstance(R.raw.help_main);
break;
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.main_fragment, new HelpListFragment())
.commit();
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.main_fragment, f);
if (mTwoPane)
ft.remove(getSupportFragmentManager().findFragmentById(R.id.detail_fragment));
ft.commit();
}
public static class HelpHtmlFragment extends Fragment {
public static final String ARG_HTML_FILE = "htmlFile";
static HelpHtmlFragment newInstance(int htmlFile) {
HelpHtmlFragment f = new HelpHtmlFragment();
Bundle args = new Bundle();
args.putInt(ARG_HTML_FILE, htmlFile);
f.setArguments(args);
return f;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ScrollView scroller = new ScrollView(getActivity());
HtmlTextView text = new HtmlTextView(getActivity());
scroller.addView(text);
int padH = getResources().getDimensionPixelOffset(R.dimen.activity_horizontal_margin);
int padV = getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin);
text.setPadding(padH, padV, padH, padV);
text.setHtmlFromRawResource(getActivity(), getArguments().getInt(ARG_HTML_FILE), true);
return scroller;
}
int category = getIntent().getIntExtra(CATEGORY, -1);
if (category >= 0)
showCategory(category);
}
@Override
@ -136,21 +63,63 @@ public class HelpActivity extends ActionBarActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_help_licenses:
Intent lic = new Intent(HelpActivity.this, LicenseActivity.class);
startActivity(lic);
return true;
case R.id.menu_help_release_notes:
TextResourceDialog dialog = new TextResourceDialog();
Bundle args = new Bundle();
args.putString(TextResourceDialog.TEXT_DIALOG_TITLE,
getResources().getString(R.string.label_release_notes));
args.putInt(TextResourceDialog.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
dialog.setArguments(args);
dialog.show(getSupportFragmentManager(), "release_notes");
return true;
default:
return super.onOptionsItemSelected(item);
case android.R.id.home:
onBackPressed();
return true;
case R.id.menu_help_licenses:
Intent lic = new Intent(HelpActivity.this, LicenseActivity.class);
startActivity(lic);
return true;
case R.id.menu_help_release_notes:
TextResourceDialog dialog = new TextResourceDialog();
Bundle args = new Bundle();
args.putString(TextResourceDialog.TEXT_DIALOG_TITLE,
getResources().getString(R.string.label_release_notes));
args.putInt(TextResourceDialog.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
dialog.setArguments(args);
dialog.show(getSupportFragmentManager(), "release_notes");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// HelpListFragment.OnEntrySelectedListener
@Override
public void onEntrySelected(int entry) {
if (entry == CAT_CONFIGURE_BROWSER) {
Intent i = new Intent(this, BrowserConfigActivity.class);
startActivity(i);
} else
showCategory(entry);
}
private void showCategory(int category) {
int file;
switch (category) {
case CAT_ADDRESSBOOK:
file = R.raw.help_addressbook;
break;
case CAT_I2PTUNNEL:
file = R.raw.help_i2ptunnel;
break;
case CAT_MAIN:
default:
file = R.raw.help_main;
break;
}
HelpHtmlFragment f = HelpHtmlFragment.newInstance(file);
if (mTwoPane) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.detail_fragment, f).commit();
} else {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_fragment, f)
.addToBackStack("help" + category)
.commit();
}
}
}

View File

@ -0,0 +1,36 @@
package net.i2p.android.help;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import net.i2p.android.router.R;
import org.sufficientlysecure.htmltextview.HtmlTextView;
public class HelpHtmlFragment extends Fragment {
public static final String ARG_HTML_FILE = "htmlFile";
static HelpHtmlFragment newInstance(int htmlFile) {
HelpHtmlFragment f = new HelpHtmlFragment();
Bundle args = new Bundle();
args.putInt(ARG_HTML_FILE, htmlFile);
f.setArguments(args);
return f;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ScrollView scroller = new ScrollView(getActivity());
HtmlTextView text = new HtmlTextView(getActivity());
scroller.addView(text);
int padH = getResources().getDimensionPixelOffset(R.dimen.activity_horizontal_margin);
int padV = getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin);
text.setPadding(padH, padV, padH, padV);
text.setHtmlFromRawResource(getActivity(), getArguments().getInt(ARG_HTML_FILE), true);
return scroller;
}
}

View File

@ -0,0 +1,47 @@
package net.i2p.android.help;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import net.i2p.android.router.R;
public class HelpListFragment extends ListFragment {
OnEntrySelectedListener mEntrySelectedCallback;
// Container Activity must implement this interface
public interface OnEntrySelectedListener {
public void onEntrySelected(int entry);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mEntrySelectedCallback = (OnEntrySelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnEntrySelectedListener");
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(ArrayAdapter.createFromResource(getActivity(),
R.array.help_categories, R.layout.listitem_text));
}
@Override
public void onListItemClick(ListView parent, View view, int pos, long id) {
super.onListItemClick(parent, view, pos, id);
mEntrySelectedCallback.onEntrySelected(pos);
}
}

View File

@ -96,11 +96,14 @@ public class TunnelDetailFragment extends Fragment {
TextView description = (TextView) v.findViewById(R.id.tunnel_description);
description.setText(mTunnel.getDescription());
TextView details = (TextView) v.findViewById(R.id.tunnel_details);
details.setText(mTunnel.getDetails());
TextView targetIfacePort = (TextView) v.findViewById(R.id.tunnel_target_interface_port);
targetIfacePort.setText(mTunnel.getIfacePort());
targetIfacePort.setText(mTunnel.getTunnelLink(false));
TextView accessIfacePort = (TextView) v.findViewById(R.id.tunnel_access_interface_port);
accessIfacePort.setText(mTunnel.getIfacePort());
accessIfacePort.setText(mTunnel.getTunnelLink(false));
CheckBox autoStart = (CheckBox) v.findViewById(R.id.tunnel_autostart);
autoStart.setChecked(mTunnel.startAutomatically());

View File

@ -4,6 +4,7 @@ import java.util.List;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.widget.Toast;
import net.i2p.android.i2ptunnel.util.TunnelConfig;
import net.i2p.android.i2ptunnel.util.TunnelUtil;
@ -90,6 +91,16 @@ public class TunnelEntry {
else return NOT_RUNNING;
}
public boolean isRunning() {
switch (getStatus()) {
case STANDBY:
case RUNNING:
return true;
default:
return false;
}
}
public boolean isClient() {
return TunnelUtil.isClient(mController.getType());
}
@ -100,18 +111,42 @@ public class TunnelEntry {
return Boolean.parseBoolean(mController.getSharedClient());
}
/**
* Call this to see if it is okay to linkify getClientLink()
* @return true if getClientLink() can be linkified, false otherwise.
*/
public boolean isClientLinkValid() {
return ("ircclient".equals(mController.getType())) &&
mController.getListenOnInterface() != null &&
mController.getListenPort() != null;
}
/**
* @return valid host:port only if isClientLinkValid() is true
*/
public String getClientLink(boolean linkify) {
String host = getClientInterface();
String port = getClientPort();
String link = host + ":" + port;
if (linkify) {
if ("ircclient".equals(mController.getType()))
link = "irc://" + link;
}
return link;
}
public String getClientInterface() {
String rv;
if ("streamrclient".equals(mController.getType()))
return mController.getTargetHost();
rv = mController.getTargetHost();
else
return mController.getListenOnInterface();
rv = mController.getListenOnInterface();
return rv != null ? rv : "";
}
public String getClientPort() {
String rv = mController.getListenPort();
if (rv != null)
return rv;
return "";
return rv != null ? rv : "";
}
public String getClientDestination() {
@ -128,10 +163,10 @@ public class TunnelEntry {
/* Server tunnel data */
/**
* Call this to see if it is okay to linkify getServerTarget()
* @return true if getServerTarget() can be linkified, false otherwise.
* Call this to see if it is okay to linkify getServerLink()
* @return true if getServerLink() can be linkified, false otherwise.
*/
public boolean isServerTargetLinkValid() {
public boolean isServerLinkValid() {
return ("httpserver".equals(mController.getType()) ||
"httpbidirserver".equals(mController.getType())) &&
mController.getTargetHost() != null &&
@ -139,9 +174,9 @@ public class TunnelEntry {
}
/**
* @return valid host:port only if isServerTargetLinkValid() is true
* @return valid host:port only if isServerLinkValid() is true
*/
public String getServerTarget() {
public String getServerLink(boolean linkify) {
String host;
if ("streamrserver".equals(getInternalType()))
host = mController.getListenOnInterface();
@ -152,7 +187,13 @@ public class TunnelEntry {
if (port == null) port = "";
if (host.indexOf(':') >= 0)
host = '[' + host + ']';
return host + ":" + port;
String link = host + ":" + port;
if (linkify) {
if ("httpserver".equals(mController.getType()) ||
"httpbidirserver".equals(mController.getType()))
link = "http://" + link;
}
return link;
}
public String getDestinationBase64() {
@ -183,18 +224,25 @@ public class TunnelEntry {
/* Other output formats */
public String getIfacePort() {
if (isClient()) {
String host;
if ("streamrclient".equals(getInternalType()))
host = mController.getTargetHost();
else
host = mController.getListenOnInterface();
String port = mController.getListenPort();
if (host == null) host = "";
if (port == null) port = "";
return host + ":" + port;
} else return getServerTarget();
public boolean isTunnelLinkValid() {
if (isClient()) return isClientLinkValid();
else return isServerLinkValid();
}
public String getTunnelLink(boolean linkify) {
if (isClient()) return getClientLink(linkify);
else return getServerLink(linkify);
}
public Uri getRecommendedAppForTunnel() {
int resId = 0;
if ("ircclient".equals(mController.getType()))
resId = R.string.market_irc;
if (resId > 0)
return Uri.parse(mContext.getString(resId));
else
return null;
}
public String getDetails() {
@ -209,16 +257,29 @@ public class TunnelEntry {
public Drawable getStatusIcon() {
switch (getStatus()) {
case STANDBY:
return mContext.getResources()
.getDrawable(R.drawable.ic_schedule_black_24dp);
case STARTING:
return mContext.getResources()
.getDrawable(R.drawable.local_inprogress);
case RUNNING:
return mContext.getResources()
.getDrawable(R.drawable.local_up);
case NOT_RUNNING:
default:
return mContext.getResources()
.getDrawable(R.drawable.local_down);
return null;
}
}
public Drawable getStatusBackground() {
switch (getStatus()) {
case STANDBY:
case STARTING:
return mContext.getResources()
.getDrawable(R.drawable.tunnel_yellow);
case RUNNING:
return mContext.getResources()
.getDrawable(R.drawable.tunnel_green);
case NOT_RUNNING:
default:
return mContext.getResources()
.getDrawable(R.drawable.tunnel_red);
}
}
}

View File

@ -1,9 +1,12 @@
package net.i2p.android.i2ptunnel;
import java.util.List;
import net.i2p.android.router.R;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -11,6 +14,10 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import net.i2p.android.router.R;
import java.util.List;
public class TunnelEntryAdapter extends ArrayAdapter<TunnelEntry> {
private final LayoutInflater mInflater;
@ -31,22 +38,56 @@ public class TunnelEntryAdapter extends ArrayAdapter<TunnelEntry> {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = mInflater.inflate(R.layout.listitem_i2ptunnel, parent, false);
TunnelEntry tunnel = getItem(position);
final TunnelEntry tunnel = getItem(position);
ImageView status = (ImageView) v.findViewById(R.id.tunnel_status);
status.setImageDrawable(tunnel.getStatusIcon());
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
status.setBackgroundDrawable(tunnel.getStatusBackground());
else
status.setBackground(tunnel.getStatusBackground());
TextView name = (TextView) v.findViewById(R.id.tunnel_name);
name.setText(tunnel.getName());
TextView type = (TextView) v.findViewById(R.id.tunnel_type);
type.setText(tunnel.getType());
TextView type = (TextView) v.findViewById(R.id.tunnel_description);
type.setText(tunnel.getDescription());
TextView ifacePort = (TextView) v.findViewById(R.id.tunnel_interface_port);
ifacePort.setText(tunnel.getIfacePort());
ifacePort.setText(tunnel.getTunnelLink(false));
TextView details = (TextView) v.findViewById(R.id.tunnel_details);
details.setText(tunnel.getDetails());
ImageView status = (ImageView) v.findViewById(R.id.tunnel_status);
status.setImageDrawable(tunnel.getStatusIcon());
if (tunnel.isRunning() && tunnel.isTunnelLinkValid()) {
View open = v.findViewById(R.id.tunnel_open);
open.setVisibility(View.VISIBLE);
open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(tunnel.getTunnelLink(true)));
try {
getContext().startActivity(i);
} catch (ActivityNotFoundException e) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.install_recommended_app)
.setMessage(R.string.app_needed_for_this_tunnel_type)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
Uri uri = tunnel.getRecommendedAppForTunnel();
if (uri != null) {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
getContext().startActivity(intent);
}
}
})
.setNegativeButton(net.i2p.android.lib.client.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.show();
}
}
});
}
return v;
}

View File

@ -1,27 +1,32 @@
package net.i2p.android.i2ptunnel;
import java.util.List;
import net.i2p.android.help.HelpActivity;
import net.i2p.android.i2ptunnel.util.TunnelConfig;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.R;
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.router.RouterContext;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;
import net.i2p.android.help.HelpActivity;
import net.i2p.android.i2ptunnel.util.TunnelConfig;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
import net.i2p.android.router.R;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.router.RouterContext;
import java.util.List;
public class TunnelListFragment extends ListFragment implements
I2PFragmentBase.RouterContextUser,
LoaderManager.LoaderCallbacks<List<TunnelEntry>> {
@ -50,6 +55,8 @@ public class TunnelListFragment extends ListFragment implements
private int mActivatedPosition = ListView.INVALID_POSITION;
private boolean mActivateOnItemClick = false;
private ImageButton mNewTunnel;
// Container Activity must implement this interface
public interface OnTunnelSelectedListener {
public void onTunnelSelected(int tunnelId);
@ -85,6 +92,27 @@ public class TunnelListFragment extends ListFragment implements
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Create the list fragment's content view by calling the super method
final View listFragmentView = super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.fragment_list_with_add, container, false);
FrameLayout listContainer = (FrameLayout) v.findViewById(R.id.list_container);
listContainer.addView(listFragmentView);
mNewTunnel = (ImageButton) v.findViewById(R.id.promoted_action);
mNewTunnel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent wi = new Intent(getActivity(), TunnelWizardActivity.class);
startActivityForResult(wi, TUNNEL_WIZARD_REQUEST);
}
});
return v;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
@ -162,7 +190,7 @@ public class TunnelListFragment extends ListFragment implements
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_i2ptunnel_list_actions, menu);
if (getRouterContext() == null) {
menu.findItem(R.id.action_add_tunnel).setVisible(false);
mNewTunnel.setVisibility(View.GONE);
menu.findItem(R.id.action_start_all_tunnels).setVisible(false);
menu.findItem(R.id.action_stop_all_tunnels).setVisible(false);
menu.findItem(R.id.action_restart_all_tunnels).setVisible(false);
@ -174,26 +202,22 @@ public class TunnelListFragment extends ListFragment implements
// Handle presses on the action bar items
List<String> msgs;
switch (item.getItemId()) {
case R.id.action_add_tunnel:
Intent wi = new Intent(getActivity(), TunnelWizardActivity.class);
startActivityForResult(wi, TUNNEL_WIZARD_REQUEST);
return true;
case R.id.action_start_all_tunnels:
msgs = mGroup.startAllControllers();
break;
case R.id.action_stop_all_tunnels:
msgs = mGroup.stopAllControllers();
break;
case R.id.action_restart_all_tunnels:
msgs = mGroup.restartAllControllers();
break;
case R.id.action_i2ptunnel_help:
Intent hi = new Intent(getActivity(), HelpActivity.class);
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_I2PTUNNEL);
startActivity(hi);
return true;
default:
return super.onOptionsItemSelected(item);
case R.id.action_start_all_tunnels:
msgs = mGroup.startAllControllers();
break;
case R.id.action_stop_all_tunnels:
msgs = mGroup.stopAllControllers();
break;
case R.id.action_restart_all_tunnels:
msgs = mGroup.restartAllControllers();
break;
case R.id.action_i2ptunnel_help:
Intent hi = new Intent(getActivity(), HelpActivity.class);
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_I2PTUNNEL);
startActivity(hi);
return true;
default:
return super.onOptionsItemSelected(item);
}
// TODO: Do something with the other messages
if (msgs.size() > 0)
@ -251,7 +275,7 @@ public class TunnelListFragment extends ListFragment implements
}
public void onLoadFinished(Loader<List<TunnelEntry>> loader,
List<TunnelEntry> data) {
List<TunnelEntry> data) {
if (loader.getId() == (mClientTunnels ?
CLIENT_LOADER_ID : SERVER_LOADER_ID)) {
mAdapter.setData(data);

View File

@ -52,7 +52,6 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
/**
* Router variables
*/
protected String _myDir;
protected boolean _isBound;
protected boolean _triedBind;
protected ServiceConnection _connection;
@ -95,7 +94,6 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
Util.d(this + " onCreate called");
super.onCreate(savedInstanceState);
_sharedPrefs = getSharedPreferences(SHARED_PREFS, 0);
_myDir = getFilesDir().getAbsolutePath();
// If the Activity wants to use a ViewPager, provide it.
// If the Activity can make use of two panes (if available),
@ -174,8 +172,10 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
private void selectItem(int pos) {
switch (pos) {
case 1:
Intent news = new Intent(I2PActivityBase.this, NewsActivity.class);
startActivity(news);
if (!(this instanceof NewsActivity)) {
Intent news = new Intent(I2PActivityBase.this, NewsActivity.class);
startActivity(news);
}
break;
case 2:
Intent ab = new Intent(I2PActivityBase.this, AddressbookActivity.class);
@ -186,8 +186,10 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
startActivity(itb);
break;
case 4:
Intent log = new Intent(I2PActivityBase.this, LogActivity.class);
startActivity(log);
if (!(this instanceof LogActivity)) {
Intent log = new Intent(I2PActivityBase.this, LogActivity.class);
startActivity(log);
}
break;
case 5:
Intent wp = new Intent(I2PActivityBase.this, WebActivity.class);
@ -195,16 +197,20 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
startActivity(wp);
break;
case 6:
Intent active = new Intent(I2PActivityBase.this, RateGraphActivity.class);
startActivity(active);
if (!(this instanceof RateGraphActivity)) {
Intent active = new Intent(I2PActivityBase.this, RateGraphActivity.class);
startActivity(active);
}
break;
case 7:
Intent peers = new Intent(I2PActivityBase.this, PeersActivity.class);
startActivity(peers);
break;
case 8:
Intent netdb = new Intent(I2PActivityBase.this, NetDbActivity.class);
startActivity(netdb);
if (!(this instanceof NetDbActivity)) {
Intent netdb = new Intent(I2PActivityBase.this, NetDbActivity.class);
startActivity(netdb);
}
break;
default:
Intent main = new Intent(I2PActivityBase.this, MainActivity.class);
@ -318,8 +324,11 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
if (mDrawerToggle.onOptionsItemSelected(item))
return true;
else if (item.getItemId() == android.R.id.home) {
// This happens when mDrawerToggle.setDrawerIndicatorEnabled(false)
onBackPressed();
}
// Handle action buttons and overflow

View File

@ -0,0 +1,5 @@
package net.i2p.android.router;
public interface I2PConstants {
public static final String ANDROID_PREF_PREFIX = "i2pandroid.";
}

View File

@ -233,7 +233,7 @@ class InitActivities {
* @param overrides local overrides or null
*/
private void mergeResourceToFile(int resID, String f, Properties overrides) {
Util.mergeResourceToFile(ctx, myDir, f, resID, overrides);
Util.mergeResourceToFile(ctx, myDir, f, resID, overrides, null);
}
/**

View File

@ -1,23 +1,13 @@
package net.i2p.android.router;
import java.io.File;
import java.util.List;
import java.util.Properties;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.support.v4.app.DialogFragment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -31,8 +21,9 @@ import net.i2p.android.router.service.RouterService;
import net.i2p.android.router.service.State;
import net.i2p.android.router.util.Connectivity;
import net.i2p.android.router.util.Util;
import net.i2p.router.RouterContext;
import net.i2p.util.OrderedProperties;
import java.io.File;
import java.lang.ref.WeakReference;
public class MainActivity extends I2PActivityBase implements
MainFragment.RouterControlListener {
@ -144,7 +135,6 @@ public class MainActivity extends I2PActivityBase implements
case R.id.menu_help:
Intent hi = new Intent(MainActivity.this, HelpActivity.class);
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_MAIN);
startActivity(hi);
return true;
@ -245,24 +235,35 @@ public class MainActivity extends I2PActivityBase implements
private static final int STATE_MSG = 1;
private static final String MSG_DATA = "state";
private Handler mHandler = new Handler() {
private Handler mHandler = new StateHandler(new WeakReference<>(this));
private static class StateHandler extends Handler {
WeakReference<MainActivity> mReference;
public StateHandler(WeakReference<MainActivity> reference) {
mReference = reference;
}
private State lastRouterState = null;
@Override
public void handleMessage(Message msg) {
MainActivity parent = mReference.get();
if (parent == null)
return;
switch (msg.what) {
case STATE_MSG:
State state = msg.getData().getParcelable(MSG_DATA);
if (lastRouterState == null || lastRouterState != state) {
if (mMainFragment == null)
mMainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(R.id.main_fragment);
if (mMainFragment != null) {
mMainFragment.updateState(state);
if (parent.mMainFragment == null)
parent.mMainFragment = (MainFragment) parent.getSupportFragmentManager().findFragmentById(R.id.main_fragment);
if (parent.mMainFragment != null) {
parent.mMainFragment.updateState(state);
lastRouterState = state;
}
if (state == State.RUNNING && mAutoStartFromIntent) {
setResult(RESULT_OK);
finish();
if (state == State.RUNNING && parent.mAutoStartFromIntent) {
parent.setResult(RESULT_OK);
parent.finish();
}
}
break;
@ -270,7 +271,7 @@ public class MainActivity extends I2PActivityBase implements
super.handleMessage(msg);
}
}
};
}
private boolean canStart() {
RouterService svc = _routerService;
@ -300,7 +301,7 @@ public class MainActivity extends I2PActivityBase implements
setPref(PREF_AUTO_START, true);
svc.manualStart();
} else {
(new File(_myDir, "wrapper.log")).delete();
(new File(Util.getFileDir(this), "wrapper.log")).delete();
startRouter();
}
}

View File

@ -9,10 +9,15 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import net.i2p.I2PAppContext;
import net.i2p.android.router.service.StatSummarizer;
import net.i2p.android.router.util.IntEditTextPreference;
import net.i2p.android.router.util.Util;
import net.i2p.router.RouterContext;
import net.i2p.stat.FrequencyStat;
@ -24,6 +29,7 @@ import net.i2p.util.LogManager;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
public class SettingsActivity extends PreferenceActivity {
@ -33,6 +39,8 @@ public class SettingsActivity extends PreferenceActivity {
private static final String ACTION_PREFS_LOGGING = "net.i2p.android.router.PREFS_LOGGING";
private static final String ACTION_PREFS_ADVANCED = "net.i2p.android.router.PREFS_ADVANCED";
private Toolbar mToolbar;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -50,11 +58,14 @@ public class SettingsActivity extends PreferenceActivity {
setupLoggingSettings(this, getPreferenceScreen(), Util.getRouterContext());
} else if (ACTION_PREFS_ADVANCED.equals(action)) {
addPreferencesFromResource(R.xml.settings_advanced);
setupAdvancedSettings(this, getPreferenceScreen(), Util.getRouterContext());
}
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
// Load the legacy preferences headers
addPreferencesFromResource(R.xml.settings_headers_legacy);
}
mToolbar.setTitle(getTitle());
}
protected static void setupGraphSettings(Context context, PreferenceScreen ps, RouterContext ctx) {
@ -145,6 +156,24 @@ public class SettingsActivity extends PreferenceActivity {
}
}
protected static void setupAdvancedSettings(Context context, PreferenceScreen ps, RouterContext ctx) {
if (ctx != null) {
final String udpPortKey = context.getString(R.string.PROP_UDP_INTERNAL_PORT);
final String ntcpPortKey = context.getString(R.string.PROP_I2NP_NTCP_PORT);
IntEditTextPreference udpPort = (IntEditTextPreference) ps.findPreference(udpPortKey);
IntEditTextPreference ntcpPort = (IntEditTextPreference) ps.findPreference(ntcpPortKey);
String udpCurrentPort = ctx.getProperty(udpPortKey, "0");
udpPort.setText(udpCurrentPort);
String ntcpCurrentPort = ctx.getProperty(ntcpPortKey);
if (ntcpCurrentPort != null && ntcpCurrentPort.length() > 0)
ntcpPort.setText(ntcpCurrentPort);
else
ntcpPort.setText(udpCurrentPort);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onBuildHeaders(List<Header> target) {
@ -155,24 +184,48 @@ public class SettingsActivity extends PreferenceActivity {
loadHeadersFromResource(R.xml.settings_headers, target);
}
@Override
public void setContentView(int layoutResID) {
ViewGroup contentView = (ViewGroup) LayoutInflater.from(this).inflate(
R.layout.activity_settings,
(ViewGroup) getWindow().getDecorView().getRootView(), false);
mToolbar = (Toolbar) contentView.findViewById(R.id.main_toolbar);
mToolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp));
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
ViewGroup contentWrapper = (ViewGroup) contentView.findViewById(R.id.content_wrapper);
LayoutInflater.from(this).inflate(layoutResID, contentWrapper, true);
getWindow().setContentView(contentView);
}
@Override
protected void onPause() {
List<Properties> lProps = Util.getPropertiesFromPreferences(this);
Properties props = lProps.get(0);
Properties logSettings = lProps.get(1);
Properties propsToRemove = lProps.get(1);
Properties logSettings = lProps.get(2);
boolean restartRequired = Util.checkAndCorrectRouterConfig(this, props);
Set toRemove = propsToRemove.keySet();
boolean restartRequired = Util.checkAndCorrectRouterConfig(this, props, toRemove);
// Apply new config if we are running.
RouterContext rCtx = Util.getRouterContext();
if (rCtx != null) {
rCtx.router().saveConfig(props, null);
rCtx.router().saveConfig(props, toRemove);
// Merge in new log settings
saveLoggingChanges(rCtx, logSettings);
} else {
// Merge in new config settings, write the file.
Util.mergeResourceToFile(this, Util.getFileDir(this), "router.config", R.raw.router_config, props);
Util.mergeResourceToFile(this, Util.getFileDir(this), "router.config", R.raw.router_config, props, toRemove);
// Merge in new log settings
saveLoggingChanges(I2PAppContext.getGlobalContext(), logSettings);
@ -221,6 +274,7 @@ public class SettingsActivity extends PreferenceActivity {
setupLoggingSettings(getActivity(), getPreferenceScreen(), Util.getRouterContext());
} else if ("advanced".equals(settings)) {
addPreferencesFromResource(R.xml.settings_advanced);
setupAdvancedSettings(getActivity(), getPreferenceScreen(), Util.getRouterContext());
}
}
}

View File

@ -14,7 +14,7 @@ public class AddressEntryAdapter extends ArrayAdapter<AddressEntry> {
private final LayoutInflater mInflater;
public AddressEntryAdapter(Context context) {
super(context, R.layout.addressbook_list_item);
super(context, R.layout.listitem_text);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@ -29,7 +29,7 @@ public class AddressEntryAdapter extends ArrayAdapter<AddressEntry> {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = mInflater.inflate(R.layout.addressbook_list_item, parent, false);
View v = mInflater.inflate(R.layout.listitem_text, parent, false);
AddressEntry address = getItem(position);
TextView text = (TextView) v.findViewById(R.id.text);

View File

@ -1,38 +1,43 @@
package net.i2p.android.router.addressbook;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.util.NamingServiceUtil;
import net.i2p.android.router.util.Util;
import net.i2p.client.naming.NamingService;
import net.i2p.data.Destination;
import net.i2p.router.RouterContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import net.i2p.android.router.util.NamingServiceUtil;
import net.i2p.android.router.util.Util;
import net.i2p.client.naming.NamingService;
import net.i2p.data.Destination;
import net.i2p.router.RouterContext;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public class AddressEntryLoader extends AsyncTaskLoader<List<AddressEntry>> {
private RouterContext mRContext;
private I2PFragmentBase.RouterContextProvider mRContextProvider;
private String mBook;
private String mFilter;
private List<AddressEntry> mData;
public AddressEntryLoader(Context context, RouterContext rContext,
public AddressEntryLoader(Context context, I2PFragmentBase.RouterContextProvider rContextProvider,
String book, String filter) {
super(context);
mRContext = rContext;
mRContextProvider = rContextProvider;
mBook = book;
mFilter = filter;
}
@Override
public List<AddressEntry> loadInBackground() {
RouterContext routerContext = mRContextProvider.getRouterContext();
if (routerContext == null)
return null;
// get the names
NamingService ns = NamingServiceUtil.getNamingService(mRContext, mBook);
NamingService ns = NamingServiceUtil.getNamingService(routerContext, mBook);
Util.d("NamingService: " + ns.getName());
// After router shutdown we get nothing... why?
List<AddressEntry> ret = new ArrayList<AddressEntry>();

View File

@ -18,8 +18,6 @@ import android.widget.Spinner;
import net.i2p.android.router.I2PActivityBase;
import net.i2p.android.router.R;
import net.i2p.android.router.web.WebActivity;
import net.i2p.android.router.web.WebFragment;
public class AddressbookActivity extends I2PActivityBase
implements AddressbookFragment.OnAddressSelectedListener,
@ -37,7 +35,7 @@ public class AddressbookActivity extends I2PActivityBase
@Override
protected boolean canUseTwoPanes() {
return true;
return false;
}
@Override
@ -114,12 +112,8 @@ public class AddressbookActivity extends I2PActivityBase
setResult(Activity.RESULT_OK, result);
finish();
} else {
//Intent i = new Intent(Intent.ACTION_VIEW);
//i.setData(Uri.parse("http://" + host));
// XXX: Temporarily reverting to inbuilt browser
// until an alternative browser is ready.
Intent i = new Intent(this, WebActivity.class);
i.putExtra(WebFragment.HTML_URI, "http://" + host + '/');
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("http://" + host));
startActivity(i);
}
}

View File

@ -7,25 +7,29 @@ import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import net.i2p.addressbook.Daemon;
import net.i2p.android.help.HelpActivity;
import net.i2p.android.router.I2PFragmentBase;
import net.i2p.android.router.R;
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
import net.i2p.android.router.R;
import net.i2p.android.router.util.NamingServiceUtil;
import net.i2p.client.naming.NamingService;
import net.i2p.router.RouterContext;
import java.util.List;
public class AddressbookFragment extends ListFragment implements
I2PFragmentBase.RouterContextUser,
LoaderManager.LoaderCallbacks<List<AddressEntry>> {
@ -46,6 +50,8 @@ public class AddressbookFragment extends ListFragment implements
private String mBook;
private String mCurFilter;
private ImageButton mAddToAddressbook;
// Set in onActivityResult()
private Intent mAddWizardData;
@ -84,6 +90,27 @@ public class AddressbookFragment extends ListFragment implements
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Create the list fragment's content view by calling the super method
final View listFragmentView = super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.fragment_list_with_add, container, false);
FrameLayout listContainer = (FrameLayout) v.findViewById(R.id.list_container);
listContainer.addView(listFragmentView);
mAddToAddressbook = (ImageButton) v.findViewById(R.id.promoted_action);
mAddToAddressbook.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent wi = new Intent(getActivity(), AddressbookAddWizardActivity.class);
startActivityForResult(wi, ADD_WIZARD_REQUEST);
}
});
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@ -111,8 +138,8 @@ public class AddressbookFragment extends ListFragment implements
// Show actions
if (mSearchAddressbook != null)
mSearchAddressbook.setVisible(true);
if (mAddToAddressbook != null)
mAddToAddressbook.setVisible(false);
if (mAddToAddressbook != null && mAddToAddressbook.getVisibility() != View.VISIBLE)
mAddToAddressbook.setVisibility(View.VISIBLE);
if (mAddWizardData != null) {
// Save the new entry
@ -140,24 +167,26 @@ public class AddressbookFragment extends ListFragment implements
}
private MenuItem mSearchAddressbook;
private MenuItem mAddToAddressbook;
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_addressbook_actions, menu);
mSearchAddressbook = menu.findItem(R.id.action_search_addressbook);
mAddToAddressbook = menu.findItem(R.id.action_add_to_addressbook);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
// Hide until needed
if (getRouterContext() == null) {
mSearchAddressbook.setVisible(false);
mAddToAddressbook.setVisible(false);
if (mAddToAddressbook != null)
mAddToAddressbook.setVisibility(View.GONE);
}
// Only allow adding to private book
if (!PRIVATE_BOOK.equals(mBook)) {
mAddToAddressbook.setVisible(false);
if (!PRIVATE_BOOK.equals(mBook) && mAddToAddressbook != null) {
mAddToAddressbook.setVisibility(View.GONE);
mAddToAddressbook = null;
}
}
@ -167,26 +196,22 @@ public class AddressbookFragment extends ListFragment implements
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_add_to_addressbook:
Intent wi = new Intent(getActivity(), AddressbookAddWizardActivity.class);
startActivityForResult(wi, ADD_WIZARD_REQUEST);
return true;
case R.id.action_reload_subscriptions:
Daemon.wakeup();
Toast.makeText(getActivity(), "Reloading subscriptions...",
Toast.LENGTH_SHORT).show();
return true;
case R.id.action_addressbook_settings:
Intent si = new Intent(getActivity(), AddressbookSettingsActivity.class);
startActivity(si);
return true;
case R.id.action_addressbook_help:
Intent hi = new Intent(getActivity(), HelpActivity.class);
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_ADDRESSBOOK);
startActivity(hi);
return true;
default:
return super.onOptionsItemSelected(item);
case R.id.action_reload_subscriptions:
Daemon.wakeup();
Toast.makeText(getActivity(), "Reloading subscriptions...",
Toast.LENGTH_SHORT).show();
return true;
case R.id.action_addressbook_settings:
Intent si = new Intent(getActivity(), AddressbookSettingsActivity.class);
startActivity(si);
return true;
case R.id.action_addressbook_help:
Intent hi = new Intent(getActivity(), HelpActivity.class);
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_ADDRESSBOOK);
startActivity(hi);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@ -224,27 +249,32 @@ public class AddressbookFragment extends ListFragment implements
public Loader<List<AddressEntry>> onCreateLoader(int id, Bundle args) {
return new AddressEntryLoader(getActivity(),
getRouterContext(), mBook, mCurFilter);
mRouterContextProvider, mBook, mCurFilter);
}
public void onLoadFinished(Loader<List<AddressEntry>> loader,
List<AddressEntry> data) {
List<AddressEntry> data) {
if (loader.getId() == (PRIVATE_BOOK.equals(mBook) ?
PRIVATE_LOADER_ID : ROUTER_LOADER_ID)) {
mAdapter.setData(data);
if (data == null)
setEmptyText(getResources().getString(
R.string.router_not_running));
else {
mAdapter.setData(data);
TextView v = (TextView) getListView().findViewWithTag("addressbook_header");
if (mCurFilter != null)
v.setText(getActivity().getResources().getString(
R.string.addressbook_search_header,
data.size()));
else
v.setText("");
TextView v = (TextView) getListView().findViewWithTag("addressbook_header");
if (mCurFilter != null)
v.setText(getActivity().getResources().getString(
R.string.addressbook_search_header,
data.size()));
else
v.setText("");
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
}
}

View File

@ -1,20 +1,22 @@
package net.i2p.android.router.addressbook;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import net.i2p.android.router.R;
import net.i2p.util.FileUtil;
public class AddressbookSettingsActivity extends Activity {
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class AddressbookSettingsActivity extends ActionBarActivity {
private EditText text_content_subscriptions;
private Button btn_save_subscriptions;
@ -25,6 +27,12 @@ public class AddressbookSettingsActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addressbook_settings);
// Set the action bar
Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
text_content_subscriptions = (EditText) findViewById(R.id.subscriptions_content);
btn_save_subscriptions = (Button) findViewById(R.id.button_save_subscriptions);
init_actions();
@ -32,12 +40,6 @@ public class AddressbookSettingsActivity extends Activity {
load();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_addressbook_settings, menu);
return true;
}
private void init_actions() {
btn_save_subscriptions.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {

View File

@ -11,6 +11,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import net.i2p.android.help.BrowserConfigActivity;
import net.i2p.android.help.HelpActivity;
import net.i2p.android.router.R;
import net.i2p.android.router.util.I2Patterns;
@ -26,8 +27,7 @@ public class ConfigureBrowserDialog extends DialogFragment {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
Intent hi = new Intent(getActivity(), HelpActivity.class);
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_CONFIGURE_BROWSER);
Intent hi = new Intent(getActivity(), BrowserConfigActivity.class);
startActivity(hi);
}
})

View File

@ -37,7 +37,7 @@ public class NetDbStatsLoader extends AsyncTaskLoader<List<ObjectCounter<String>
ObjectCounter<String> countries = new ObjectCounter<String>();
ObjectCounter<String> transports = new ObjectCounter<String>();
if (mRContext.netDb().isInitialized()) {
if (mRContext != null && mRContext.netDb() != null && mRContext.netDb().isInitialized()) {
Hash us = mRContext.routerHash();
Set<RouterInfo> routers = new TreeSet<RouterInfo>(new RouterInfoComparator());

View File

@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.i2p.android.apps.EepGetFetcher;
import net.i2p.android.router.BuildConfig;
import net.i2p.android.router.util.AppCache;
import net.i2p.android.router.util.Util;
@ -45,7 +46,7 @@ public class CacheProvider extends ContentProvider {
//private static final String NONCE = Integer.toString(Math.abs((new java.util.Random()).nextInt()));
private static final String NONCE = "0";
private static final String SCHEME = "content";
public static final String AUTHORITY = "net.i2p.android";
public static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
/** includes the nonce */
public static final Uri CONTENT_URI = Uri.parse(SCHEME + "://" + AUTHORITY + '/' + NONCE);

View File

@ -0,0 +1,25 @@
package net.i2p.android.router.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import net.i2p.android.router.I2PConstants;
import net.i2p.android.router.service.RouterService;
public class OnBootReceiver extends BroadcastReceiver implements I2PConstants {
public static final String PREF_START_ON_BOOT = ANDROID_PREF_PREFIX + "startOnBoot";
@Override
public void onReceive(Context context, Intent intent) {
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);
}
}
}

View File

@ -0,0 +1,125 @@
package net.i2p.android.router.util;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public abstract class BetterAsyncTaskLoader<T> extends AsyncTaskLoader<T> {
protected T mData;
public BetterAsyncTaskLoader(Context context) {
super(context);
}
/**
* Called when there is new data to deliver to the client. The
* super class will take care of delivering it; the implementation
* here just adds a little more logic.
*/
@Override
public void deliverResult(T data) {
if (isReset()) {
// An async query came in while the loader is stopped. We
// don't need the result.
if (data != null) {
releaseResources(data);
}
}
// Hold a reference to the old data so it doesn't get garbage collected.
// We must protect it until the new data has been delivered.
T oldData = mData;
mData = data;
if (isStarted()) {
// If the Loader is currently started, we can immediately
// deliver its results.
super.deliverResult(data);
}
// Invalidate the old data as we don't need it any more.
if (oldData != null && oldData != data) {
releaseResources(oldData);
}
}
/**
* Handles a request to start the Loader.
*/
@Override
protected void onStartLoading() {
if (mData != null) {
// Deliver any previously loaded data immediately.
deliverResult(mData);
}
// Start watching for changes
onStartMonitoring();
if (takeContentChanged() || mData == null) {
// When the observer detects a change, it should call onContentChanged()
// on the Loader, which will cause the next call to takeContentChanged()
// to return true. If this is ever the case (or if the current data is
// null), we force a new load.
forceLoad();
}
}
/**
* Handles a request to stop the Loader.
*/
@Override
protected void onStopLoading() {
// The Loader is in a stopped state, so we should attempt to cancel the
// current load (if there is one).
cancelLoad();
// Note that we leave the observer as is. Loaders in a stopped state
// should still monitor the data source for changes so that the Loader
// will know to force a new load if it is ever started again.
}
/**
* Handles a request to completely reset the Loader.
*/
@Override
protected void onReset() {
super.onReset();
// Ensure the loader has been stopped.
onStopLoading();
// At this point we can release the resources associated with 'mData'.
if (mData != null) {
releaseResources(mData);
mData = null;
}
// Stop monitoring for changes.
onStopMonitoring();
}
/**
* Handles a request to cancel a load.
*/
@Override
public void onCanceled(T data) {
// Attempt to cancel the current asynchronous load.
super.onCanceled(data);
// The load has been canceled, so we should release the resources
// associated with 'data'.
releaseResources(data);
}
protected abstract void onStartMonitoring();
protected abstract void onStopMonitoring();
/**
* Helper function to take care of releasing resources associated
* with an actively loaded data set.
* For a simple List, there is nothing to do. For something like a Cursor, we
* would close it in this method. All resources associated with the Loader
* should be released here.
*/
protected abstract void releaseResources(T data);
}

View File

@ -0,0 +1,39 @@
package net.i2p.android.router.util;
import android.content.Context;
import android.preference.EditTextPreference;
import android.text.InputType;
import android.util.AttributeSet;
public class IntEditTextPreference extends EditTextPreference {
public IntEditTextPreference(Context context) {
super(context);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
}
public IntEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
}
public IntEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
}
@Override
public CharSequence getSummary() {
return String.format((String) super.getSummary(), getText());
}
@Override
protected String getPersistedString(String defaultReturnValue) {
return String.valueOf(getPersistedInt(-1));
}
@Override
protected boolean persistString(String value) {
return persistInt(Integer.valueOf(value));
}
}

View File

@ -0,0 +1,60 @@
package net.i2p.android.router.util;
import android.content.Context;
import android.preference.EditTextPreference;
import android.text.InputType;
import android.util.AttributeSet;
import net.i2p.android.router.R;
public class PortPreference extends EditTextPreference {
public PortPreference(Context context) {
super(context);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
}
public PortPreference(Context context, AttributeSet attrs) {
super(context, attrs);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
}
public PortPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getEditText().setInputType(InputType.TYPE_CLASS_NUMBER);
}
@Override
public CharSequence getSummary() {
int port = getPersistedInt(-1);
if (port < 0)
return getContext().getResources().getString(R.string.unset);
else
return String.valueOf(port);
}
@Override
protected String getPersistedString(String defaultReturnValue) {
int port = getPersistedInt(-1);
if (port < 0)
return defaultReturnValue;
else
return String.valueOf(port);
}
@Override
protected boolean persistString(String value) {
if (value == null || value.isEmpty())
return persistInt(-1);
int port;
try {
port = Integer.valueOf(value);
if (port < 0)
port = -1;
} catch (NumberFormatException e) {
port = -1;
}
return persistInt(port);
}
}

View File

@ -8,10 +8,12 @@ import android.content.res.Resources;
import android.preference.PreferenceManager;
import net.i2p.I2PAppContext;
import net.i2p.android.router.I2PConstants;
import net.i2p.data.DataHelper;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.transport.TransportManager;
import net.i2p.router.transport.udp.UDPTransport;
import net.i2p.util.OrderedProperties;
import java.io.File;
@ -19,13 +21,14 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public abstract class Util {
public abstract class Util implements I2PConstants {
public static String getOurVersion(Context ctx) {
PackageManager pm = ctx.getPackageManager();
String us = ctx.getPackageName();
@ -123,29 +126,33 @@ public abstract class Util {
}
}
/** copied from various private components */
final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoport";
public static List<Properties> getPropertiesFromPreferences(Context context) {
List<Properties> pList = new ArrayList<Properties>();
// Copy prefs
Properties routerProps = new OrderedProperties();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
// List to store stats for graphing
List<String> statSummaries = new ArrayList<String>();
// Properties to remove
Properties toRemove = new OrderedProperties();
// List to store Log settings
Properties logSettings = new OrderedProperties();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Map<String, ?> all = preferences.getAll();
Iterator<String> iterator = all.keySet().iterator();
// get values from the Map and make them strings.
// This loop avoids needing to convert each one, or even know it's type, or if it exists yet.
while (iterator.hasNext()) {
String x = iterator.next();
if ( x.startsWith("i2pandroid.")) // Skip over UI-related I2P Android settings
continue;
else if ( x.startsWith("stat.summaries.")) {
if ( x.startsWith("stat.summaries.")) {
String stat = x.substring("stat.summaries.".length());
String checked = all.get(x).toString();
if (checked.equals("true")) {
@ -160,7 +167,7 @@ public abstract class Util {
String string = all.get(x).toString();
String inverted = Boolean.toString(!Boolean.parseBoolean(string));
routerProps.setProperty(x, inverted);
} else {
} else if ( !x.startsWith(ANDROID_PREF_PREFIX)) { // Skip over UI-related I2P Android settings
String string = all.get(x).toString();
routerProps.setProperty(x, string);
}
@ -176,7 +183,22 @@ public abstract class Util {
routerProps.setProperty("stat.summaries", buf.toString());
}
// See net.i2p.router.web.ConfigNetHandler.saveChanges()
int udpPort = Integer.parseInt(routerProps.getProperty(UDPTransport.PROP_INTERNAL_PORT, "-1"));
System.out.println("UDP port: " + udpPort);
if (udpPort <= 0)
routerProps.remove(UDPTransport.PROP_INTERNAL_PORT);
int ntcpPort = Integer.parseInt(routerProps.getProperty(PROP_I2NP_NTCP_PORT, "-1"));
System.out.println("NTCP port: " + ntcpPort);
boolean ntcpAutoPort = Boolean.parseBoolean(
routerProps.getProperty(PROP_I2NP_NTCP_AUTO_PORT, "true"));
if (ntcpPort <= 0 || ntcpAutoPort) {
routerProps.remove(PROP_I2NP_NTCP_PORT);
toRemove.setProperty(PROP_I2NP_NTCP_PORT, "");
}
pList.add(routerProps);
pList.add(toRemove);
pList.add(logSettings);
return pList;
@ -192,8 +214,12 @@ public abstract class Util {
boolToAdd.put(TransportManager.PROP_ENABLE_UPNP, true);
boolToAdd.put(TransportManager.PROP_ENABLE_NTCP, true);
boolToAdd.put(TransportManager.PROP_ENABLE_UDP, true);
boolToAdd.put(PROP_I2NP_NTCP_AUTO_PORT, true);
boolToAdd.put(Router.PROP_HIDDEN, false);
strToAdd.put(UDPTransport.PROP_INTERNAL_PORT, "-1");
strToAdd.put(PROP_I2NP_NTCP_PORT, "-1");
booleanOptionsRequiringRestart.putAll(boolToAdd);
stringOptionsRequiringRestart.putAll(strToAdd);
}
@ -209,9 +235,10 @@ public abstract class Util {
* </li></ul>
*
* @param props a Properties object containing the router.config
* @param toRemove a Collection of properties that will be removed
* @return true if the router needs to be restarted.
*/
public static boolean checkAndCorrectRouterConfig(Context context, Properties props) {
public static boolean checkAndCorrectRouterConfig(Context context, Properties props, Collection<String> toRemove) {
// Disable UPnP on mobile networks, ignoring user's configuration
// TODO disabled until changes elsewhere are finished
//if (Connectivity.isConnectedMobile(context)) {
@ -225,17 +252,17 @@ public abstract class Util {
for (Map.Entry<String, Boolean> option : booleanOptionsRequiringRestart.entrySet()) {
String propName = option.getKey();
boolean defaultValue = option.getValue();
restartRequired |= (
Boolean.parseBoolean(props.getProperty(propName, Boolean.toString(defaultValue))) !=
(defaultValue ? rCtx.getBooleanPropertyDefaultTrue(propName) : rCtx.getBooleanProperty(propName))
);
boolean currentValue = defaultValue ? rCtx.getBooleanPropertyDefaultTrue(propName) : rCtx.getBooleanProperty(propName);
boolean newValue = Boolean.parseBoolean(props.getProperty(propName, Boolean.toString(defaultValue)));
restartRequired |= (currentValue != newValue);
}
if (!restartRequired) { // Cut out now if we already know the answer
for (Map.Entry<String, String> option : stringOptionsRequiringRestart.entrySet()) {
String propName = option.getKey();
String defaultValue = option.getValue();
restartRequired |= props.getProperty(propName, defaultValue).equals(
rCtx.getProperty(propName, defaultValue));
String currentValue = rCtx.getProperty(propName, defaultValue);
String newValue = props.getProperty(propName, defaultValue);
restartRequired |= !currentValue.equals(newValue);
}
}
}
@ -256,7 +283,7 @@ public abstract class Util {
* @param props properties to set
*/
public static void writePropertiesToFile(Context ctx, String dir, String file, Properties props) {
mergeResourceToFile(ctx, dir, file, 0, props);
mergeResourceToFile(ctx, dir, file, 0, props, null);
}
/**
@ -267,8 +294,10 @@ public abstract class Util {
* @param file relative to dir
* @param resID the ID of the default resource, or 0
* @param userProps local properties or null
* @param toRemove properties to remove, or null
*/
public static void mergeResourceToFile(Context ctx, String dir, String file, int resID, Properties userProps) {
public static void mergeResourceToFile(Context ctx, String dir, String file, int resID,
Properties userProps, Collection<String> toRemove) {
InputStream fin = null;
InputStream in = null;
@ -297,6 +326,11 @@ public abstract class Util {
// override with user settings
if (userProps != null)
props.putAll(userProps);
if (toRemove != null) {
for (String key : toRemove) {
props.remove(key);
}
}
File path = new File(dir, file);
DataHelper.storeProps(props, path);

View File

@ -194,8 +194,7 @@ public class I2PWebViewClient extends WebViewClient {
/**
* This should always be a content url
*/
void deleteCurrentPageCache(WebView view) {
String url = view.getUrl();
void deleteCurrentPageCache(WebView view, String url) {
Uri uri = Uri.parse(url);
if (CONTENT.equals(uri.getScheme())) {
try {

View File

@ -22,6 +22,7 @@ import net.i2p.android.router.R;
public class WebFragment extends I2PFragmentBase {
private I2PWebViewClient _wvClient;
private String _uriStr;
public final static String HTML_URI = "html_url";
public final static String HTML_RESOURCE_ID = "html_resource_id";
@ -48,9 +49,9 @@ 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);
String uriStr = getArguments().getString(HTML_URI);
if (uriStr != null) {
Uri uri = Uri.parse(uriStr);
_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
@ -115,14 +116,18 @@ public class WebFragment extends I2PFragmentBase {
_wvClient.cancelAll();
wv.stopLoading();
String url = wv.getUrl();
Uri uri = Uri.parse(url);
// If a resource, _uriStr == null but url != null (resource loads don't fail)
// If a URL, _uriStr != null and url might be null (if pageload failed)
if (url != null && (!url.equals(_uriStr)))
_uriStr = url;
Uri uri = Uri.parse(_uriStr);
if ("data".equals(uri.getScheme())) {
// welcome page... or just do nothing ?
wv.reload();
} else {
// wv.reload() doesn't call shouldOverrideUrlLoading(), so do it this way
_wvClient.deleteCurrentPageCache(wv);
_wvClient.shouldOverrideUrlLoading(wv, url);
_wvClient.deleteCurrentPageCache(wv, _uriStr);
_wvClient.shouldOverrideUrlLoading(wv, _uriStr);
}
return true;

View File

@ -16,7 +16,11 @@ import java.util.Queue;
* @author zzz
*/
class LogWriter implements Runnable {
/** every 10 seconds? why? Just have the gui force a reread after a change?? */
private final static long CONFIG_READ_ITERVAL = 10 * 1000;
final static long FLUSH_INTERVAL = 29 * 1000;
private final static long MIN_FLUSH_INTERVAL = 2*1000;
private final static long MAX_FLUSH_INTERVAL = 5*60*1000;
private long _lastReadConfig = 0;
private long _numBytesInCurrentFile = 0;
private OutputStream _currentOut; // = System.out
@ -26,6 +30,8 @@ class LogWriter implements Runnable {
private LogManager _manager;
private boolean _write;
// ms
private volatile long _flushInterval = FLUSH_INTERVAL;
private LogWriter() { // nop
}
@ -38,6 +44,14 @@ class LogWriter implements Runnable {
_write = false;
}
/**
* @param interval in ms
* @since 0.9.18
*/
public void setFlushInterval(long interval) {
_flushInterval = Math.min(MAX_FLUSH_INTERVAL, Math.max(MIN_FLUSH_INTERVAL, interval));
}
public void run() {
_write = true;
try {
@ -77,7 +91,7 @@ class LogWriter implements Runnable {
if (shouldWait) {
try {
synchronized (this) {
this.wait(10*1000);
this.wait(_flushInterval);
}
} catch (InterruptedException ie) { // nop
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,48 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:padding="10px"
android:scrollbarStyle="outsideInset"
>
<LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Addressbook Settings"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:fillViewport="true"
android:scrollbarStyle="outsideInset">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Subscriptions"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/subscriptions_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textMultiLine"
android:maxLines="@integer/min_lines"
android:minLines="@integer/min_lines" >
<requestFocus />
</EditText>
<Button
android:id="@+id/button_save_subscriptions"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save subscriptions.txt" />
android:orientation="vertical">
</LinearLayout>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Subscriptions"
android:textAppearance="?android:attr/textAppearanceMedium" />
</ScrollView>
<EditText
android:id="@+id/subscriptions_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textMultiLine">
<requestFocus />
</EditText>
<Button
android:id="@+id/button_save_subscriptions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save subscriptions.txt" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
</android.support.v7.widget.Toolbar>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
</android.support.v7.widget.Toolbar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal">
<!--
This layout is a two-pane layout for the master/detail
flow within a DrawerLayout. See res/values-large/refs.xml
and res/values-sw600dp/refs.xml for layout aliases
that replace the single-pane version of the layout with
this two-pane version.
-->
<!-- The main fragment view -->
<FrameLayout
android:id="@+id/main_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<!-- The detail fragment view -->
<FrameLayout
android:id="@+id/detail_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
<FrameLayout
android:id="@+id/content_wrapper"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="6dp"
android:textSize="16sp" >
</TextView>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/browser_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/list_vertical_padding"
android:paddingTop="@dimen/list_vertical_padding"
android:scrollbars="vertical" />

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
android:layout_height="match_parent">
<TextView
android:id="@+id/tunnel_name"
@ -17,16 +17,24 @@
android:id="@+id/tunnel_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/tunnel_type"
android:layout_alignParentLeft="true"
android:layout_below="@+id/tunnel_name"
android:text="Tunnel description" />
<TextView
android:id="@+id/tunnel_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/tunnel_description"
android:text="Tunnel details" />
<TextView
android:id="@+id/tunnel_target_interface_port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/tunnel_description"
android:layout_below="@+id/tunnel_type"
android:gravity="right"
android:text="Interface:port" />
@ -35,23 +43,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/tunnel_name"
android:layout_below="@+id/tunnel_details"
android:text="@string/i2ptunnel_view_type" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView2"
android:text="@string/i2ptunnel_view_desc" />
<TextView
android:id="@+id/tunnel_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/tunnel_name"
android:layout_below="@+id/tunnel_details"
android:text="Tunnel type" />
<TextView
@ -59,7 +59,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:layout_below="@+id/textView2"
android:text="@string/i2ptunnel_view_target" />
<TextView

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<net.i2p.android.ext.floatingactionbutton.AddFloatingActionButton
android:id="@+id/promoted_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="@dimen/listitem_horizontal_margin"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
app:fab_colorNormal="@color/accent"
app:fab_colorPressed="@color/accent_dark" />
</RelativeLayout>

View File

@ -2,21 +2,26 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/news_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_above="@+id/news_status"/>
android:layout_above="@+id/news_status"
android:layout_alignParentTop="true" />
<TextView
android:id="@+id/news_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:layout_alignParentBottom="true"
android:gravity="end"
android:visibility="gone" />
</RelativeLayout>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/listitem_height_one_line_avatar"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin">
<ImageView
android:id="@+id/browser_icon"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:scaleType="fitCenter" />
<TextView
android:id="@+id/browser_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/listitem_text_left_margin"
android:layout_marginStart="@dimen/listitem_text_left_margin"
android:layout_toLeftOf="@+id/browser_status_icon"
android:layout_toStartOf="@+id/browser_status_icon"
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
<ImageView
android:id="@+id/browser_status_icon"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/listitem_icon_left_margin"
android:layout_marginStart="@dimen/listitem_icon_left_margin"
android:scaleType="center"
android:visibility="gone" />
</RelativeLayout>

View File

@ -1,49 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp" >
android:layout_width="match_parent"
android:layout_height="@dimen/listitem_height_two_lines"
android:paddingEnd="@dimen/listitem_horizontal_margin"
android:paddingRight="@dimen/listitem_horizontal_margin">
<!-- The name of the tunnel -->
<TextView android:id="@+id/tunnel_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:textSize="16sp"
<!-- Tunnel status -->
<ImageView
android:id="@+id/tunnel_status"
android:layout_width="@dimen/listitem_icon_size"
android:layout_height="@dimen/listitem_icon_size"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dp"
android:text="Tunnel name" />
<!-- The type of tunnel -->
<TextView android:id="@+id/tunnel_type"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tunnel_name"
android:text="Tunnel type" />
<!-- Additional tunnel details -->
<TextView android:id="@+id/tunnel_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tunnel_type"
android:text="Tunnel details" />
<!-- Interface:port the tunnel listens on or points to -->
<TextView android:id="@+id/tunnel_interface_port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tunnel_name"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/tunnel_name"
android:gravity="right"
android:text="Interface:port" />
<!-- Status star -->
<ImageView android:id="@+id/tunnel_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:contentDescription="Status" />
<!-- The name of the tunnel -->
<TextView
android:id="@+id/tunnel_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="@dimen/listitem_text_left_margin"
android:layout_marginStart="@dimen/listitem_text_left_margin"
android:layout_marginTop="@dimen/listitem_text_top_margin_two_lines"
android:text="Tunnel name"
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
<!-- Open link -->
<ImageView
android:id="@+id/tunnel_open"
android:layout_width="@dimen/listitem_icon_size"
android:layout_height="@dimen/listitem_icon_size"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:contentDescription="Open"
android:src="@drawable/ic_open_in_browser_white_24dp"
android:visibility="gone" />
<!-- Interface:port the tunnel listens on or points to -->
<TextView
android:id="@+id/tunnel_interface_port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@id/tunnel_name"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_toEndOf="@id/tunnel_name"
android:layout_toLeftOf="@id/tunnel_open"
android:layout_toRightOf="@id/tunnel_name"
android:layout_toStartOf="@id/tunnel_open"
android:ellipsize="start"
android:gravity="right"
android:maxLines="1"
android:text="Interface:port"
android:textAppearance="@style/TextAppearance.AppCompat.Secondary" />
<!-- The tunnel description -->
<TextView
android:id="@+id/tunnel_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tunnel_name"
android:layout_alignParentBottom="true"
android:layout_alignStart="@+id/tunnel_name"
android:layout_marginBottom="@dimen/listitem_text_bottom_margin_two_lines"
android:layout_toLeftOf="@id/tunnel_open"
android:layout_toStartOf="@id/tunnel_open"
android:ellipsize="end"
android:maxLines="1"
android:text="Tunnel description"
android:textAppearance="@style/TextAppearance.AppCompat.Secondary" />
</RelativeLayout>

View File

@ -1,24 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp" >
android:layout_width="match_parent"
android:layout_height="@dimen/listitem_height_two_lines"
android:paddingEnd="@dimen/listitem_horizontal_margin"
android:paddingRight="@dimen/listitem_horizontal_margin">
<!-- The nickname of the LeaseSet -->
<TextView android:id="@+id/ls_nickname"
<TextView
android:id="@+id/ls_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:textSize="16sp"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dp"
android:text="LeaseSet nickname" />
android:layout_alignParentStart="true"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/listitem_text_top_margin_two_lines"
android:text="LeaseSet nickname"
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
<!-- The hash of the LeaseSet -->
<TextView android:id="@+id/dbentry_hash"
<TextView
android:id="@+id/dbentry_hash"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ls_nickname"
android:text="LeaseSet hash" />
android:layout_alignLeft="@+id/ls_nickname"
android:layout_alignParentBottom="true"
android:layout_alignStart="@+id/ls_nickname"
android:layout_marginBottom="@dimen/listitem_text_bottom_margin_two_lines"
android:ellipsize="end"
android:maxLines="1"
android:text="LeaseSet hash"
android:textAppearance="@style/TextAppearance.AppCompat.Secondary" />
</RelativeLayout>

View File

@ -1,25 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp" >
<!-- The hash of the RouterInfo -->
<TextView android:id="@+id/dbentry_hash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp"
android:textSize="16sp"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dp"
android:text="RouterInfo hash" />
android:layout_width="match_parent"
android:layout_height="@dimen/listitem_height_one_line"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin">
<!-- Country flag -->
<ImageView android:id="@+id/ri_country"
<ImageView
android:id="@+id/ri_country"
android:layout_width="@dimen/listitem_icon_size"
android:layout_height="@dimen/listitem_icon_size"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:contentDescription="Country"
android:visibility="gone" />
<!-- The hash of the RouterInfo -->
<TextView
android:id="@+id/dbentry_hash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:contentDescription="Country" />
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:ellipsize="marquee"
android:maxLines="1"
android:text="RouterInfo hash"
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
</RelativeLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="@dimen/listitem_height_one_line"
android:gravity="center_vertical"
android:paddingEnd="@dimen/listitem_horizontal_margin"
android:paddingLeft="@dimen/listitem_horizontal_margin"
android:paddingRight="@dimen/listitem_horizontal_margin"
android:paddingStart="@dimen/listitem_horizontal_margin"
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />

View File

@ -1,5 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_settings"
android:title="@string/menu_settings"
android:orderInCategory="100" />
</menu>

View File

@ -1,11 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:i2pandroid="http://schemas.android.com/apk/res-auto" >
<!-- Add, should appear as action buttons -->
<item android:id="@+id/action_add_to_addressbook"
android:title="@string/action_add"
android:icon="@drawable/ic_add_white_24dp"
i2pandroid:showAsAction="ifRoom" />
<!-- Settings, Help, should always be in the overflow -->
<item android:id="@+id/action_reload_subscriptions"
android:title="@string/action_reload_subscriptions"

View File

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:i2pandroid="http://schemas.android.com/apk/res-auto" >
<item android:id="@+id/action_add_tunnel"
android:title="@string/action_add"
android:icon="@drawable/ic_add_white_24dp"
i2pandroid:showAsAction="ifRoom" />
<item android:id="@+id/action_start_all_tunnels"
android:title="@string/action_i2ptunnel_start_all"
i2pandroid:showAsAction="never" />

View File

@ -1,12 +1,8 @@
<html>
<head></head>
<body>
<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 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>
<h2>Embedded web browser</h2>
<p>An embedded web browser is provided for convenience that will open .i2p addresses. However, it is not recommended for general use; users should download the Orweb browser, or Firefox Mobile and the ProxyMob Firefox plugin.</p>
<p>An embedded web browser is provided for convenience that will open .i2p addresses. However, it is not recommended for general use.</p>
<p>The browser does not use the outproxy for regular web sites. Javascript is disabled.</p>
<p>The following problems with eepsites are probably not fixable except on Android 3.0 (Honeycomb - i.e. tablets) and higher due to API limitations. The workaround is to use Firefox Mobile 4 and the ProxMob plugin (see below).</p>

View File

@ -1,6 +1,15 @@
<html>
<head></head>
<body>
<h2>What is I2PTunnel?</h2>
<p>Tunnels are the heart of I2P. All data inside the I2P network is sent through tunnels that hide the location of users. If an app has native I2P support, it will create its own tunnels.</p>
<p>I2PTunnel lets you create your own tunnels manually. This is useful for when you want to use an app that doesn't have native I2P support, like:</p>
<ul>
<li>A browser.</li>
<li>An IRC client.</li>
<li>A web server.</li>
</ul>
<h2>Using clients with pre-configured tunnels</h2>
<p>The app starts an HTTP proxy 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>
@ -8,9 +17,10 @@
<ol>
<li>Port 6668: IRC2P - irc.postman.i2p, irc.freshcoffee.i2p, and irc.echelon.i2p</li>
<li>Port 6669: irc.welterde.i2p</li>
<li>Port 6670: irc.telecomix.i2p (probably down)</li>
<li>Port 6671: irc.killyourtv.i2p</li>
<li>Port 6672: Nameless IRC - irc.stream.i2p</li>
<li>Port 6670: irc.killyourtv.i2p</li>
</ol>
<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>
</body>
</html>

View File

@ -0,0 +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>
</body>
</html>

View File

@ -0,0 +1,16 @@
<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.
</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>You can now browse I2P eepsites!</li>
</ol>
</body>
</html>

View File

@ -7,5 +7,10 @@
<h2>How do I use it?</h2>
<p>If you want to view I2P sites, see the "Browser configuration" help category.</p>
<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 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>

View File

@ -0,0 +1,16 @@
<html>
<head></head>
<body>
<h2>How to configure Firefox:</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.
</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>You can now browse I2P eepsites!</li>
</ol>
</body>
</html>

View File

@ -0,0 +1,9 @@
<html>
<head></head>
<body>
<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 proxy setting to use <code>localhost:4444</code>.</p>
</body>
</html>

View File

@ -0,0 +1,7 @@
<html>
<head></head>
<body>
<h2>Sorry, this browser is unsupported</h2>
<p>This browser can't be used with I2P.</p>
</body>
</html>

View File

@ -27,7 +27,7 @@ tunnel.0.startOnLoad=true
# irc
tunnel.1.name=Irc2P
tunnel.1.description=IRC tunnel to access the Irc2P network
tunnel.1.description=IRC tunnel to the Irc2P network
tunnel.1.type=ircclient
tunnel.1.sharedClient=true
tunnel.1.interface=127.0.0.1
@ -50,14 +50,14 @@ tunnel.1.option.outbound.lengthVariance=0
tunnel.1.option.outbound.priority=15
tunnel.1.startOnLoad=true
# irc
tunnel.2.name=IRC welterde
tunnel.2.description=IRC tunnel to access welterde's network
tunnel.2.type=ircclient
# postman's SMTP server - see hq.postman.i2p
tunnel.2.name=smtp.postman.i2p
tunnel.2.description=smtp server
tunnel.2.type=client
tunnel.2.sharedClient=true
tunnel.2.interface=127.0.0.1
tunnel.2.listenPort=6669
tunnel.2.targetDestination=irc.welterde.i2p
tunnel.2.listenPort=7659
tunnel.2.targetDestination=smtp.postman.i2p:25
tunnel.2.i2cpHost=127.0.0.1
tunnel.2.i2cpPort=7654
tunnel.2.option.inbound.nickname=shared clients
@ -67,20 +67,22 @@ tunnel.2.option.i2cp.reduceIdleTime=600000
tunnel.2.option.i2cp.reduceOnIdle=true
tunnel.2.option.i2cp.reduceQuantity=1
tunnel.2.option.i2p.streaming.connectDelay=1000
tunnel.2.option.i2p.streaming.maxWindowSize=16
tunnel.2.option.inbound.length=2
tunnel.2.option.inbound.lengthVariance=0
tunnel.2.option.outbound.length=2
tunnel.2.option.outbound.lengthVariance=0
tunnel.2.option.outbound.priority=15
tunnel.2.startOnLoad=true
# irc
tunnel.3.name=Telecomix IRC
tunnel.3.description=IRC tunnel to access the Telecomix network
tunnel.3.type=ircclient
# postman's POP3 server - see hq.postman.i2p
tunnel.3.name=pop3.postman.i2p
tunnel.3.description=pop3 server
tunnel.3.type=client
tunnel.3.sharedClient=true
tunnel.3.interface=127.0.0.1
tunnel.3.listenPort=6670
tunnel.3.targetDestination=irc.telecomix.i2p
tunnel.3.listenPort=7660
tunnel.3.targetDestination=pop.postman.i2p:110
tunnel.3.i2cpHost=127.0.0.1
tunnel.3.i2cpPort=7654
tunnel.3.option.inbound.nickname=shared clients
@ -90,20 +92,22 @@ tunnel.3.option.i2cp.reduceIdleTime=600000
tunnel.3.option.i2cp.reduceOnIdle=true
tunnel.3.option.i2cp.reduceQuantity=1
tunnel.3.option.i2p.streaming.connectDelay=1000
tunnel.3.option.i2p.streaming.maxWindowSize=16
tunnel.3.option.inbound.length=2
tunnel.3.option.inbound.lengthVariance=0
tunnel.3.option.outbound.length=2
tunnel.3.option.outbound.lengthVariance=0
tunnel.3.option.outbound.priority=15
tunnel.3.startOnLoad=true
# irc irc.killyourtv.i2p
tunnel.4.name=KYTV IRC
tunnel.4.description=IRC tunnel to access KillYourTV's network
# 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=6671
tunnel.4.targetDestination=irc.killyourtv.i2p
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
@ -113,20 +117,22 @@ 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
# irc irc.stream.i2p
tunnel.5.name=Nameless IRC
tunnel.5.description=IRC tunnel to access the Nameless network
# irc irc.killyourtv.i2p
tunnel.5.name=KYTV IRC
tunnel.5.description=IRC tunnel to KillYourTV's network
tunnel.5.type=ircclient
tunnel.5.sharedClient=true
tunnel.5.interface=127.0.0.1
tunnel.5.listenPort=6672
tunnel.5.targetDestination=irc.stream.i2p
tunnel.5.listenPort=6670
tunnel.5.targetDestination=irc.killyourtv.i2p
tunnel.5.i2cpHost=127.0.0.1
tunnel.5.i2cpPort=7654
tunnel.5.option.inbound.nickname=shared clients
@ -136,8 +142,10 @@ tunnel.5.option.i2cp.reduceIdleTime=600000
tunnel.5.option.i2cp.reduceOnIdle=true
tunnel.5.option.i2cp.reduceQuantity=1
tunnel.5.option.i2p.streaming.connectDelay=1000
tunnel.5.option.i2p.streaming.maxWindowSize=16
tunnel.5.option.inbound.length=2
tunnel.5.option.inbound.lengthVariance=0
tunnel.5.option.outbound.length=2
tunnel.5.option.outbound.lengthVariance=0
tunnel.5.startOnLoad=true
tunnel.5.option.outbound.priority=15
tunnel.5.startOnLoad=true

View File

@ -1,2 +1 @@
irc.welterde.i2p=qv0mnQG0CqKM0b4613~8rOKBLA9ZQLCdU0Iiz6Ou8eszJjvjNCHTaa-Rcorz50~7zMu8Lh~OYplf2JatBhWirTsmbVRlOxtAvqYl0oAfY1bUpUu9AeU9wfgj806jw0vIO6JNDpSiRRhGL6HHYLqDvqvE4JgFFpMjF30dIdBxCGsVa1EbwlUUCpgZV1Psl45l~1wkMJ7NsSglHy46l5m9uYXNxu-NERrMN0~mGxnFsAllJZZCKixFQY-mDDiEMksCF7aNueTm~SknvrVQIue9jVf5lZVvxPSmKuRIEGL3bAC-IF3Jhv0NEhuxAYpzKBT1yMupJficIHhcqwk-iUHNnUqgEH8MRQM4SrrcGeBvwZ-daQVOv~ujLijiFl4QrrNLzArgYOxRZMO1Jz3kAgWxULw3RNiszmIcuxYvGT4z7e5YeuroejyE1ExMis-3JBmbjrd2kOKWX5LqgMeAkDjYIsI8QPigxLbC3l7Y5tbyrZA0t~vvOU--2wP6Kg5rb7r1AAAA
irc.telecomix.i2p=ogLZQpnNgs514P0hp-vwPU3iHhKUymyotVxyX7fC8-a4dFAUXx~HUR0ezvkb3RVI3Snvh~yl7QJHzs3hIy2jjZmo~rlZLmtpEVgu1IvrMYusR3KQZ-1Tdfr3JftxA~dr3vmmro3hIhR18xRWA87A~y2VyEGGw4how-EEYS~VT6hnxoJ4FQztvQF0in2A70fCQ1obVYD3lBL~Jn9VV-~tgjohOZHSkIA4yCD80~QfhHa0g4GqJRgQry5fEjAvc1h5owsNyQ8siU3NfldvTd4Tj~dRuD3F91Svk6Wepp~IbPyIKgWPDGWW3RQWFoyDyHjwLI8IdPg0Io8Q4oRgTcA4JJaaHop2WzV7E-thM41h8evo~jO-XDzfW0DFtFTRRK7use5cYLbNlRXVlHQCe7qHALYi3JkH6wBsW5o8irHFMiGYe-YmGEwVRRQ0p2j-tRVJC4jYEOTSTO2Fr~hAUxramtah9wKOd05bSIOYxQxb0~0fGsw3gDMBCZW8PrhFUn3LAAAA

View File

@ -2,8 +2,8 @@
<resources>
<string name="app_name">I2P</string>
<string name="desc_i2p_logo">I2P-Logo</string>
<string name="welcome_new_install">Willkommen bei I2P! Diese App ist Alpha-Software und bietet keine starke Anonymität. Bitte lies die Veröffentlichungshinweise und die Lizenzeninformationen.</string>
<string name="welcome_new_version">Eine neue Version wurde installiert. Bitte lies die Veröffentlichungshinweise. Version:</string>
<string name="welcome_new_install">Willkommen bei I2P! Diese App ist Alpha-Software und bietet keine starke Anonymität. Bitte lesen Sie die Veröffentlichungshinweise und die Lizenzinformationen.</string>
<string name="welcome_new_version">Eine neue Version wurde installiert. Bitte lesen Sie die Veröffentlichungshinweise. Version:</string>
<string name="label_home">Einstellungen und Status</string>
<string name="label_tunnels">Tunnel</string>
<string name="label_status">Status</string>
@ -12,14 +12,14 @@
<string name="label_i2ptunnel_client">Kliententunnel</string>
<string name="label_i2ptunnel_server">Servertunnel</string>
<string name="label_logs">Statusberichte</string>
<string name="label_error_logs">Fehler-Protokolle</string>
<string name="label_error_logs">Fehlerprotokolle</string>
<string name="label_info_and_pages">Informationen und Seiten</string>
<string name="label_welcome_page">Begrüßungsseite</string>
<string name="label_news">Neuigkeiten</string>
<string name="label_peers_status">Teilnehmer</string>
<string name="label_release_notes">Veröffentlichungshinweise</string>
<string name="label_licenses">Lizenzen</string>
<string name="label_nonanon_info">Nichtanonyme Informationen</string>
<string name="label_nonanon_info">Nicht-anonyme Informationen</string>
<string name="label_browse">Surfen</string>
<string name="label_graphs">Graphen</string>
<string name="button_router_off">Lange drücken, um I2P zu starten</string>
@ -30,13 +30,13 @@
<string name="char_server_tunnel">S</string>
<string name="no_client_tunnels_running">Keine Kliententunnel laufen noch.</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 Menu erledigen).</string>
<string name="first_start_title">Herzlichen Glückwunsch, du hast I2P installiert!</string>
<string name="first_start_welcome"><b>Willkommen im I2P</b> Bitte <b>hab Geduld</b>, während I2P startet und Teilnehmer findet.</string>
<string name="first_start_read">Während du wartest, lies bitte die Veröffentlichungshinweise und die Startseite.</string>
<string name="first_start_faq">Sobald du Kliententunnels hast, <b>lies</b> bitte unsere FAQs:</string>
<string name="first_start_faq_nonanon">Oder benutze unsere nicht-anonymen Links, wenn du nicht auf die Tunnel warten willst.</string>
<string name="first_start_irc">Verbinde dich mit deinem IRC-Klienten zu <b>localhost:6668</b> und schau bei uns vorbei:</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="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="drawer_open">Navigation öffnen</string>
<string name="drawer_close">Navigation schließen</string>
<string name="action_search">Suche</string>
@ -45,22 +45,22 @@
<string name="action_delete">Löschen</string>
<string name="action_router_start">Router starten</string>
<string name="action_router_stop">Router stoppen</string>
<string name="action_i2ptunnel_start">Starte den Tunnel</string>
<string name="action_i2ptunnel_stop">Stoppe den Tunnel</string>
<string name="action_i2ptunnel_start">Tunnel starten</string>
<string name="action_i2ptunnel_stop">Tunnel stoppen</string>
<string name="action_i2ptunnel_start_all">Alle Tunnel starten</string>
<string name="action_i2ptunnel_stop_all">Alle Tunnel anhalten</string>
<string name="action_i2ptunnel_restart_all">Alle Tunnel neu starten</string>
<string name="action_reload">Neu laden</string>
<string name="action_refresh">Auffrischen</string>
<string name="hint_search_addressbook">Durchsuche das Adressbuch</string>
<string name="hint_search_addressbook">Adressbuch durchsuchen</string>
<string name="action_reload_subscriptions">Abonnements neu laden</string>
<string name="router_not_running">Der Router läuft nicht.</string>
<string name="stats_not_ready">Der Statistikmanager ist noch nicht bereit. Versuch es später erneut.</string>
<string name="stats_not_ready">Der Statistikmanager ist noch nicht bereit. Versuchen Sie es später noch einmal.</string>
<string name="no_graphs_configured">Keine Graphen konfiguriert. Sie können die Statistiken zum Erstellen der Graphen im Einstellungsmenu auswählen. Jede Änderung wird nach 60 Sekunden aktiv gesetzt.</string>
<string name="configure_graphs">Graphen konfigurieren</string>
<string name="graphs_not_ready">Die Graphen sind noch nicht bereit oder der Router läuft nicht. Probiere es später nochmal.</string>
<string name="netdb_routers_empty">Keine Router in deiner NetDB.</string>
<string name="netdb_leases_empty">Keine LeaseSets in deiner NetDB</string>
<string name="graphs_not_ready">Die Graphen sind noch nicht bereit oder der Router läuft nicht. Versuchen Sie es später noch einmal.</string>
<string name="netdb_routers_empty">Keine Router in Ihrer NetDB.</string>
<string name="netdb_leases_empty">Keine LeaseSets in Ihrer NetDB.</string>
<string name="notification_status_bw">Bandbreite: %1$s KB/s eingehend / %2$s KB/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>
@ -70,10 +70,10 @@
<string name="settings_desc_subscriptions">Abonnements-URLs</string>
<string name="settings_label_bandwidth_net">Bandbreite und Netzwerk</string>
<string name="settings_label_bandwidth">Bandbreite</string>
<string name="settings_label_bw_inbound">maximal eingehend</string>
<string name="settings_desc_bw_inbound">maximal ausgehend</string>
<string name="settings_label_bw_outbound">ausgehende Übertragungsgeschwindigkeit</string>
<string name="settings_desc_bw_outbound">maximale ausgehende Übertragungsgeschwindigkeit</string>
<string name="settings_label_bw_inbound">Eingehende Übertragungsgeschwindigkeit</string>
<string name="settings_desc_bw_inbound">Maximale eingehende Übertragungsgeschwindigkeit</string>
<string name="settings_label_bw_outbound">Ausgehende Übertragungsgeschwindigkeit</string>
<string name="settings_desc_bw_outbound">Maximale ausgehende Übertragungsgeschwindigkeit</string>
<string name="settings_label_network">Netzwerk</string>
<string name="settings_label_hiddenMode">Beteiligung</string>
<string name="settings_desc_hiddenMode">Tarnmodus ausschalten</string>
@ -88,11 +88,11 @@
<string name="settings_label_default_log_level">Standard-Detailtiefe der Statusberichte</string>
<string name="settings_label_advanced">Erweitert</string>
<string name="settings_label_showStats">Routerstatistiken</string>
<string name="settings_summ_showStats">Zeige ausführliche Statistiken in der Hauptkonsole.</string>
<string name="settings_summ_showStats">Ausführliche Statistiken in der Hauptkonsole anzeigen.</string>
<string name="settings_label_transports">Transporte</string>
<string name="settings_label_maxConns">max. Verbindungen</string>
<string name="settings_label_maxConns">Max. Verbindungen</string>
<string name="settings_label_i2cp">I2CP-Benutzeroberfläche</string>
<string name="settings_desc_i2cp">lausche auf Port 7654</string>
<string name="settings_desc_i2cp">Auf Port 7654 lauschen</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>
@ -115,14 +115,15 @@
<string name="about_project">Projektseite:</string>
<string name="about_bugs">Fehlermeldungen und Unterstützung:</string>
<string name="about_helpwanted">Unterstützer gesucht!!</string>
<string name="about_volunteer">Du willst mithelfen, die App besser zu machen? Dann schau in das Android forum:</string>
<string name="about_donate">Wenn du Geld oder Bitcoins spenden wilst, damit wir mehr Android-Geräte zum Testen kaufen können, dann schau auf:</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="addressbook_search_header">%s gefunden</string>
<string name="addressbook_add_wizard_k_name">Name</string>
<string name="addressbook_add_wizard_k_destination">Ziel</string>
<string name="addressbook_add_wizard_desc_name">Der Name</string>
<string name="addressbook_add_wizard_desc_destination">Kopiere den B64-Code des Ziels hier her. Falls du einen Dateimanager installiert hast, kannst du die Textdatei auswählen, welche den B64-Code enthält.</string>
<string name="addressbook_add_wizard_desc_destination">Kopieren Sie den B64-Code des Ziels hier her. Falls Sie einen Dateimanager installiert haben, können Sie die Textdatei auswählen, welche den B64-Code enthält.</string>
<string name="nsu_iae_illegal_char">Hostname \"%1$s\" beinhaltet ein unzulässiges Zeichen %2$s</string>
<string name="nsu_iae_cannot_start_with">Hostnamen dürfen nicht mit \"%s\" beginnen</string>
<string name="nsu_iae_cannot_end_with">Hostnamen dürfen nicht auf \"%s\" enden</string>
@ -140,12 +141,14 @@
<string name="i2ptunnel_type_streamrclient">Streamr-Klient</string>
<string name="i2ptunnel_type_streamrserver">Streamr-Server</string>
<string name="i2ptunnel_type_httpbidirserver">HTTP bidirektional</string>
<string name="i2ptunnel_not_initialized">Tunnel sind noch nicht initialisiert. Bitte lade die Seite in zwei Minuten erneut.</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="i2ptunnel_new_tunnel">Neuer Tunnel</string>
<string name="i2ptunnel_msg_config_saved">Änderungen gespeichert</string>
<string name="i2ptunnel_msg_config_save_failed">Speichern der Änderungen fehlgeschlagen</string>
<string name="i2ptunnel_msg_tunnel_starting">Starte den Tunnel</string>
<string name="i2ptunnel_msg_tunnel_stopping">Stoppe den Tunnel</string>
<string name="i2ptunnel_msg_tunnel_starting">Tunnel wird gestartet</string>
<string name="i2ptunnel_msg_tunnel_stopping">Tunnel wird gestoppt</string>
<string name="i2ptunnel_delete_confirm_message">Tunnel löschen?</string>
<string name="i2ptunnel_delete_confirm_button">Tunnel löschen</string>
<string name="i2ptunnel_wizard_k_client_server">Klient oder Server</string>
@ -158,19 +161,19 @@
<string name="i2ptunnel_wizard_k_outproxies">Outproxys</string>
<string name="i2ptunnel_wizard_k_target_host">Zielhost</string>
<string name="i2ptunnel_wizard_k_target_port">Zielport</string>
<string name="i2ptunnel_wizard_k_reachable_on">erreichbar unter</string>
<string name="i2ptunnel_wizard_k_binding_port">zu benutzender Port</string>
<string name="i2ptunnel_wizard_k_reachable_on">Erreichbar unter</string>
<string name="i2ptunnel_wizard_k_binding_port">Zu benutzender Port</string>
<string name="i2ptunnel_wizard_k_auto_start">Autostart</string>
<string name="next">Nächste</string>
<string name="prev">Vorherige</string>
<string name="finish">Absenden</string>
<string name="review">Überprüfen</string>
<string name="enabled">Aktiviert</string>
<string name="i2ptunnel_wizard_desc_name">Der Name des Tunnels - zur Unterscheidung in der Tunnelliste.</string>
<string name="i2ptunnel_wizard_desc_desc">Eine optionale aber für dich aussagekräftige Beschreibung des Tunnels.</string>
<string name="i2ptunnel_wizard_desc_dest">Bitte gib hier das I2P-Ziel des Dienstes ein, zu dem dieser Tunnel führen soll. Dies kann im Basis64-Format (langer Schlüssel) geschehen, oder eine I2P URL aus dem Adressbuch sein.</string>
<string name="i2ptunnel_wizard_desc_outproxies">Falls du Outproxys für diese Tunnel-Art kennst (HTTP oder SOCKS), gib sie hier kommagetrennt ein.</string>
<string name="i2ptunnel_wizard_desc_target_host">Das ist die IP unter der der Dienst erreichbar ist - meistens die 127.0.0.1</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">Bitte geben Sie hier das I2P-Ziel des Dienstes ein, zu dem dieser Tunnel führen soll. Dies kann ein voller Basis64-Zielschlüssel oder eine I2P URL aus dem Adressbuch sein.</string>
<string name="i2ptunnel_wizard_desc_outproxies">Falls Sie Outproxys 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>

View File

@ -69,6 +69,8 @@
<string name="settings_enable">Activar</string>
<string name="settings_desc_subscriptions">URLs de subscripción</string>
<string name="settings_label_bandwidth_net">Ancho de banda y red</string>
<string name="settings_label_startOnBoot">Iniciar I2P al arrancar</string>
<string name="settings_desc_startOnBoot">Conectar automáticamente a I2P cuando arranque su dispositivo Android</string>
<string name="settings_label_bandwidth">Ancho de banda</string>
<string name="settings_label_bw_inbound">Velocidad de descarga</string>
<string name="settings_desc_bw_inbound">Velocidad máxima de descarga</string>
@ -118,6 +120,7 @@
<string name="about_volunteer">¿Quiere ayudar a hacer mejor la aplicación? Haga de 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 testeo? Vaya a:</string>
<string name="menu_help">Ayuda</string>
<string name="general">General</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</string>
@ -140,6 +143,8 @@
<string name="i2ptunnel_type_streamrclient">Cliente Streamr</string>
<string name="i2ptunnel_type_streamrserver">Servidor Streamr</string>
<string name="i2ptunnel_type_httpbidirserver">HTTP bidireccional</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 no están inicializados aún, por favor vuelva a cargar en dos minutos.</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>
@ -188,4 +193,5 @@
<string name="error_logs_copied_to_clipboard">Los registros (logs) de errores se copiaron al portapapeles</string>
<string name="logs_copied_to_clipboard">Los registros (logs) se copiaron al portapapeles</string>
<string name="label_browser_configuration">Configuración del navegador</string>
<string name="unset">No configurado</string>
</resources>

View File

@ -0,0 +1,121 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="app_name">I2P</string>
<string name="desc_i2p_logo">I2P-logo</string>
<string name="welcome_new_install">Tervetuloa I2P-sovellukseen! Täsmä sovellus on ALFA-ohjelmisto ja se ei tarjoa vahvaa nimettömyyttä. Lue julkaisutiedot ja linsessitiedot.</string>
<string name="welcome_new_version">Uusi versio asennettu. Lue julkaisutiedot. Versio:</string>
<string name="label_tunnels">Tunnelit</string>
<string name="label_status">Tila</string>
<string name="label_addressbook">Osoitekirja</string>
<string name="label_i2ptunnel">I2PTunnel</string>
<string name="label_i2ptunnel_client">Asiakastunnelit</string>
<string name="label_i2ptunnel_server">Palvelintunnelit</string>
<string name="label_logs">Lokitiedostot</string>
<string name="label_error_logs">Virhelokitiedostot</string>
<string name="label_info_and_pages">Tietoja ja sivut</string>
<string name="label_welcome_page">Tervetuloa-sivu</string>
<string name="label_news">Uutiset</string>
<string name="label_release_notes">Julkaisutiedot</string>
<string name="label_licenses">Lisenssit</string>
<string name="label_nonanon_info">Ei-anonyymit tiedot</string>
<string name="label_browse">Selaa</string>
<string name="label_graphs">Kuvaajat</string>
<string name="button_router_off">Pitkä painallus käynnistää I2P-sovelluksen</string>
<string name="button_router_on">I2P on käynnissä (paina pitkään pysäyttääksesi)</string>
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
<string name="char_client_tunnel">A</string>
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
<string name="char_server_tunnel">P</string>
<string name="no_client_tunnels_running">Yhtään asiakastunneli ei ole vielä käynnissä.</string>
<string name="configure_browser_title">Asetetaanko selain?</string>
<string name="configure_browser_for_i2p">Haluaisitko asettaa selaimesi katsomaan I2P-sivustoja? (Voit myös tehdä tämän myöhemmin opaste-valikosta).</string>
<string name="first_start_title">Onnittelut I2P:n asentamisesta!</string>
<string name="first_start_welcome"><b>Tervetuloa I2P-sovellukseen!</b> <b>Ole kärsivällinen</b> kun I2P käynnistyy ja löytää vertaisverkkovastaanottajia.</string>
<string name="first_start_read">Odottaessa lue julkaisutiedot ja tervetuloa-sivu.</string>
<string name="first_start_faq">Kun asiakastunnelit ovat valmiit, <b>tarkista</b> UKK-kysymykset:</string>
<string name="first_start_faq_nonanon">Tai käytä ei-anonyymeja linkkejä, jos et halua odottaa tunneleita:</string>
<string name="action_search">Haku</string>
<string name="action_add">Lisää</string>
<string name="action_edit">Muokkaa</string>
<string name="action_delete">Poista</string>
<string name="action_router_start">Käynnistä reititin</string>
<string name="action_router_stop">Pysäytä reititin</string>
<string name="action_i2ptunnel_start">Käynnistä tunneli</string>
<string name="action_i2ptunnel_stop">Pysäytä tunneli</string>
<string name="action_i2ptunnel_start_all">Käynnistä kaikki tunnelit</string>
<string name="action_i2ptunnel_stop_all">Pysäytä kaikki tunnelit</string>
<string name="action_i2ptunnel_restart_all">Käynnistä kaikki tunnelit uudelleen</string>
<string name="action_reload">Lataa uudelleen</string>
<string name="action_refresh">Virkistä</string>
<string name="hint_search_addressbook">Etsi osoitekirja</string>
<string name="router_not_running">Reititin ei ole käynnissä.</string>
<string name="notification_status_bw">Kaistanleveys: %1$s kilotavua/s alaspäin / %2$s kilotavua/s ylöspäin</string>
<string name="notification_status_peers">Vertaisverkkovastaanottajaa: %1$d aktiivista, %2$d tunnettua</string>
<string name="notification_status_client">Asiakastunnelit: %1$d/%2$d</string>
<string name="menu_settings">Asetukset</string>
<string name="settings_enable">Ota käyttöön</string>
<string name="settings_label_bandwidth_net">Kaistanleveys ja verkko</string>
<string name="settings_label_bandwidth">Kaistanleveys</string>
<string name="settings_label_bw_inbound">Tulonopeus</string>
<string name="settings_desc_bw_inbound">Enimmäistulonopeus</string>
<string name="settings_label_bw_outbound">Lähtönopeus</string>
<string name="settings_desc_bw_outbound">Enimmäislähtönopeus</string>
<string name="settings_label_network">Verkko</string>
<string name="settings_desc_hiddenMode">Käännä piilotila pois päältä</string>
<string name="settings_label_showStats">Reititintilastot</string>
<string name="settings_label_maxConns">Yhteyksien enimmäismäärä</string>
<string name="settings_label_i2cp">I2CP-käyttöliittymä</string>
<string name="settings_desc_i2cp">Kuuntele portissa 7654</string>
<string name="settings_desc_exploratory_pool">Tunneliparametrit</string>
<string name="settings_label_expl_inbound">Tulotunnelit</string>
<string name="settings_label_expl_outbound">Lähtötunnelit</string>
<string name="settings_label_expl_length">Pituus</string>
<string name="settings_summ_expl_lengthVariance">%s</string>
<string name="settings_summ_expl_quantity">%s tunnelia</string>
<string name="settings_desc_expl_quantity">Kuinka monta tunnelia</string>
<string name="settings_summ_expl_backupQuantity">%s tunnelia</string>
<string name="menu_about">Ohjelmasta</string>
<string name="about_version">Versio:</string>
<string name="about_project">Hankekoti:</string>
<string name="about_helpwanted">Etsitään apua!</string>
<string name="menu_help">Opaste</string>
<string name="general">Yleistä</string>
<string name="addressbook_add_wizard_k_name">Nimi</string>
<string name="addressbook_add_wizard_k_destination">Kohde</string>
<string name="addressbook_add_wizard_desc_name">Nimi</string>
<string name="i2ptunnel_type_httpclient">HTTP-asiakas</string>
<string name="i2ptunnel_type_ircclient">IRC-asiakas</string>
<string name="i2ptunnel_type_server">Vakiopalvelin</string>
<string name="i2ptunnel_type_httpserver">HTTP-palvelin</string>
<string name="i2ptunnel_type_ircserver">IRC-palvelin</string>
<string name="i2ptunnel_new_tunnel">Uusi tunneli</string>
<string name="i2ptunnel_msg_tunnel_starting">Käynnistetään tunneli</string>
<string name="i2ptunnel_msg_tunnel_stopping">Pysäytetään tunneli</string>
<string name="i2ptunnel_delete_confirm_message">Poistetaanko tunneli?</string>
<string name="i2ptunnel_delete_confirm_button">Poista tunneli</string>
<string name="i2ptunnel_wizard_k_client_server">Asiakas tai palvelin</string>
<string name="i2ptunnel_wizard_v_client">Asiakastunneli</string>
<string name="i2ptunnel_wizard_v_server">Palvelintunneli</string>
<string name="i2ptunnel_wizard_k_type">Tunnelityyppi</string>
<string name="i2ptunnel_wizard_k_name">Nimi</string>
<string name="i2ptunnel_wizard_k_desc">Kuvaus</string>
<string name="i2ptunnel_wizard_k_dest">Kohde</string>
<string name="i2ptunnel_wizard_k_target_host">Kohdetietokone</string>
<string name="i2ptunnel_wizard_k_target_port">Kohdeportti</string>
<string name="next">Seuraava</string>
<string name="prev">Edellinen</string>
<string name="finish">Lähetä</string>
<string name="review">Katselmoi</string>
<string name="enabled">Otettu käyttöön</string>
<string name="i2ptunnel_wizard_submit_confirm_message">Luodaanko tunneli?</string>
<string name="i2ptunnel_wizard_submit_confirm_button">Luo tunneli</string>
<string name="i2ptunnel_view_type">Tyyppi:</string>
<string name="i2ptunnel_view_desc">Kuvaus:</string>
<string name="i2ptunnel_view_target">Kohde:</string>
<string name="copy_logs">Kopioi lokitiedostot</string>
<string name="i2p_android_error_logs">I2P Android-virhelokitiedostot</string>
<string name="i2p_android_logs">I2P Android-lokitiedostot</string>
<string name="error_logs_copied_to_clipboard">Virhelokitiedostot kopoitu leikepöydälle</string>
<string name="logs_copied_to_clipboard">Lokitiedostot kopioitu leikepöydälle</string>
<string name="label_browser_configuration">Selainasetukset</string>
</resources>

View File

@ -25,7 +25,9 @@
<string name="button_router_off">Presser longtemps pour démarrer I2P</string>
<string name="button_router_on">I2P est en marche (presser longtemps pour arrêter)</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_client_tunnels_running">Aucun tunnel de client n\'est encore en marche.</string>
<string name="configure_browser_title">Configurer le navigateur ?</string>
<string name="configure_browser_for_i2p">Voudriez-vous configurer un navigateur pour voir les sites d\'I2P ? (vous pouvez aussi faire cela plus tard depuis le menu d\'aide).</string>
@ -116,6 +118,7 @@
<string name="about_volunteer">Vous souhaitez aider à améliorer l\'application ? Devenez volontaire sur le forum Android :</string>
<string name="about_donate">Vous souhaitez faire un don d\'argent ou de bitcoins pour acheter davantage d\'équipements Android pour les développements et les tests ? Allez sur :</string>
<string name="menu_help">Aide</string>
<string name="general">Général</string>
<string name="addressbook_search_header">%s trouvé</string>
<string name="addressbook_add_wizard_k_name">Nom</string>
<string name="addressbook_add_wizard_k_destination">Destination</string>
@ -138,6 +141,8 @@
<string name="i2ptunnel_type_streamrclient">Client Streamr</string>
<string name="i2ptunnel_type_streamrserver">Serveur Streamr</string>
<string name="i2ptunnel_type_httpbidirserver">Bidir HTTP</string>
<string name="install_recommended_app">Installer l\'app recommandée ?</string>
<string name="app_needed_for_this_tunnel_type">Vous devez installer une app pour utiliser ce tunnel. Voudriez-vous installer l\'app recommandée ?</string>
<string name="i2ptunnel_not_initialized">Les tunnels ne sont pas encore initialisés, veuillez recharger dans deux minutes.</string>
<string name="i2ptunnel_new_tunnel">Nouveau tunnel</string>
<string name="i2ptunnel_msg_config_saved">Changements de configuration sauvegardés</string>

View File

@ -25,7 +25,12 @@
<string name="button_router_off">長押しして I2P を起動</string>
<string name="button_router_on">I2P を起動中 (長押しで中止)</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_client_tunnels_running">まだクライアントトンネルは起動していません。</string>
<string name="configure_browser_title">ブラウザの設定をしますか?</string>
<string name="configure_browser_for_i2p">I2Pサイトを見るためにブラウザを設定しますか(あとでヘルプメニューからも設定できます)</string>
<string name="first_start_title">I2P のインストールおめでとうございます!</string>
<string name="first_start_welcome"><b>I2P へようこそ!</b> I2P が立ち上がり、ピアを見つけるまで<b>我慢してください</b></string>
<string name="first_start_read">待っている間、リリースノートとウェルカムページをお読みください。</string>
@ -51,6 +56,8 @@
<string name="action_reload_subscriptions">購読を再読込</string>
<string name="router_not_running">ルーターが起動していません。</string>
<string name="stats_not_ready">統計マネージャーはまだ準備出来ていません。後でやり直してください。</string>
<string name="no_graphs_configured">グラフは設定されていません。設定でどの統計をグラフにするか選択できます。すべての変更は60秒後に有効になります</string>
<string name="configure_graphs">グラフ設定</string>
<string name="graphs_not_ready">グラフが準備出来ていない、あるいはルーターが起動していません。後でもう一度やり直してください。</string>
<string name="netdb_routers_empty">NetDB にルーターがありません。</string>
<string name="netdb_leases_empty">NetDB にリースセットがありません。</string>
@ -102,6 +109,7 @@
<string name="settings_label_expl_backupQuantity">バックアップの数量</string>
<string name="settings_summ_expl_backupQuantity">%s トンネル</string>
<string name="settings_desc_expl_backupQuantity">トンネルバックアップの数</string>
<string name="settings_router_restart_required">設定を適用するためにI2Pを再起動してください</string>
<string name="menu_about">アバウト</string>
<string name="about_version">バージョン:</string>
<string name="about_project">プロジェクトホーム:</string>
@ -110,6 +118,7 @@
<string name="about_volunteer">アプリの改善を手伝いたいですか? Android フォーラム上でボランティア:</string>
<string name="about_donate">開発や試験用にさらに Android デバイスを購入するために、お金や Bitcoin を寄付していただけますか? こちらです:</string>
<string name="menu_help">ヘルプ</string>
<string name="general">一般</string>
<string name="addressbook_search_header">%s 検出</string>
<string name="addressbook_add_wizard_k_name">名前</string>
<string name="addressbook_add_wizard_k_destination">宛先</string>
@ -132,6 +141,8 @@
<string name="i2ptunnel_type_streamrclient">Streamr クライアント</string>
<string name="i2ptunnel_type_streamrserver">Streamr サーバー</string>
<string name="i2ptunnel_type_httpbidirserver">HTTP 双方向</string>
<string name="install_recommended_app">推奨アプリをインストールしますか?</string>
<string name="app_needed_for_this_tunnel_type">このトンネルを使用するには推奨アプリをインストールする必要があります。インストールしますか?</string>
<string name="i2ptunnel_not_initialized">トンネルはまだ初期化されていません、2分後に再読み込みしてください。</string>
<string name="i2ptunnel_new_tunnel">新規トンネル</string>
<string name="i2ptunnel_msg_config_saved">構成の変更が保存されました</string>
@ -174,4 +185,10 @@
<string name="i2ptunnel_view_target">ターゲット:</string>
<string name="i2ptunnel_view_access_point">アクセスポイント:</string>
<string name="i2ptunnel_view_autostart">自動開始</string>
<string name="copy_logs">ログをコピー</string>
<string name="i2p_android_error_logs">I2PAndroidエラーログ</string>
<string name="i2p_android_logs">I2PAndroidログ</string>
<string name="error_logs_copied_to_clipboard">エラーログはクリップボードにコピーされました</string>
<string name="logs_copied_to_clipboard">ログはクリップボードにコピーされました</string>
<string name="label_browser_configuration">ブラウザ設定</string>
</resources>

View File

@ -118,6 +118,7 @@
<string name="about_volunteer">이 앱을 개선시키고 싶나요? 안드로이드 포럼에서 기여하세요:</string>
<string name="about_donate">돈이나 비트코인 기부로 개발과 테스팅에 필요한 안드로이드 기기 구입을 돕고 싶나요? 참조하세요:</string>
<string name="menu_help">도움말</string>
<string name="general">일반</string>
<string name="addressbook_search_header">%s 찾음</string>
<string name="addressbook_add_wizard_k_name">이름</string>
<string name="addressbook_add_wizard_k_destination">목적지</string>
@ -158,6 +159,8 @@
<string name="i2ptunnel_wizard_k_outproxies">나가는 프록시</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_binding_port">바인드 포트</string>
<string name="i2ptunnel_wizard_k_auto_start">자동 시작</string>
<string name="next">다음</string>
<string name="prev">이전</string>
@ -171,6 +174,7 @@
<string name="i2ptunnel_wizard_desc_target_host">서비스가 작동중인 IP, 대부분의 경우 같은 기기이기 때문에 127.0.0.1이 자동 입력됨.</string>
<string name="i2ptunnel_wizard_desc_target_port">서비스가 접속을 받아들일 포트.</string>
<string name="i2ptunnel_wizard_desc_reachable_on">이 터널을 접근할 수 있는 컴퓨터 혹은 스마트폰 제한.</string>
<string name="i2ptunnel_wizard_desc_binding_port">이 포트는 로컬에서 접근될 클라이언트 터널입니다. 또한 bidir 서버 터널의 클라이언트 포트이기도 합니다.</string>
<string name="i2ptunnel_wizard_desc_auto_start">라우터가 시작할때 터널도 같이 실행?</string>
<string name="i2ptunnel_wizard_submit_confirm_message">터널을 만들까요?</string>
<string name="i2ptunnel_wizard_submit_confirm_button">터널 </string>

View File

@ -25,7 +25,12 @@
<string name="button_router_off">Hold inne kappen for å starte I2P</string>
<string name="button_router_on">I2P kjører (hold inne knappen for å stoppe)</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">T</string>
<string name="no_client_tunnels_running">Foreløpig kjører ingen klient-tunneler</string>
<string name="configure_browser_title">Sett opp nettleser?</string>
<string name="configure_browser_for_i2p">Vil du sette opp nettleseren for visning av I2P-sider? (Du kan også gjøre dette senere fra hjelpemenyen.)</string>
<string name="first_start_title">Til lykke med ny installasjon av I2P!</string>
<string name="first_start_welcome"><b> Velkommen til I2P</b> Vennligst <b>ha tålmodighet</b> mens I2P starter opp og finner likemenn.</string>
<string name="first_start_read">Mens du venter, vennligst les versjons-notatene og velkomstsiden.</string>
@ -104,6 +109,7 @@
<string name="settings_label_expl_backupQuantity">Sikkerhetskopi-mengde</string>
<string name="settings_summ_expl_backupQuantity">%s tunneler</string>
<string name="settings_desc_expl_backupQuantity">Hvor mange reservetunneler</string>
<string name="settings_router_restart_required">Gjør en omstart av I2P for å utføre endringer</string>
<string name="menu_about">Om</string>
<string name="about_version">Versjon:</string>
<string name="about_project">Prosjekts-heim:</string>
@ -112,6 +118,7 @@
<string name="about_volunteer">Vil du gjøre dette programmet bedre? Meld deg som frivillig på Android-forumet:</string>
<string name="about_donate">Vil du donere penger eller bitcoin øremerket flere Android-enheter til utvikling og testformål? Gå til:</string>
<string name="menu_help">Hjelp</string>
<string name="general">Generelt</string>
<string name="addressbook_search_header">%s funnet</string>
<string name="addressbook_add_wizard_k_name">Navn</string>
<string name="addressbook_add_wizard_k_destination">Mål-katalog</string>
@ -134,6 +141,8 @@
<string name="i2ptunnel_type_streamrclient">Streamr-klient</string>
<string name="i2ptunnel_type_streamrserver">Streamr-tjener</string>
<string name="i2ptunnel_type_httpbidirserver">HTTP bidir</string>
<string name="install_recommended_app">Installere anbefalt app?</string>
<string name="app_needed_for_this_tunnel_type">Du trenger å installere en app for å bruke denne tunnelen. Vil du installere den anbefalte appen?</string>
<string name="i2ptunnel_not_initialized">Tunneler er ikke klargjort enda, vennligst last inn på nytt om to minutter.</string>
<string name="i2ptunnel_new_tunnel">Ny Tunnel</string>
<string name="i2ptunnel_msg_config_saved">Konfigurasjonsendringer lagret</string>
@ -176,4 +185,10 @@
<string name="i2ptunnel_view_target">Mål:</string>
<string name="i2ptunnel_view_access_point">Tilknytningspunkt:</string>
<string name="i2ptunnel_view_autostart">Auto-start</string>
<string name="copy_logs">Kopier loggførsel</string>
<string name="i2p_android_error_logs">Loggføring av feil for Android I2P</string>
<string name="i2p_android_logs">Loggfiler for Android I2P</string>
<string name="error_logs_copied_to_clipboard">Utklippstavle for feil-logg</string>
<string name="logs_copied_to_clipboard">Utklippstavle for loggføringer</string>
<string name="label_browser_configuration">Oppsett av nettleser</string>
</resources>

View File

@ -4,6 +4,7 @@
<string name="desc_i2p_logo">I2P logo</string>
<string name="welcome_new_install">Welkom op I2P! Deze app heeft de ALPHA status en het biedt geen sterke anonimiteit. Lees de releaseopmerkingen en licentie-informatie.</string>
<string name="welcome_new_version">Nieuwe versie geïnstalleerd. Lees de releaseopmerkingen. Versie:</string>
<string name="label_home">Instellingen en Status</string>
<string name="label_tunnels">Tunnels</string>
<string name="label_status">Status</string>
<string name="label_addressbook">Adresboek</string>
@ -24,7 +25,12 @@
<string name="button_router_off">Lang drukken om I2P te starten</string>
<string name="button_router_on">I2P is actief (lang drukken om te stoppen)</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_client_tunnels_running">Er draaien nog geen client tunnels.</string>
<string name="configure_browser_title">Browser instellen?</string>
<string name="configure_browser_for_i2p">Wil je een browser instellen om I2P-sites te kunnen bekijken? (Je kan dit ook later doen vanuit het help-menu.)</string>
<string name="first_start_title">Gefeliciteerd met de installatie van I2P!</string>
<string name="first_start_welcome"><b>Welkom bij I2P! Heb geduld alstublieft</b> terwijl I2P opstart en peers zoekt.</string>
<string name="first_start_read">Terwijl je wacht, lees alstublieft de release aantekeningen en welkom pagina.</string>
@ -49,15 +55,22 @@
<string name="hint_search_addressbook">Zoeken in adresboek</string>
<string name="action_reload_subscriptions">Vernieuw abonnementen</string>
<string name="router_not_running">De router is uit.</string>
<string name="stats_not_ready">De statistiekenbeheerder is nog niet klaar. Probeer het later opnieuw.</string>
<string name="no_graphs_configured">Geen grafieken ingesteld. Je kan de statistieken om in grafieken weer te geven instellen in het instellingenmenu. Alle wijzigingen vinden plaats na 60 seconden.</string>
<string name="configure_graphs">Grafieken instellen</string>
<string name="graphs_not_ready">Grafieken zijn niet klaar, of de router staat uit. Probeer het later opnieuw.</string>
<string name="netdb_routers_empty">Geen routers in je NetDB.</string>
<string name="netdb_leases_empty">Geen LeaseSets in je NetDB.</string>
<string name="notification_status_bw">Bandbreedte: %1$s KBps down / %2$s KBps up</string>
<string name="notification_status_peers">Peers: %1$d actief, %2$d bekend</string>
<string name="notification_status_expl">Verkennende tunnels: %1$d/%2$d</string>
<string name="notification_status_client">Cliënt tunnels: %1$d/%2$d</string>
<string name="menu_settings">Instellingen</string>
<string name="settings_enable">Inschakelen</string>
<string name="settings_desc_subscriptions">URL\'s van abbonementen</string>
<string name="settings_label_bandwidth_net">Bandbreedte en netwerk</string>
<string name="settings_label_startOnBoot">I2P starten bij opstarten van toestel</string>
<string name="settings_desc_startOnBoot">Automatisch verbinden met I2P wanneer je Android-toestel opstart</string>
<string name="settings_label_bandwidth">Bandbreedte</string>
<string name="settings_label_bw_inbound">Binnenkomende snelheid</string>
<string name="settings_desc_bw_inbound">Maximale binnenkomende snelheid</string>
@ -87,8 +100,10 @@
<string name="settings_label_expl_inbound">Inkomende tunnels</string>
<string name="settings_label_expl_outbound">Uitgaande tunnels</string>
<string name="settings_label_expl_length">Lengte</string>
<string name="settings_summ_expl_length">%s hops</string>
<string name="settings_desc_expl_length">Hoeveel \'hops\' te gebruiken</string>
<string name="settings_label_expl_lengthVariance">\'Hop\'-variantie</string>
<string name="settings_summ_expl_lengthVariance">%s</string>
<string name="settings_desc_expl_lengthVariance">Hoeveel willekeurig toe te voegen \'hops\'</string>
<string name="settings_label_expl_quantity">Hoeveelheid</string>
<string name="settings_summ_expl_quantity">%s tunnels</string>
@ -96,17 +111,26 @@
<string name="settings_label_expl_backupQuantity">Back-up hoeveelheid</string>
<string name="settings_summ_expl_backupQuantity">%s tunnels</string>
<string name="settings_desc_expl_backupQuantity">Hoeveel tunnel back-ups</string>
<string name="settings_router_restart_required">Herstart I2P om de instellingen toe te passen</string>
<string name="menu_about">Over</string>
<string name="about_version">Versie:</string>
<string name="about_project">Project Home:</string>
<string name="about_bugs">Bugs en Ondersteuning:</string>
<string name="about_helpwanted">Hulp Gezocht!</string>
<string name="about_volunteer">Wil je vrijwillig helpen de app beter te maken? Kijk op het Android forum:</string>
<string name="about_donate">Wil je geld of bitcoins doneren zodat we op meer Android telefoons kunnen ontwikkelen en testen? Ga naar:</string>
<string name="menu_help">Help</string>
<string name="general">Algemeen</string>
<string name="addressbook_search_header">%s gevonden</string>
<string name="addressbook_add_wizard_k_name">Naam</string>
<string name="addressbook_add_wizard_k_destination">Bestemming</string>
<string name="addressbook_add_wizard_desc_name">De naam</string>
<string name="addressbook_add_wizard_desc_destination">Plak de B64 van de bestemming hier. Als je een bestand manager geïnstalleerd hebt, kan je het tekst bestand met de B64 zoeken.</string>
<string name="nsu_iae_illegal_char">Hostnaam \"%1$s\" bevat een illegaal karakter %2$s</string>
<string name="nsu_iae_cannot_start_with">Hostnaam kan niet beginnen met \"%s\"</string>
<string name="nsu_iae_cannot_end_with">Hostnaam kan niet eindigen met \"%s\"</string>
<string name="nsu_iae_cannot_contain">Hostnaam kan \"%s\" niet bevatten</string>
<string name="nsu_iae_requires_conversion">Hostnaam \"%s\" vereist conversie naar ASCII, maar de conversie-bibliotheek is niet beschikbaar in deze Android-versie</string>
<string name="i2ptunnel_type_client">Standaard cliënt</string>
<string name="i2ptunnel_type_httpclient">HTTP cliënt</string>
<string name="i2ptunnel_type_ircclient">IRC cliënt</string>
@ -119,6 +143,8 @@
<string name="i2ptunnel_type_streamrclient">Streamr cliënt</string>
<string name="i2ptunnel_type_streamrserver">Streamr server</string>
<string name="i2ptunnel_type_httpbidirserver">HTTP bidir</string>
<string name="install_recommended_app">Aanbevolen applicatie installeren?</string>
<string name="app_needed_for_this_tunnel_type">Je moet een applicatie installeren om deze tunnel te gebruiken. Wil je de aanbevolen applicatie installeren?</string>
<string name="i2ptunnel_not_initialized">Tunnels zijn nog niet klaar, ververs in twee minuten aub.</string>
<string name="i2ptunnel_new_tunnel">Nieuwe tunnel</string>
<string name="i2ptunnel_msg_config_saved">Cofiguratie veranderingen opgeslagen</string>
@ -135,7 +161,11 @@
<string name="i2ptunnel_wizard_k_desc">Beschrijving</string>
<string name="i2ptunnel_wizard_k_dest">Bestemming</string>
<string name="i2ptunnel_wizard_k_outproxies">Outproxies</string>
<string name="i2ptunnel_wizard_k_target_host">Doelhost</string>
<string name="i2ptunnel_wizard_k_target_port">Doelpoort</string>
<string name="i2ptunnel_wizard_k_reachable_on">Bereikbaar op</string>
<string name="i2ptunnel_wizard_k_binding_port">Bindende poort</string>
<string name="i2ptunnel_wizard_k_auto_start">Automatisch starten</string>
<string name="next">Volgende</string>
<string name="prev">Vorige</string>
<string name="finish">Indienen</string>
@ -143,12 +173,25 @@
<string name="enabled">Staat aan</string>
<string name="i2ptunnel_wizard_desc_name">De naam van de tunnel, voor het identificeren in de tunnel lijst.</string>
<string name="i2ptunnel_wizard_desc_desc">Een beschrijving van de tunnel. Dit is niet verplicht maar wel informatief.</string>
<string name="i2ptunnel_wizard_desc_dest">Typ de I2P-bestemming van de dienst in waar deze cliënt-tunnel mee moet verbinden. Dit kan de volledige base-64 bestemmingssleutel zijn, of een I2P-URL van je adresboek.</string>
<string name="i2ptunnel_wizard_desc_outproxies">Als u outproxies kent voor dit type tunnel (HTTP of SOCKS), vul ze dan in. Scheid meerdere proxies door middel van komma\'s.</string>
<string name="i2ptunnel_wizard_desc_target_host">Dit is het IP adres waarop je service runt, dit is meestal op dezelfde machine, dus 127.0.0.1 is standaard ingevuld.</string>
<string name="i2ptunnel_wizard_desc_target_port">Dit is de poort waar de service verbindingen op ontvangt.</string>
<string name="i2ptunnel_wizard_desc_reachable_on">Dit limiteert welke computers of smartphones de tunnel kunnen bereiken.</string>
<string name="i2ptunnel_wizard_desc_binding_port">Dit is de poort vanwaar de cliënt-tunnel lokaal zal bereikt worden. Dit is ook de cliënt-poort voor de HTTP bidir server tunnel.</string>
<string name="i2ptunnel_wizard_desc_auto_start">Moet de tunnel automatisch gestart worden als de router start?</string>
<string name="i2ptunnel_wizard_submit_confirm_message">Tunnel aanmaken?</string>
<string name="i2ptunnel_wizard_submit_confirm_button">Tunnel aanmaken</string>
<string name="i2ptunnel_view_type">Type:</string>
<string name="i2ptunnel_view_desc">Beschrijving:</string>
<string name="i2ptunnel_view_target">Doel:</string>
<string name="i2ptunnel_view_access_point">Toegangspunt:</string>
<string name="i2ptunnel_view_autostart">Automatisch starten</string>
<string name="copy_logs">Kopieer logs</string>
<string name="i2p_android_error_logs">I2P Android Error Logs</string>
<string name="i2p_android_logs">I2P Android Logs</string>
<string name="error_logs_copied_to_clipboard">Error logs naar het klembord gekopieerd</string>
<string name="logs_copied_to_clipboard">Logs naar het klembord gekopieerd</string>
<string name="label_browser_configuration">Browserconfiguratie</string>
<string name="unset">Niet ingesteld</string>
</resources>

View File

@ -2,7 +2,7 @@
<resources>
<string name="app_name">I2P</string>
<string name="desc_i2p_logo">Logo I2P</string>
<string name="welcome_new_install">Witamy w I2P! Ta aplikacja jest w fazie ALPHA i nie zapewnia mocnej anonimowości. Zalecamy zapoznanie się z listą zmian i licencją. </string>
<string name="welcome_new_install">Witamy w I2P! Aplikacja jest w fazie ALPHA i nie zapewnia mocnej anonimowości. Zalecamy zapoznanie się z listą zmian i licencją. </string>
<string name="welcome_new_version">Nowa wersja zainstalowana. Przeczytaj listę zmian. Wersja:</string>
<string name="label_home">Kontrola i Status</string>
<string name="label_tunnels">Tunele</string>
@ -12,7 +12,7 @@
<string name="label_i2ptunnel_client">Tunele klienta</string>
<string name="label_i2ptunnel_server">Tunele serwerów</string>
<string name="label_logs">Logi</string>
<string name="label_error_logs">Rejestr błędów</string>
<string name="label_error_logs">Logi błędów</string>
<string name="label_info_and_pages">Informacje i strony</string>
<string name="label_welcome_page">Strona Powitalna</string>
<string name="label_news">Wiadomości</string>
@ -22,15 +22,20 @@
<string name="label_nonanon_info">Nie Anonimowe Informacje</string>
<string name="label_browse">Przeglądaj</string>
<string name="label_graphs">Wykresy</string>
<string name="button_router_off">Dotknij na dłużej aby uruchomić I2P</string>
<string name="button_router_off">Przytrzymaj dłużej, aby uruchomić I2P</string>
<string name="button_router_on">I2P jest włączone (dotknij na dłużej aby zatrzymać)</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="first_start_title">Gratulacje w zainstalowaniu I2P!</string>
<string name="char_server_tunnel">S</string>
<string name="no_client_tunnels_running">Jeszcze żadne tunele klienta nie są uruchomione.</string>
<string name="configure_browser_title">Konfigurować przeglądarkę?</string>
<string name="configure_browser_for_i2p">Czy chciałbyś skonfigurować przeglądarkę, aby przeglądać strony I2P? (Możesz to zrobić później w wybierająć pomoc z menu.)</string>
<string name="first_start_title">Gratulacje, zainstalowałeś I2P!</string>
<string name="first_start_welcome"><b>Witamy w I2P!</b> Proszę <b>bądz cierpliwy</b> bo I2P właśnie się uruchamia i szuka peerów.</string>
<string name="first_start_read">W międzyczasie, prosimy o zapoznanie się z notatkami tego wydania oraz stroną powitalną.</string>
<string name="first_start_faq">Kiedy będziesz miał tunele klienta proszę <b>sprawdź</b> nasze FAQ:</string>
<string name="first_start_faq_nonanon">Also użyj tych nie-anonimowych linków jeśli nie chcesz czekać na tunele:</string>
<string name="first_start_faq">Kiedy już będziesz miał tunele klienta proszę <b>sprawdź</b> nasze FAQ:</string>
<string name="first_start_faq_nonanon">Also użyj tego nie-anonimowego linka jeśli nie chcesz czekać na tunele:</string>
<string name="first_start_irc">Skieruj swojego klienta IRC do <b>localhost:6668</b> i przywitaj się z nami na.</string>
<string name="drawer_open">Otwórz nawigację</string>
<string name="drawer_close">Zamknij nawigację</string>
@ -40,8 +45,8 @@
<string name="action_delete">Usuń</string>
<string name="action_router_start">Uruchom Router</string>
<string name="action_router_stop">Zatrzymaj Router</string>
<string name="action_i2ptunnel_start">Włącz tunel</string>
<string name="action_i2ptunnel_stop">Wyłącz tunel</string>
<string name="action_i2ptunnel_start">Uruchom tunel</string>
<string name="action_i2ptunnel_stop">Zatrzymaj tunel</string>
<string name="action_i2ptunnel_start_all">Uruchom wszystkie tunele</string>
<string name="action_i2ptunnel_stop_all">Zatrzymaj wszystkie tunele</string>
<string name="action_i2ptunnel_restart_all">Zrestartuj wszystkie tunele</string>
@ -73,10 +78,10 @@
<string name="settings_label_hiddenMode">Uczestnictwo</string>
<string name="settings_desc_hiddenMode">Wyłącz tryp ukryty</string>
<string name="settings_label_maxPartTunnels">Maksymalna liczba uczestniczących tuneli</string>
<string name="settings_desc_maxPartTunnels">Maksaymalna liczba tuneli uczestniczących w (domyślne=20)</string>
<string name="settings_dialog_maxPartTunnels">Maksymalna liczba tuneli uczestniczących w</string>
<string name="settings_label_sharePercent">Udział procentowy</string>
<string name="settings_desc_sharePercent">Udział procentowy przepustowości do podziału (domyślne=80)</string>
<string name="settings_desc_maxPartTunnels">Maksaymalna liczba tuneli uczestniczących (domyślnie=20)</string>
<string name="settings_dialog_maxPartTunnels">Maksymalna liczba tuneli uczestniczących</string>
<string name="settings_label_sharePercent">Procent podziału</string>
<string name="settings_desc_sharePercent">Procent przepustowości do podziału (domyślnie=80)</string>
<string name="settings_dialog_sharePercent">Procent przepustowości do podziału</string>
<string name="settings_desc_upnp">Otwórz porty firewall\'a automatycznie</string>
<string name="settings_label_logging">Logowanie</string>
@ -97,29 +102,31 @@
<string name="settings_desc_expl_length">Ile użyć skoków</string>
<string name="settings_label_expl_lengthVariance">Wariancje skoków</string>
<string name="settings_summ_expl_lengthVariance">%s</string>
<string name="settings_desc_expl_lengthVariance">Ile skoków losowych dodać</string>
<string name="settings_desc_expl_lengthVariance">Ile dodać losowych skoków</string>
<string name="settings_label_expl_quantity">Ilość</string>
<string name="settings_summ_expl_quantity">%s tunelów</string>
<string name="settings_desc_expl_quantity">Ile tunelów</string>
<string name="settings_label_expl_backupQuantity">Ilość kopii zapasowych</string>
<string name="settings_summ_expl_backupQuantity">%s tunelów</string>
<string name="settings_desc_expl_backupQuantity">Ilość kopii zapasowych tuneli</string>
<string name="settings_router_restart_required">Proszę zrestartuj I2P, aby zmiany weszły w życie.</string>
<string name="menu_about">O programie</string>
<string name="about_version">Wersja:</string>
<string name="about_project">Strona Projektu:</string>
<string name="about_bugs">Błędy i wsparcie:</string>
<string name="about_helpwanted">Potrzebna pomoc!</string>
<string name="about_volunteer">Chcesz pomóc w ulepszeniu tej aplikacji? Zgłoś się na ochotnika na forum Android:</string>
<string name="about_donate">Chcesz przesłać pieniądze lub bitcoiny aby zakupić więcej Androidów dla rozwoju i testowania? Idź do:</string>
<string name="about_donate">Chcesz przesłać pieniądze lub bitcoiny, aby zakupić więcej Androidów dla rozwoju i testowania? Idź do:</string>
<string name="menu_help">Pomoc</string>
<string name="general">Ogólne</string>
<string name="addressbook_search_header">%s znaleziono</string>
<string name="addressbook_add_wizard_k_name">Nazwa</string>
<string name="addressbook_add_wizard_k_destination">Miejsce przeznaczenia</string>
<string name="addressbook_add_wizard_k_destination">Przeznaczenie</string>
<string name="addressbook_add_wizard_desc_name">Nazwa</string>
<string name="addressbook_add_wizard_desc_destination">Wklej B64 miejsca przeznaczenia tutaj. Jeśli masz menadżer plików zainstalowany, to możesz przegladać pliki tekstowe zawierające B64.</string>
<string name="addressbook_add_wizard_desc_destination">Wklej B64 przeznaczenia tutaj. Jeśli masz zainstalowany menadżer plików to możesz przegladać pliki tekstowe zawierające B64.</string>
<string name="nsu_iae_illegal_char">Nazwa hosta \"%1$s\" zawiera niedozwolony znak %2$s</string>
<string name="nsu_iae_cannot_start_with">Nazwa hosta nie może zaczynać się od \"%s\"</string>
<string name="nsu_iae_cannot_end_with">Nazwa hosta nie może kończyć się \"%s\"</string>
<string name="nsu_iae_cannot_end_with">Nazwa hosta nie może kończyć się na \"%s\"</string>
<string name="nsu_iae_cannot_contain">Nazwa hosta nie może zawierać \"%s\"</string>
<string name="nsu_iae_requires_conversion">Nazwa hosta \"%s\" wymaga konwersji do ASCII, ale biblioteka konwersji jest niedostępna w tej wersji Android. </string>
<string name="i2ptunnel_type_client">Standardowy klient</string>
@ -134,9 +141,11 @@
<string name="i2ptunnel_type_streamrclient">Klient Streamr</string>
<string name="i2ptunnel_type_streamrserver">Serwer Streamr</string>
<string name="i2ptunnel_type_httpbidirserver">HTTP bidir</string>
<string name="install_recommended_app">Zainstalować polecone aplikacje?</string>
<string name="app_needed_for_this_tunnel_type">Musisz zainstalować aplikację, aby użyć tego tunelu. Czy chcesz zainstalować tą aplikację?</string>
<string name="i2ptunnel_not_initialized">Tunele nie są jeszcze zainicjowane, proszę odświeżyć za dwie minuty.</string>
<string name="i2ptunnel_new_tunnel">Nowy tunel</string>
<string name="i2ptunnel_msg_config_saved">Zapisano zmiany konfiguracji</string>
<string name="i2ptunnel_msg_config_saved">Zmiany konfiguracji zostały zapisane</string>
<string name="i2ptunnel_msg_config_save_failed">Nie udało zapisać się konfiguracji</string>
<string name="i2ptunnel_msg_tunnel_starting">Uruchamianie tunelu</string>
<string name="i2ptunnel_msg_tunnel_stopping">Zatrzymanie tunelu</string>
@ -161,14 +170,14 @@
<string name="review">Przegląd</string>
<string name="enabled">Włączony</string>
<string name="i2ptunnel_wizard_desc_name">Nazwa tunelu dla identyfikacji w liście tuneli.</string>
<string name="i2ptunnel_wizard_desc_desc">Opis tunelu. Ta opcja jest nieobowiązkowa i wyłącznie służąca do celów informacyjnych.</string>
<string name="i2ptunnel_wizard_desc_dest">Wpisz przeznaczenie serwisu I2P z którym klient tunelu ma się połączyć. To może być pełna baza 64 przeznaczenia klucza, lub URL I2P z Twojej książki adresowej.</string>
<string name="i2ptunnel_wizard_desc_outproxies">Jeśli znasz jakieś wychodzące proxy dla tego typu tunelów (HTTP lub SOCKS), to wpisz je. Oddziel proxy przecinkami.</string>
<string name="i2ptunnel_wizard_desc_target_host">To jest IP z którego Twój serwis jest uruchomiony, zazwyczaj jest to te same urządzenie więc 127.0.0.1 jest wpisane automatycznie.</string>
<string name="i2ptunnel_wizard_desc_desc">Opis tunelu. Ta opcja jest nieobowiązkowa i służąca wyłącznie do celów informacyjnych.</string>
<string name="i2ptunnel_wizard_desc_dest">Wpisz przeznaczenie serwisu I2P z którym klient tunelu ma się połączyć. To może być pełny klucz base 64 przeznaczenia, lub URL I2P z Twojej książki adresowej.</string>
<string name="i2ptunnel_wizard_desc_outproxies">Jeśli znasz jakieś wychodzące proxy dla tego typu tunelów (HTTP lub SOCKS), to je wpisz. Serwery proxy oddziel przecinkami.</string>
<string name="i2ptunnel_wizard_desc_target_host">To jest IP na którym Twój serwis jest uruchomiony, zazwyczaj jest to te same urządzenie więc 127.0.0.1 jest wpisane automatycznie.</string>
<string name="i2ptunnel_wizard_desc_target_port">To jest port na którym Twój serwis akceptuje połączenia.</string>
<string name="i2ptunnel_wizard_desc_reachable_on">To limituje do czego komputery lub telefony mogą mięć dostęp w tunelu.</string>
<string name="i2ptunnel_wizard_desc_binding_port">To jest port z którego klient tunelu będzie miał dostęp lokalny. To jest także port klienta dla HTTP bidir serwera tunelu.</string>
<string name="i2ptunnel_wizard_desc_auto_start">Czy tunel powinien włączyć się automatycznie kiedy włączy się router?</string>
<string name="i2ptunnel_wizard_desc_reachable_on">To limituje do czego komputery lub telefony mogą mięć dostęp w tym tunelu.</string>
<string name="i2ptunnel_wizard_desc_binding_port">To jest port z którego klient tunelu będzie miał dostęp lokalnie. To jest także port klienta dla HTTP bidir serwera tunelu.</string>
<string name="i2ptunnel_wizard_desc_auto_start">Czy chcesz, aby tunel włączył się automatycznie kiedy uruchomi się router?</string>
<string name="i2ptunnel_wizard_submit_confirm_message">Utworzyć tunel?</string>
<string name="i2ptunnel_wizard_submit_confirm_button">Utwórz tunel</string>
<string name="i2ptunnel_view_type">Typ:</string>
@ -176,4 +185,10 @@
<string name="i2ptunnel_view_target">Cel:</string>
<string name="i2ptunnel_view_access_point">Punkt dostępu:</string>
<string name="i2ptunnel_view_autostart">Auto-start</string>
<string name="copy_logs">Kopiuj logi</string>
<string name="i2p_android_error_logs">Logi Błędów I2P Android</string>
<string name="i2p_android_logs">Logi Błędów I2P Android</string>
<string name="error_logs_copied_to_clipboard">Logi błędów zostały skopiowane do schowka</string>
<string name="logs_copied_to_clipboard">Logi zostały skopiowane do schowka</string>
<string name="label_browser_configuration">Konfiguracja przeglądarki</string>
</resources>

View File

@ -4,7 +4,7 @@
<string name="desc_i2p_logo">Emblema I2P</string>
<string name="welcome_new_install">Bine ati venit la I2P! Aceasta aplicatie este un software ALPHA și nu oferă anonimatul puternic. Vă rugăm să citiți notele de lansare și licență.</string>
<string name="welcome_new_version">Noua versiune instalată. Vă rugăm să citiți notele de lansare. versiune:</string>
<string name="label_home">Stare si Controale</string>
<string name="label_home">Controale și stare</string>
<string name="label_tunnels">Tuneluri</string>
<string name="label_status">Stare</string>
<string name="label_addressbook">Agendă</string>
@ -25,8 +25,16 @@
<string name="button_router_off">Apasari lung pentru a porni I2P</string>
<string name="button_router_on">I2P ruleaza (tineti apasat pentru a oprii)</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="configure_browser_title">Configurați navigatorul web?</string>
<string name="configure_browser_for_i2p">Doriți să configurați un navigator web să vizualizați site-uri I2P? (Puteți face acest lucru mai târziu din meniul ajutor.)</string>
<string name="first_start_title">Felicitari pentru instalarea I2P!</string>
<string name="first_start_read">Cât timp așteptați, citiți notele de lansare și pagina de bun venit.</string>
<string name="first_start_faq_nonanon">Sau utilizați acest link ne-anonim dacă nu doriți să așteptați pentru tuneluri:</string>
<string name="drawer_open">Deschide nav</string>
<string name="drawer_close">Închide nav</string>
<string name="action_search">Cauta</string>
<string name="action_add">Adaugă</string>
<string name="action_edit">Editeaza</string>
@ -47,6 +55,7 @@
<string name="graphs_not_ready">Graficele nu sunt gata, sau ruterul nu rulează. Încercați mai târziu.</string>
<string name="netdb_routers_empty">Nu sunt rutere în NetDB.</string>
<string name="notification_status_bw">Lățime de bandă: %1$s KBps desc / %2$s KBps în</string>
<string name="notification_status_peers">Parteneri: %1$d activi, %2$d cunoscuți</string>
<string name="menu_settings">Configurări</string>
<string name="settings_enable">Activează</string>
<string name="settings_desc_subscriptions">URLs de abonare:</string>
@ -88,6 +97,7 @@
<string name="settings_label_expl_backupQuantity">Cantitatea de rezervă</string>
<string name="settings_summ_expl_backupQuantity">%s tuneluri</string>
<string name="settings_desc_expl_backupQuantity">Câți copii de rezervă tunel</string>
<string name="settings_router_restart_required">Reporniți I2P pentru aplicarea modificărilor</string>
<string name="menu_about">Despre</string>
<string name="about_version">Versiune:</string>
<string name="about_bugs">Defecte și suport:</string>
@ -95,16 +105,33 @@
<string name="about_volunteer">Doriți să faceți aplicația mai bună? Voluntari pe forumul Android:</string>
<string name="about_donate">Doriți să donați bani sau bitcoins pentru cumpărarea de mai multe dispozitive Android pentru dezvoltare și testare? Mergeți la:</string>
<string name="menu_help">Ajutor</string>
<string name="general">General</string>
<string name="addressbook_search_header">%s gasit</string>
<string name="addressbook_add_wizard_k_name">Nume</string>
<string name="addressbook_add_wizard_k_destination">Destinatie</string>
<string name="addressbook_add_wizard_desc_name">Numele</string>
<string name="nsu_iae_illegal_char">Numele gazdă \"%1$s\" conține caractere ilegale %2$s</string>
<string name="nsu_iae_cannot_start_with">Numele gazdă nu poate începe cu \"%s\"</string>
<string name="nsu_iae_cannot_end_with">Numele gazdă nu se poate termina cu \"%s\"</string>
<string name="nsu_iae_cannot_contain">Numele gazdă nu poate conține \"%s\"</string>
<string name="nsu_iae_requires_conversion">Numele gazdă \"%s\" necesită conversia la ASCII dar biblioteca de conversie nu este disponibilă în versiunea Android</string>
<string name="i2ptunnel_type_client">Client standard</string>
<string name="i2ptunnel_type_httpclient">Client HTTP</string>
<string name="i2ptunnel_type_ircclient">Client IRC</string>
<string name="i2ptunnel_type_server">Server standard</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_ircserver">Server IRC</string>
<string name="i2ptunnel_new_tunnel">Tunel nou</string>
<string name="i2ptunnel_msg_config_saved">Modificările configurării s-au salvat</string>
<string name="i2ptunnel_msg_config_save_failed">A eșuat salvarea configurării</string>
<string name="i2ptunnel_msg_tunnel_starting">Se pornește tunelul</string>
<string name="i2ptunnel_msg_tunnel_stopping">Se oprește tunelul</string>
<string name="i2ptunnel_delete_confirm_message">Se șterge tunelul?</string>
<string name="i2ptunnel_delete_confirm_button">Șterge tunelul</string>
<string name="i2ptunnel_wizard_k_client_server">Client sau server</string>
<string name="i2ptunnel_wizard_k_type">Tip tunel</string>
<string name="i2ptunnel_wizard_k_name">Nume</string>
<string name="i2ptunnel_wizard_k_desc">Descriere</string>
<string name="i2ptunnel_wizard_k_dest">Destinatie</string>
@ -113,6 +140,12 @@
<string name="i2ptunnel_wizard_k_auto_start">Auto pornire</string>
<string name="next">Urmatorul</string>
<string name="prev">Anteriorul</string>
<string name="finish">Trimite</string>
<string name="enabled">Activat</string>
<string name="i2ptunnel_wizard_desc_name">Numele tunelului, pentru identificare în lista tunelurilor.</string>
<string name="i2ptunnel_wizard_desc_desc">O descriere a tunelului. Este facultativ și pur informativ.</string>
<string name="i2ptunnel_wizard_desc_reachable_on">Aceasta limitează ce computere sau smartphone-uri pot accesa acest tunel.</string>
<string name="i2ptunnel_wizard_desc_auto_start">Ar trebui ca tunelul să pornească automat când ruterul pornește?</string>
<string name="i2ptunnel_wizard_submit_confirm_message">Se creează tunelul?</string>
<string name="i2ptunnel_wizard_submit_confirm_button">Creare tunel</string>
<string name="i2ptunnel_view_type">Tip:</string>
@ -120,4 +153,10 @@
<string name="i2ptunnel_view_target">Tinta:</string>
<string name="i2ptunnel_view_access_point">Punct de acces:</string>
<string name="i2ptunnel_view_autostart">Auto pornire</string>
<string name="copy_logs">Copiază jurnale</string>
<string name="i2p_android_error_logs">Jurnale eroare I2P Android</string>
<string name="i2p_android_logs">Jurnale I2P Android</string>
<string name="error_logs_copied_to_clipboard">Jurnalele de eroare sunt copiate în memoria temporară</string>
<string name="logs_copied_to_clipboard">Jurnalele sunt copiate în memoria temporară</string>
<string name="label_browser_configuration">Configurare navigator web</string>
</resources>

View File

@ -118,6 +118,7 @@
<string name="about_volunteer">Хотите помочь улучшить приложение? Добровольцы на Android форуме:</string>
<string name="about_donate">Хотите пожертвовать деньги или bitcoins на покупку дополнительных Android устройств для разработчиков и тестировщиков? Зайдите:</string>
<string name="menu_help">Справка</string>
<string name="general">Общие</string>
<string name="addressbook_search_header">%s найдено</string>
<string name="addressbook_add_wizard_k_name">Имя</string>
<string name="addressbook_add_wizard_k_destination">Пункт назначения</string>
@ -140,6 +141,8 @@
<string name="i2ptunnel_type_streamrclient">Streamr клиент</string>
<string name="i2ptunnel_type_streamrserver">Streamr сервер</string>
<string name="i2ptunnel_type_httpbidirserver">HTTP bidir</string>
<string name="install_recommended_app">Установить рекомендованное приложение?</string>
<string name="app_needed_for_this_tunnel_type">Требуется установить приложение для использования этого туннеля. Хотите установить рекомендованное приложение?</string>
<string name="i2ptunnel_not_initialized">Туннели еще не инициализированы, пожалуйста, обновите через пару минут</string>
<string name="i2ptunnel_new_tunnel">Создать туннель</string>
<string name="i2ptunnel_msg_config_saved">Изменения конфигурации сохранены</string>

Some files were not shown because too many files have changed in this diff Show More