Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e558c45139 | ||
|
|
a2284de509 | ||
|
|
a61fe817ca | ||
|
|
15349b3d23 | ||
|
|
6eea640647 | ||
|
|
91864f76e4 | ||
|
|
3c303ff760 | ||
|
|
dec4f81faa | ||
|
|
3e691e6aef | ||
|
|
66ae1ddc8d | ||
|
|
d757f45e8b | ||
|
|
374acf1c70 | ||
|
|
b1ab14f311 | ||
|
|
d65a021536 | ||
|
|
8e61320225 | ||
|
|
ef698102f1 | ||
|
|
47e417158f | ||
|
|
65d3986257 | ||
|
|
c350baa863 | ||
|
|
4222a5d2c6 | ||
|
|
718bcebf20 | ||
|
|
c6d3370dd3 | ||
|
|
f03e1d7948 | ||
|
|
cff047c4cb | ||
|
|
7a3a9047e6 | ||
|
|
7edd960d47 | ||
|
|
46a5a8a25a | ||
|
|
a3f2c23a3c | ||
|
|
aaee3fbd9b | ||
|
|
b80608be98 | ||
|
|
531440d5a9 | ||
|
|
be8657433e | ||
|
|
c5af9a735b | ||
|
|
3a582c4534 | ||
|
|
bd3d27f883 | ||
|
|
601cfff788 | ||
|
|
2fec3e3cb8 | ||
|
|
c4725a9b17 | ||
|
|
70bec8e980 | ||
|
|
0d0341fd62 | ||
|
|
b49bdda7e8 |
13
.gitmodules
vendored
@@ -1,13 +1,12 @@
|
||||
[submodule "dav4android"]
|
||||
path = dav4android
|
||||
url = https://gitlab.com/bitfireAT/dav4android.git
|
||||
url = ../dav4android.git
|
||||
[submodule "ical4android"]
|
||||
path = ical4android
|
||||
url = https://gitlab.com/bitfireAT/ical4android.git
|
||||
url = ../ical4android.git
|
||||
[submodule "vcard4android"]
|
||||
path = vcard4android
|
||||
url = https://gitlab.com/bitfireAT/vcard4android.git
|
||||
[submodule "MemorizingTrustManager"]
|
||||
path = MemorizingTrustManager
|
||||
url = https://github.com/ge0rg/MemorizingTrustManager
|
||||
ignore = dirty
|
||||
url = ../vcard4android.git
|
||||
[submodule "cert4android"]
|
||||
path = cert4android
|
||||
url = ../cert4android.git
|
||||
|
||||
@@ -13,6 +13,7 @@ Help and discussion: [DAVdroid forums](https://davdroid.bitfire.at/forums)
|
||||
|
||||
Parts of DAVdroid have been outsourced into these libraries:
|
||||
|
||||
* [cert4android](https://gitlab.com/bitfireAT/cert4android) – custom certificate management
|
||||
* [dav4android](https://gitlab.com/bitfireAT/dav4android) – WebDAV/CalDav/CardDAV framework
|
||||
* [ical4android](https://gitlab.com/bitfireAT/ical4android) – iCalendar processing and Calendar Provider access
|
||||
* [vcard4android](https://gitlab.com/bitfireAT/vcard4android) – VCard processing and Contacts Provider access
|
||||
@@ -28,7 +29,6 @@ Those libraries are used by DAVdroid (alphabetically):
|
||||
* [dnsjava](http://www.xbill.org/dnsjava/) – [BSD License](http://www.xbill.org/dnsjava/dnsjava-current/LICENSE)
|
||||
* [ez-vcard](https://code.google.com/p/ez-vcard/) – [New BSD License](http://opensource.org/licenses/BSD-3-Clause)
|
||||
* [iCal4j](http://ical4j.sourceforge.net/) – [New BSD License](http://sourceforge.net/p/ical4j/ical4j/ci/default/tree/LICENSE)
|
||||
* [MemorizingTrustManager](https://github.com/ge0rg/MemorizingTrustManager) – [MIT License](https://raw.githubusercontent.com/ge0rg/MemorizingTrustManager/master/LICENSE.txt)
|
||||
* [okhttp](https://square.github.io/okhttp/) – [Apache License, Version 2.0](https://square.github.io/okhttp/#license)
|
||||
* [Project Lombok](http://projectlombok.org/) – [MIT License](http://opensource.org/licenses/mit-license.php)
|
||||
* [SLF4J](http://www.slf4j.org/) – [MIT License](http://www.slf4j.org/license.html)
|
||||
|
||||
@@ -9,26 +9,50 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.3"
|
||||
compileSdkVersion 24
|
||||
buildToolsVersion '24.0.2'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "at.bitfire.davdroid"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 23
|
||||
|
||||
versionCode 109
|
||||
resValue "string", "packageID", applicationId
|
||||
|
||||
versionCode 118
|
||||
buildConfigField "long", "buildTime", System.currentTimeMillis() + "L"
|
||||
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 24
|
||||
|
||||
buildConfigField "boolean", "customCerts", "false"
|
||||
buildConfigField "at.bitfire.vcard4android.GroupMethod", "settingContactGroupMethod", "null"
|
||||
buildConfigField "Boolean", "settingVCardRFC6868", "null"
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
standard {
|
||||
versionName "1.2"
|
||||
versionName "1.3.2"
|
||||
buildConfigField "boolean", "customCerts", "true"
|
||||
}
|
||||
gplay {
|
||||
versionName "1.2-gplay"
|
||||
versionName "1.3.2-gplay"
|
||||
buildConfigField "boolean", "customCerts", "true"
|
||||
}
|
||||
icloud {
|
||||
applicationId "at.bitfire.cloudsync"
|
||||
resValue "string", "packageID", applicationId
|
||||
|
||||
versionName "1.3.2-cloud"
|
||||
|
||||
buildConfigField "at.bitfire.vcard4android.GroupMethod", "settingContactGroupMethod", "at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS"
|
||||
buildConfigField "Boolean", "settingVCardRFC6868", "true"
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
standard.java.srcDirs = [ "src/davdroid/java" ]
|
||||
standard.res.srcDirs = [ "src/davdroid/res" ]
|
||||
|
||||
gplay.java.srcDirs = [ "src/gplay/java", "src/davdroid/java" ]
|
||||
gplay.res.srcDirs = [ "src/gplay/res", "src/davdroid/res" ]
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -64,25 +88,24 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':cert4android')
|
||||
compile project(':dav4android')
|
||||
compile project(':ical4android')
|
||||
compile project(':vcard4android')
|
||||
|
||||
compile 'com.android.support:appcompat-v7:23.+'
|
||||
compile 'com.android.support:cardview-v7:23.+'
|
||||
compile 'com.android.support:design:23.+'
|
||||
compile 'com.android.support:preference-v14:23.+'
|
||||
compile 'com.android.support:appcompat-v7:24.+'
|
||||
compile 'com.android.support:cardview-v7:24.+'
|
||||
compile 'com.android.support:design:24.+'
|
||||
compile 'com.android.support:preference-v14:24.+'
|
||||
|
||||
compile 'com.github.yukuku:ambilwarna:2.0.1'
|
||||
compile project(':MemorizingTrustManager')
|
||||
|
||||
compile 'dnsjava:dnsjava:2.1.7'
|
||||
compile 'org.apache.commons:commons-lang3:3.4'
|
||||
compile 'org.apache.commons:commons-collections4:4.1'
|
||||
provided 'org.projectlombok:lombok:1.16.8'
|
||||
|
||||
provided 'org.projectlombok:lombok:1.16.10'
|
||||
// for tests
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'com.squareup.okhttp3:mockwebserver:3.3.1'
|
||||
androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.3.1'
|
||||
testCompile 'com.squareup.okhttp3:mockwebserver:3.4.1'
|
||||
androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.4.1'
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.net.Socket;
|
||||
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import de.duenndns.ssl.MemorizingTrustManager;
|
||||
import at.bitfire.cert4android.CustomCertManager;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
|
||||
public class SSLSocketFactoryCompatTest extends InstrumentationTestCase {
|
||||
@@ -26,7 +26,7 @@ public class SSLSocketFactoryCompatTest extends InstrumentationTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
factory = new SSLSocketFactoryCompat(new MemorizingTrustManager(getInstrumentation().getTargetContext().getApplicationContext()));
|
||||
factory = new SSLSocketFactoryCompat(new CustomCertManager(getInstrumentation().getTargetContext().getApplicationContext(), true));
|
||||
server.start();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public class CollectionInfoTest extends TestCase {
|
||||
"</response>" +
|
||||
"</multistatus>"));
|
||||
|
||||
DavResource dav = new DavResource(HttpClient.create(), server.url("/"));
|
||||
DavResource dav = new DavResource(HttpClient.create(null), server.url("/"));
|
||||
dav.propfind(0, ResourceType.NAME);
|
||||
CollectionInfo info = CollectionInfo.fromDavResource(dav);
|
||||
assertEquals(CollectionInfo.Type.ADDRESS_BOOK, info.type);
|
||||
@@ -66,7 +66,7 @@ public class CollectionInfoTest extends TestCase {
|
||||
"</response>" +
|
||||
"</multistatus>"));
|
||||
|
||||
dav = new DavResource(HttpClient.create(), server.url("/"));
|
||||
dav = new DavResource(HttpClient.create(null), server.url("/"));
|
||||
dav.propfind(0, ResourceType.NAME);
|
||||
info = CollectionInfo.fromDavResource(dav);
|
||||
assertEquals(CollectionInfo.Type.CALENDAR, info.type);
|
||||
|
||||
@@ -53,11 +53,11 @@ public class DavResourceFinderTest extends InstrumentationTestCase {
|
||||
server.setDispatcher(new TestDispatcher());
|
||||
server.start();
|
||||
|
||||
credentials = new LoginCredentials(URI.create("/"), "mock", "12345", true);
|
||||
finder = new DavResourceFinder(getInstrumentation().getContext(), credentials);
|
||||
credentials = new LoginCredentials(URI.create("/"), "mock", "12345");
|
||||
finder = new DavResourceFinder(getInstrumentation().getTargetContext(), credentials);
|
||||
|
||||
client = HttpClient.create();
|
||||
client = HttpClient.addAuthentication(client, credentials.userName, credentials.password, credentials.authPreemptive);
|
||||
client = HttpClient.create(null);
|
||||
client = HttpClient.addAuthentication(client, credentials.userName, credentials.password);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,8 +129,11 @@ public class DavResourceFinderTest extends InstrumentationTestCase {
|
||||
|
||||
@Override
|
||||
public MockResponse dispatch(RecordedRequest rq) throws InterruptedException {
|
||||
if (!checkAuth(rq))
|
||||
return new MockResponse().setResponseCode(401);
|
||||
if (!checkAuth(rq)) {
|
||||
MockResponse authenticate = new MockResponse().setResponseCode(401);
|
||||
authenticate.setHeader("WWW-Authenticate", "Basic realm=\"test\"");
|
||||
return authenticate;
|
||||
}
|
||||
|
||||
String path = rq.getPath();
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,48 @@
|
||||
package at.bitfire.davdroid.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.BuildConfig;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
|
||||
public class DefaultAccountsDrawerHandler implements IAccountsDrawerHandler {
|
||||
|
||||
@Override
|
||||
public boolean onNavigationItemSelected(@NonNull Activity activity, MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.nav_about:
|
||||
activity.startActivity(new Intent(activity, AboutActivity.class));
|
||||
break;
|
||||
case R.id.nav_app_settings:
|
||||
activity.startActivity(new Intent(activity, AppSettingsActivity.class));
|
||||
break;
|
||||
case R.id.nav_twitter:
|
||||
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/davdroidapp")));
|
||||
break;
|
||||
case R.id.nav_website:
|
||||
activity.startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri));
|
||||
break;
|
||||
case R.id.nav_faq:
|
||||
activity.startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("faq/").build()));
|
||||
break;
|
||||
case R.id.nav_forums:
|
||||
activity.startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("forums/").build()));
|
||||
break;
|
||||
case R.id.nav_donate:
|
||||
if (BuildConfig.FLAVOR != App.FLAVOR_GOOGLE_PLAY)
|
||||
activity.startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("donate/").build()));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
package at.bitfire.davdroid.ui.setup;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -32,7 +35,7 @@ import at.bitfire.dav4android.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.ui.widget.EditPassword;
|
||||
|
||||
public class LoginCredentialsFragment extends Fragment implements CompoundButton.OnCheckedChangeListener {
|
||||
public class DefaultLoginCredentialsFragment extends Fragment implements CompoundButton.OnCheckedChangeListener {
|
||||
|
||||
RadioButton radioUseEmail;
|
||||
LinearLayout emailDetails;
|
||||
@@ -43,9 +46,9 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
|
||||
LinearLayout urlDetails;
|
||||
EditText editBaseURL, editUserName;
|
||||
EditPassword editUrlPassword;
|
||||
CheckBox checkPreemptiveAuth;
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.login_credentials_fragment, container, false);
|
||||
@@ -60,13 +63,35 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
|
||||
editBaseURL = (EditText)v.findViewById(R.id.base_url);
|
||||
editUserName = (EditText)v.findViewById(R.id.user_name);
|
||||
editUrlPassword = (EditPassword)v.findViewById(R.id.url_password);
|
||||
checkPreemptiveAuth = (CheckBox)v.findViewById(R.id.preemptive_auth);
|
||||
|
||||
radioUseEmail.setOnCheckedChangeListener(this);
|
||||
radioUseURL.setOnCheckedChangeListener(this);
|
||||
|
||||
if (savedInstanceState == null)
|
||||
radioUseEmail.setChecked(true);
|
||||
if (savedInstanceState == null) {
|
||||
// first call
|
||||
|
||||
Activity activity = getActivity();
|
||||
Intent intent = (activity != null) ? activity.getIntent() : null;
|
||||
if (intent != null) {
|
||||
// we've got initial login data
|
||||
String url = intent.getStringExtra(LoginActivity.EXTRA_URL),
|
||||
username = intent.getStringExtra(LoginActivity.EXTRA_USERNAME),
|
||||
password = intent.getStringExtra(LoginActivity.EXTRA_PASSWORD);
|
||||
|
||||
if (url != null) {
|
||||
radioUseURL.setChecked(true);
|
||||
editBaseURL.setText(url);
|
||||
editUserName.setText(username);
|
||||
editUrlPassword.setText(password);
|
||||
} else {
|
||||
radioUseEmail.setChecked(true);
|
||||
editEmailAddress.setText(username);
|
||||
editEmailPassword.setText(password);
|
||||
}
|
||||
|
||||
} else
|
||||
radioUseEmail.setChecked(true);
|
||||
}
|
||||
|
||||
final Button login = (Button)v.findViewById(R.id.login);
|
||||
login.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -114,7 +139,7 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
|
||||
valid = false;
|
||||
}
|
||||
|
||||
return valid ? new LoginCredentials(uri, email, password, true) : null;
|
||||
return valid ? new LoginCredentials(uri, email, password) : null;
|
||||
|
||||
} else if (radioUseURL.isChecked()) {
|
||||
URI uri = null;
|
||||
@@ -159,10 +184,20 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
|
||||
valid = false;
|
||||
}
|
||||
|
||||
return valid ? new LoginCredentials(uri, userName, password, checkPreemptiveAuth.isChecked()) : null;
|
||||
return valid ? new LoginCredentials(uri, userName, password) : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static class Factory implements ILoginCredentialsFragment {
|
||||
|
||||
@Override
|
||||
public Fragment getFragment() {
|
||||
return new DefaultLoginCredentialsFragment();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
5
app/src/davdroid/res/drawable/ic_settings_action.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<vector android:alpha="0.54" android:height="24dp"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||
</vector>
|
||||
@@ -94,13 +94,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/login_password"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/preemptive_auth"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/login_auth_preemptive"
|
||||
android:checked="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RadioGroup>
|
||||
@@ -14,9 +14,9 @@
|
||||
<!--AddAccountActivity-->
|
||||
<string name="login_type_email">Entra amb una adreça de correu electrònic</string>
|
||||
<string name="login_type_url">Entra amb una URL i un nom d\'usuari</string>
|
||||
<string name="login_auth_preemptive">Autentificació preferent (recomanat però incompatible amb l\'autentificació Digest)</string>
|
||||
<!--AccountSettingsActivity-->
|
||||
<!--collection management-->
|
||||
<!--ExceptionInfoFragment-->
|
||||
<!--sync errors and DebugInfoActivity-->
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">Chvíli strpení ...</string>
|
||||
<string name="send">Odeslat</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Optimalizace využití baterie</string>
|
||||
<string name="startup_battery_optimization_message">Android může po několika dnech vypnout/prodloužit interval synchronizování DAVdroid. Chcete-li tomuto zabránit, vypněte optimalizaci baterie.</string>
|
||||
<string name="startup_battery_optimization_disable">Vypnout pro DAVdroid</string>
|
||||
<string name="startup_dont_show_again">Již nezobrazovat</string>
|
||||
<string name="startup_development_version">DAVdroid preview vydání</string>
|
||||
<string name="startup_development_version_message">Toto je vývojová verze aplikace DAVdroid. Mějte na paměti, že vše nemusí správně fungovat. Budeme rádi za konstruktivní zpětnou vazbu, která pomůže vylepšit DAVdroid.</string>
|
||||
@@ -54,13 +57,12 @@
|
||||
<string name="app_settings_reset_hints_summary">Znovu povolí vypnuté texty nápovědy</string>
|
||||
<string name="app_settings_reset_hints_success">Budou zobrazovány všechny texty nápovědy</string>
|
||||
<string name="app_settings_security">Zabezpečení</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Resetovat důvěryhodné certifikáty</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Zapomene všechny dříve akceptované certifikáty</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Znedůvěryhodněn jeden certifikát</item>
|
||||
<item quantity="few">Znedůvěryhodněny %d certifikáty</item>
|
||||
<item quantity="other">Znedůvěryhodněno %d certifikátů</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">Nedůvěřovat systémovým certifikátům</string>
|
||||
<string name="app_settings_distrust_system_certs_on">Systémovým a uživatelem přidaným CA nebude důvěřováno</string>
|
||||
<string name="app_settings_distrust_system_certs_off">Systémovým a uživatelem přidaným CA bude důvěřováno (doporučeno)</string>
|
||||
<string name="app_settings_reset_certificates">Resetovat (ne)důvěryhodné certifikáty</string>
|
||||
<string name="app_settings_reset_certificates_summary">Resetovat důvěryhodnost všech vlastních certifikátů</string>
|
||||
<string name="app_settings_reset_certificates_success">Všechny vlastní certifikáty byly resetovány</string>
|
||||
<string name="app_settings_debug">Ladění</string>
|
||||
<string name="app_settings_log_to_external_storage">Logovat do externího souboru</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Logování do externího úložiště (pokud dostupné)</string>
|
||||
@@ -102,7 +104,6 @@
|
||||
<string name="login_user_name">Uživatelské jméno</string>
|
||||
<string name="login_user_name_required">Vyžadováno uživatelské jméno</string>
|
||||
<string name="login_base_url">Základní URL</string>
|
||||
<string name="login_auth_preemptive">Preemptivní ověření (doporučeno, ale není kompatibilní s Digest ověřením)</string>
|
||||
<string name="login_login">Login</string>
|
||||
<string name="login_back">Zpět</string>
|
||||
<string name="login_create_account">Vytvořit účet</string>
|
||||
@@ -123,9 +124,6 @@
|
||||
<string name="settings_password">Heslo</string>
|
||||
<string name="settings_password_summary">Aktualizovat heslo dle svého serveru.</string>
|
||||
<string name="settings_enter_password">Vložit své heslo:</string>
|
||||
<string name="settings_preemptive">Preemptivní ověření</string>
|
||||
<string name="settings_preemptive_on">Přihlašovací údaje jsou zasílány s každým požadavkem (doporučeno)</string>
|
||||
<string name="settings_preemptive_off">Přihlašovací údaje jsou zasílány po vyžádání serverem</string>
|
||||
<string name="settings_sync">Synchronizace</string>
|
||||
<string name="settings_sync_interval_contacts">Interval synchronizace kontaktů</string>
|
||||
<string name="settings_sync_summary_manually">Pouze manuálně</string>
|
||||
@@ -239,4 +237,7 @@
|
||||
<item>ukládání stavu synchronizace</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Chybné uživatelské jméno/heslo</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: Zabezpečení připojení</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">DAVdroid nalezl neznámý certifikát. Chcete mu důvěřovat?</string>
|
||||
</resources>
|
||||
@@ -54,12 +54,6 @@
|
||||
<string name="app_settings_reset_hints_summary">Genaktiverer hjælp, som er blevet lukket tidligere</string>
|
||||
<string name="app_settings_reset_hints_success">Al vejledning vil blive vist igen</string>
|
||||
<string name="app_settings_security">Sikkerhed</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Nulstil verificerede certifikater</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Glemmer alle certifikater, der er blevet godkendt tidligere</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Ikke-accepteret certifikat</item>
|
||||
<item quantity="other">%d kke-accepterede certifikater</item>
|
||||
</plurals>
|
||||
<string name="app_settings_debug">Debugging</string>
|
||||
<string name="app_settings_log_to_external_storage">Log til ekstern fil</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Logger til eksternt lager (hvis muligt)</string>
|
||||
@@ -101,7 +95,6 @@
|
||||
<string name="login_user_name">Brugernavn</string>
|
||||
<string name="login_user_name_required">Brugernavn påkrævet</string>
|
||||
<string name="login_base_url">Basis-URL</string>
|
||||
<string name="login_auth_preemptive">Forhåndsgodkendelse (preemptive authentication - anbefalet, men ikke kompatiblelt med Digest auth)</string>
|
||||
<string name="login_login">Login</string>
|
||||
<string name="login_back">Tilbage</string>
|
||||
<string name="login_create_account">Opret konto</string>
|
||||
@@ -122,9 +115,6 @@
|
||||
<string name="settings_password">Adgangskode</string>
|
||||
<string name="settings_password_summary">Opdater adgangskoden, så den svarer til din server.</string>
|
||||
<string name="settings_enter_password">Indtast adgangskode:</string>
|
||||
<string name="settings_preemptive">Forhåndsgodkendelse</string>
|
||||
<string name="settings_preemptive_on">Loginoplysninger sendes ved hver anmodning (anbefalet)</string>
|
||||
<string name="settings_preemptive_off">Loginoplysninger sendes efter server anmoder om dem</string>
|
||||
<string name="settings_sync">Synkronisering</string>
|
||||
<string name="settings_sync_interval_contacts">Synkroniseringsinterval for kontakter</string>
|
||||
<string name="settings_sync_summary_manually">Kun manuelt</string>
|
||||
@@ -237,4 +227,5 @@
|
||||
<item>gemmer synkroniseringsstatus</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Fejl i brugernavn/adgangskode</string>
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">Por favor, espere...</string>
|
||||
<string name="send">Enviar</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Optimización de batería</string>
|
||||
<string name="startup_battery_optimization_message">Android puede desactivar/reducir la sincronización de DAVdroid después de unos días. Para prevenir esto, desactiva la optimización.</string>
|
||||
<string name="startup_battery_optimization_disable">Apagar para DAVdroid</string>
|
||||
<string name="startup_dont_show_again">No mostrar de nuevo</string>
|
||||
<string name="startup_development_version">Versión candidata final de DAVdroid</string>
|
||||
<string name="startup_development_version_message">Esta es una versión de desarrollo de DAVdroid. Tenga presente que puede que no todo funcione como espera. Por favor, denos una retroalimentación constructiva para mejorar DAVdroid.</string>
|
||||
@@ -43,7 +46,7 @@
|
||||
<string name="navigation_drawer_faq">Preguntas frequentes</string>
|
||||
<string name="navigation_drawer_forums">Comunidad</string>
|
||||
<string name="navigation_drawer_donate">Donar</string>
|
||||
<string name="account_list_empty">Bienvenido a DAVdroid!\n\nAhora puede añadir una cuenta CalDAV/CardDAV.</string>
|
||||
<string name="account_list_empty">Bienvenido a DAVdroid!\n\nAhora puedes añadir una cuenta CalDAV/CardDAV.</string>
|
||||
<!--DavService-->
|
||||
<string name="dav_service_refresh_failed">Falló la detección del servicio</string>
|
||||
<string name="dav_service_refresh_couldnt_refresh">No se pudo refrescar lista de colección</string>
|
||||
@@ -51,15 +54,15 @@
|
||||
<string name="app_settings">Ajustes</string>
|
||||
<string name="app_settings_user_interface">Interfaz de usuario</string>
|
||||
<string name="app_settings_reset_hints">Restablecer advertencias</string>
|
||||
<string name="app_settings_reset_hints_summary">Habilita las advertencias que han sido cesadas con anterioridad</string>
|
||||
<string name="app_settings_reset_hints_success">Todas las advertencias serán mostradas de nuevo</string>
|
||||
<string name="app_settings_reset_hints_summary">Habilita las advertencias que han sido rechazadas con anterioridad</string>
|
||||
<string name="app_settings_reset_hints_success">Todas las advertencias se mostrarán nuevamente</string>
|
||||
<string name="app_settings_security">Seguridad</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Restablecer certificados de confianza</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Olvidar todos los certificados aceptados previamente</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Retirada la confianza de un certificado</item>
|
||||
<item quantity="other">Retirada la confianza de %d certificados</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">Invalidar los certificados del sistema</string>
|
||||
<string name="app_settings_distrust_system_certs_on">Los CA del sistema y los añadidos por el usuario no serán válidos</string>
|
||||
<string name="app_settings_distrust_system_certs_off">Los CA del sistema y los añadidos por el usuario serán usados y de confianza (recomendado)</string>
|
||||
<string name="app_settings_reset_certificates">Reiniciar certificados (in)validados</string>
|
||||
<string name="app_settings_reset_certificates_summary">Reinicia la validez de todos los certificados particulares</string>
|
||||
<string name="app_settings_reset_certificates_success">Todos los certificados particulares han sido limpiados</string>
|
||||
<string name="app_settings_debug">Depuración</string>
|
||||
<string name="app_settings_log_to_external_storage">Registrar en fichero externo</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Registro en almacenamiento externo (si está disponible)</string>
|
||||
@@ -71,8 +74,8 @@
|
||||
<string name="account_synchronizing_now">Sincronizando...</string>
|
||||
<string name="account_settings">Ajustes de cuenta</string>
|
||||
<string name="account_delete">Eliminar cuenta</string>
|
||||
<string name="account_delete_confirmation_title">¿Seguro que desea eliminar la cuenta?</string>
|
||||
<string name="account_delete_confirmation_text">Todas las copias locales de sus contactos, calendarios y tareas serán eliminadas.</string>
|
||||
<string name="account_delete_confirmation_title">¿Seguro que deseas eliminar la cuenta?</string>
|
||||
<string name="account_delete_confirmation_text">Todas las copias locales de tus contactos, calendarios y tareas serán eliminadas.</string>
|
||||
<string name="account_refresh_address_book_list">Refrescar contactos</string>
|
||||
<string name="account_create_new_address_book">Crear nueva lista de contactos</string>
|
||||
<string name="account_refresh_calendar_list">Refrescar calendario</string>
|
||||
@@ -80,13 +83,13 @@
|
||||
<!--PermissionsActivity-->
|
||||
<string name="permissions_title">Permisos de DAVdroid</string>
|
||||
<string name="permissions_calendar">Permisos de calendario</string>
|
||||
<string name="permissions_calendar_details">Para sincronizar eventos CalDAV con sus calendarios locales, DAVdroid necesita acceder a los mismos.</string>
|
||||
<string name="permissions_calendar_details">Para sincronizar eventos CalDAV con tus calendarios locales, DAVdroid necesita acceder a los mismos.</string>
|
||||
<string name="permissions_calendar_request">Solicitar permisos sobre calendario</string>
|
||||
<string name="permissions_contacts">Permisos de contactos</string>
|
||||
<string name="permissions_contacts_details">Para sincronizar libretas de contactos CadDAV con sus contactos locales, DAVdroid necesita acceder a los mismos.</string>
|
||||
<string name="permissions_contacts_details">Para sincronizar libretas de contactos CadDAV con tus contactos locales, DAVdroid necesita acceder a los mismos.</string>
|
||||
<string name="permissions_contacts_request">Solicitar permisos sobre contactos</string>
|
||||
<string name="permissions_opentasks">Permisos de OpenTasks</string>
|
||||
<string name="permissions_opentasks_details">Para sincronizar listas de tareas CalDAV con sus listas de tareas locales, DAVdroid necesita acceder a OpenTasks.</string>
|
||||
<string name="permissions_opentasks_details">Para sincronizar listas de tareas CalDAV con tus listas de tareas locales, DAVdroid necesita acceder a OpenTasks.</string>
|
||||
<string name="permissions_opentasks_request">Solicitar permisos sobre OpenTasks</string>
|
||||
<!--AddAccountActivity-->
|
||||
<string name="login_title">Añadir cuenta</string>
|
||||
@@ -101,17 +104,17 @@
|
||||
<string name="login_user_name">Nombre de usuario</string>
|
||||
<string name="login_user_name_required">Nombre de usuario requerido</string>
|
||||
<string name="login_base_url">URL base</string>
|
||||
<string name="login_auth_preemptive">Autenticación preferente (recomendado, pero incompatible con Digest auth)</string>
|
||||
<string name="login_login">Registrar</string>
|
||||
<string name="login_back">Volver</string>
|
||||
<string name="login_create_account">Crear cuenta</string>
|
||||
<string name="login_account_name">Nombre de cuenta</string>
|
||||
<string name="login_account_name_info">Use su dirección de correo como nombre de su cuenta puesto que Android usará el nombre de la cuenta como campo de \"organizador\" en los eventos que cree. No puede tener dos cuentas con el mismo nombre.</string>
|
||||
<string name="login_account_name_info">Usa tu dirección de correo como nombre de cuenta puesto que Android usará el nombre de la cuenta como campo de \"organizador\" en los eventos que cree. No puedes tener dos cuentas con el mismo nombre.</string>
|
||||
<string name="login_account_contact_group_method">Método de contacto de grupo:</string>
|
||||
<string name="login_account_name_required">Nombre de cuenta requerido</string>
|
||||
<string name="login_account_not_created">La cuenta no pudo ser creada</string>
|
||||
<string name="login_configuration_detection">Detectar configuración</string>
|
||||
<string name="login_querying_server">Por favor espere, consultando al servidor...</string>
|
||||
<string name="login_no_caldav_carddav">No se pudo encontrar servicio CalDAV o CardDAV.</string>
|
||||
<string name="login_querying_server">Por favor espera, consultando al servidor...</string>
|
||||
<string name="login_no_caldav_carddav">No se pudo encontrar el servicio CalDAV o CardDAV.</string>
|
||||
<string name="login_view_logs">Ver registros</string>
|
||||
<!--AccountSettingsActivity-->
|
||||
<string name="settings_title">Ajustes: %s</string>
|
||||
@@ -121,9 +124,6 @@
|
||||
<string name="settings_password">Contraseña</string>
|
||||
<string name="settings_password_summary">Actualiza la contraseña de acuerdo a tu servidor.</string>
|
||||
<string name="settings_enter_password">Introduce tu contraseña:</string>
|
||||
<string name="settings_preemptive">Autenticación preferente</string>
|
||||
<string name="settings_preemptive_on">Las credenciales se envían en cada petición (recomendado)</string>
|
||||
<string name="settings_preemptive_off">Las credenciales se envían después de que el servidor las pida</string>
|
||||
<string name="settings_sync">Sincronización</string>
|
||||
<string name="settings_sync_interval_contacts">Intervalo de sincronización de contactos</string>
|
||||
<string name="settings_sync_summary_manually">Solo manualmente</string>
|
||||
@@ -153,11 +153,24 @@
|
||||
</string-array>
|
||||
<string name="settings_sync_wifi_only">Sincronizar sólo sobre WiFi</string>
|
||||
<string name="settings_sync_wifi_only_on">La sincronización está restringida a conexiones WiFi</string>
|
||||
<string name="settings_sync_wifi_only_off">Tipo de conexión no tomada en consideración</string>
|
||||
<string name="settings_sync_wifi_only_off">Tipo de conexión no tenido en cuenta</string>
|
||||
<string name="settings_sync_wifi_only_ssid">Restricción WiFi SSID</string>
|
||||
<string name="settings_sync_wifi_only_ssid_on">Sólo se sincronizará sobre %s</string>
|
||||
<string name="settings_sync_wifi_only_ssid_off">Todas las conexiones WiFi pueden ser usadas</string>
|
||||
<string name="settings_sync_wifi_only_ssid_message">Introduzca el nombre de una red WiFi (SSID) para restringir la sincronización a esta red, o deje el campo en blanco para usar todas las conexiones WiFi.</string>
|
||||
<string name="settings_sync_wifi_only_ssid_message">Introduce el nombre de una red WiFi (SSID) para restringir la sincronización a esta red, o deja el campo en blanco para usar todas las conexiones WiFi.</string>
|
||||
<string name="settings_carddav">CardDAV</string>
|
||||
<string name="settings_contact_group_method">Método de contacto de grupo</string>
|
||||
<string-array name="settings_contact_group_method_values">
|
||||
<item>GROUP_VCARDS</item>
|
||||
<item>CATEGORIAS</item>
|
||||
</string-array>
|
||||
<string-array name="settings_contact_group_method_entries">
|
||||
<item>Los groups tienen VCards separadas</item>
|
||||
<item>Los groups tienen una categoría por contacto</item>
|
||||
</string-array>
|
||||
<string name="settings_rfc6868_for_vcards">Usar RFC6868 para VCards</string>
|
||||
<string name="settings_rfc6868_for_vcards_on">Las comillas dobles se pueden usar en los valores de los parámetros</string>
|
||||
<string name="settings_rfc6868_for_vcards_off">Las comillas dobles no se pueden usar en los valores de los parámetros</string>
|
||||
<string name="settings_caldav">CalDAV</string>
|
||||
<string name="settings_sync_time_range_past">Límite de tiempo de eventos pasados</string>
|
||||
<string name="settings_sync_time_range_past_none">Todos los eventos serán sincronizados</string>
|
||||
@@ -165,7 +178,7 @@
|
||||
<item quantity="one">Los eventos anteriores a un día serán ignorados</item>
|
||||
<item quantity="other">Los eventos anteriores a %d días serán ignorados</item>
|
||||
</plurals>
|
||||
<string name="settings_sync_time_range_past_message">Los eventos anteriores a este número de días serán ignorados (puede ser 0). Deje en blanco el campo para sincronizar todos los eventos.</string>
|
||||
<string name="settings_sync_time_range_past_message">Los eventos anteriores a este número de días serán ignorados (puede ser 0). Deja en blanco el campo para sincronizar todos los eventos.</string>
|
||||
<string name="settings_manage_calendar_colors">Colores de calendario</string>
|
||||
<string name="settings_manage_calendar_colors_on">Los colores de los calendarios son administrados por DAVdroid</string>
|
||||
<string name="settings_manage_calendar_colors_off">Los colores de los calendarios no son establecidos por DAVdroid</string>
|
||||
@@ -190,7 +203,7 @@
|
||||
<string name="create_collection_home_set">Establecer localización:</string>
|
||||
<string name="create_collection_create">Crear</string>
|
||||
<string name="delete_collection">Eliminar colección</string>
|
||||
<string name="delete_collection_confirm_title">¿Está seguro/a?</string>
|
||||
<string name="delete_collection_confirm_title">¿Estás seguro/a?</string>
|
||||
<string name="delete_collection_confirm_warning">Esta colección (%s) y toda su información será eliminada del servidor.</string>
|
||||
<string name="delete_collection_deleting_collection">Eliminando colección</string>
|
||||
<!--ExceptionInfoFragment-->
|
||||
@@ -208,5 +221,22 @@
|
||||
<string name="sync_error">Error al %s</string>
|
||||
<string name="sync_error_http_dav">Error de servidor al %s</string>
|
||||
<string name="sync_error_local_storage">Error de base de datos al %s</string>
|
||||
<string-array name="sync_error_phases">
|
||||
<item>preparando sincronización</item>
|
||||
<item>buscando capacidades</item>
|
||||
<item>procesando entradas borradas localmente</item>
|
||||
<item>preparando entradas creadas/modificadas</item>
|
||||
<item>cargando entradas creadas/modificadas</item>
|
||||
<item>comprobando estado de sincronización</item>
|
||||
<item>enumerando entradas locales</item>
|
||||
<item>enumerando entradas remotas</item>
|
||||
<item>comparando entradas locales/remotas</item>
|
||||
<item>descargando entradas remotas</item>
|
||||
<item>post-procesando</item>
|
||||
<item>guardando estado de sincronización</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Nombre de usuario/contraseña erróneo</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: Seguridad de conexión</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">DAVdroid ha encontrado un certificado desconocido. ¿Quieres que sea válido?</string>
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">SVP attendez ...</string>
|
||||
<string name="send">Envoyer</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Optimisation de la batterie</string>
|
||||
<string name="startup_battery_optimization_message">Android peut désactiver/réduire la synchronisation de DAVdroid après quelques jours. Pour éviter cela, désactivez l\'optimisation de la batterie.</string>
|
||||
<string name="startup_battery_optimization_disable">Désactivez pour DAVdroid</string>
|
||||
<string name="startup_dont_show_again">Ne plus afficher</string>
|
||||
<string name="startup_development_version">Pré-version de DAVdroid</string>
|
||||
<string name="startup_development_version_message">Il s\'agit d\'une version de développement de DAVdroid. Il se peut que les choses ne fonctionnent pas comme prévu. S’il vous plaît faites-nous un retour pour améliorer DAVdroid.</string>
|
||||
@@ -53,12 +56,8 @@
|
||||
<string name="app_settings_reset_hints_summary">Réactiver les astuces qui ont été vu précédemment</string>
|
||||
<string name="app_settings_reset_hints_success">Toutes les astuces seront affichés à nouveau</string>
|
||||
<string name="app_settings_security">Sécurité</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Réinitialiser les certificats de confiance</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Oublier tous les certificats qui ont été acceptés précédemment</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Un certificat douteux</item>
|
||||
<item quantity="other">%d certificats douteux</item>
|
||||
</plurals>
|
||||
<string name="app_settings_reset_certificates_summary">Réinitialiser la confiance de tous les certificats personnalisés</string>
|
||||
<string name="app_settings_reset_certificates_success">Tous les certificats personnalisés ont été effacés</string>
|
||||
<string name="app_settings_debug">Débogage</string>
|
||||
<string name="app_settings_log_to_external_storage">Journaliser dans un fichier externe</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Journaliser sur le stockage externe (si disponible)</string>
|
||||
@@ -100,7 +99,6 @@
|
||||
<string name="login_user_name">Nom d\'utilisateur</string>
|
||||
<string name="login_user_name_required">Nom d\'utilisateur requis</string>
|
||||
<string name="login_base_url">URL de base</string>
|
||||
<string name="login_auth_preemptive">Authentification préventive (recommandé, mais incompatible avec l\'authentification Digest)</string>
|
||||
<string name="login_login">Se connecter</string>
|
||||
<string name="login_back">Retour</string>
|
||||
<string name="login_create_account">Créer un compte</string>
|
||||
@@ -120,9 +118,6 @@
|
||||
<string name="settings_password">Mot de passe</string>
|
||||
<string name="settings_password_summary">Mettre à jour le mot de passe </string>
|
||||
<string name="settings_enter_password">Saisissez votre mot de passe :</string>
|
||||
<string name="settings_preemptive">Authentification préventive</string>
|
||||
<string name="settings_preemptive_on">Le nom d\'utilisateur et le mot de passe sont envoyés avec chaque requête (recommandé)</string>
|
||||
<string name="settings_preemptive_off">Le nom d\'utilisateur et le mot de passe sont envoyés à la demande du serveur.</string>
|
||||
<string name="settings_sync">Synchronisation</string>
|
||||
<string name="settings_sync_interval_contacts">Interval de synchronisation des carnets d\'adresses</string>
|
||||
<string name="settings_sync_summary_manually">Manuellement</string>
|
||||
@@ -215,5 +210,21 @@
|
||||
<string name="sync_error">Erreur durant %s</string>
|
||||
<string name="sync_error_http_dav">Erreur de serveur durant %s</string>
|
||||
<string name="sync_error_local_storage">Erreur de base de donnée durant %s</string>
|
||||
<string-array name="sync_error_phases">
|
||||
<item>prépare la synchronisation</item>
|
||||
<item>demande les autorisations</item>
|
||||
<item>procède à la suppression des entrées locales</item>
|
||||
<item>prépare les entrées créées/modifiées</item>
|
||||
<item>envoi les entrées créées/modifiées</item>
|
||||
<item>vérifie l\'état de la synchronisation</item>
|
||||
<item>liste les entrées locales</item>
|
||||
<item>liste les entrées distantes</item>
|
||||
<item>compare les entrées locales/distantes</item>
|
||||
<item>télécharge les entrées distantes</item>
|
||||
<item>post-traitement</item>
|
||||
<item>enregistre l\'état de la synchronisation</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Nom d\'utilisateur ou mot de passe erroné</string>
|
||||
<!--cert4android-->
|
||||
<string name="trust_certificate_unknown_certificate_found">DAVdroid a rencontré un certificat inconnu. Voulez-vous lui faire confiance?</string>
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">Kérjük, várjon ...</string>
|
||||
<string name="send">Küldés</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Akkumulátoroptimalizálás </string>
|
||||
<string name="startup_battery_optimization_message">Az operációs rendszer a DAVdroid szinkronizálást pár nap után leállíthatja vagy visszafoghatja. Ennek elkerülésére kapcsolja ki az akkumulátoroptimalizálást.</string>
|
||||
<string name="startup_battery_optimization_disable">Kikapcsolás a DAVdroid kapcsán</string>
|
||||
<string name="startup_dont_show_again">Ne jelenjen meg többet</string>
|
||||
<string name="startup_development_version">DAVdroid előzetes kiadás</string>
|
||||
<string name="startup_development_version_message">Ez a DAVdroid egy fejlesztői verziója. Elképzelhető, hogy nem minden működik úgy, ahogyan kellene. Ha így lenne, kérjük küldjön a tapasztaltakról visszajelzést.</string>
|
||||
@@ -54,12 +57,12 @@
|
||||
<string name="app_settings_reset_hints_summary">Újra jelenjen meg az összes tipp</string>
|
||||
<string name="app_settings_reset_hints_success">Az összes tipp újra meg fog jelenni</string>
|
||||
<string name="app_settings_security">Biztonság</string>
|
||||
<string name="app_settings_reset_trusted_certificates">A tanúsítványtár visszaállítása</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Az összes korábban megbízhatónak kiválasztott tanúsítvány törlése</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Egy tanúsítvány megbízhatósága törölve</item>
|
||||
<item quantity="other">%d tanúsítvány megbízhatósága törölve</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">A rendszertanúsítványok elfogadása</string>
|
||||
<string name="app_settings_distrust_system_certs_on">A rendszer által kezelt, előre vagy felhasználó által telepített tanúsítványok figyelmen kívül lesznek hagyva</string>
|
||||
<string name="app_settings_distrust_system_certs_off">A rendszer által kezelt, előre vagy felhasználó által telepített tanúsítványok megbízhatóak (javasolt)</string>
|
||||
<string name="app_settings_reset_certificates">A tanúsítványok megbízhatóságának törlésére</string>
|
||||
<string name="app_settings_reset_certificates_summary">A tanúsítványok megbízhatóságával kapcsolatos beállítások törlésére</string>
|
||||
<string name="app_settings_reset_certificates_success">A tanúsítványok megbízhatóságával kapcsolatos beállítások törölve</string>
|
||||
<string name="app_settings_debug">Hibakeresés</string>
|
||||
<string name="app_settings_log_to_external_storage">Naplózás fájlba</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Naplózás külső tárhelyre (ha elérhető)</string>
|
||||
@@ -101,7 +104,6 @@
|
||||
<string name="login_user_name">Felhasználónév</string>
|
||||
<string name="login_user_name_required">A felhasználónév megadása feltétlenül szükséges</string>
|
||||
<string name="login_base_url">URL-törzs</string>
|
||||
<string name="login_auth_preemptive">Preemptív authentikáció (ajánlott, de Digest authentikációval nem működik)</string>
|
||||
<string name="login_login">Bejelentkezés</string>
|
||||
<string name="login_back">Vissza</string>
|
||||
<string name="login_create_account">Fiók létrehozása</string>
|
||||
@@ -122,9 +124,6 @@
|
||||
<string name="settings_password">Jelszó</string>
|
||||
<string name="settings_password_summary">Adja meg a szerveren érvényes új jelszót.</string>
|
||||
<string name="settings_enter_password">Adja meg a jelszót:</string>
|
||||
<string name="settings_preemptive">Preemptív authentikáció</string>
|
||||
<string name="settings_preemptive_on">A hitelesítő adatok elküldése minden kérésnél (ajánlott)</string>
|
||||
<string name="settings_preemptive_off">A hitelesítő adatok elküldése, csak ha a szerver azt igényli</string>
|
||||
<string name="settings_sync">Szinkronizálás</string>
|
||||
<string name="settings_sync_interval_contacts">Névjegyszinkronizálás sűrűsége</string>
|
||||
<string name="settings_sync_summary_manually">Manuális</string>
|
||||
@@ -161,6 +160,10 @@
|
||||
<string name="settings_sync_wifi_only_ssid_message">Adja meg a WIFI hálózat nevét (SSID) a szinkronizálás egy hálózatra való korlátozához, vagy hagyja üresen, ha nem akar ilyen szűkítést.</string>
|
||||
<string name="settings_carddav">CardDAV</string>
|
||||
<string name="settings_contact_group_method">A csoportok kezelésének módja</string>
|
||||
<string-array name="settings_contact_group_method_values">
|
||||
<item>GROUP_VCARDS</item>
|
||||
<item>CATEGORIES</item>
|
||||
</string-array>
|
||||
<string-array name="settings_contact_group_method_entries">
|
||||
<item>Minden csoport egy különálló VCard</item>
|
||||
<item>A csoportok a kapcsolatonkéni kategóriák</item>
|
||||
@@ -233,4 +236,7 @@
|
||||
<item>szinkronizációs állapot mentése</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">A felhasználónév vagy jelszó hibás</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: kapcsolatbiztonság</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">Egy eddig ismeretlen tanúsítvány érkezett. Megbízhatónak kívánja elfogadni?</string>
|
||||
</resources>
|
||||
@@ -81,4 +81,5 @@
|
||||
<string name="exception_show_details">Mostra dettagli</string>
|
||||
<!--sync errors and DebugInfoActivity-->
|
||||
<string name="sync_error_permissions">Permessi DAVdroid</string>
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">しばらくお待ちください …</string>
|
||||
<string name="send">送信</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">バッテリー最適化</string>
|
||||
<string name="startup_battery_optimization_message">Android は数日後に DAVdroid の同期を無効にする/減らすことがあります。これを防止するには、バッテリー最適化をオフにしてください。</string>
|
||||
<string name="startup_battery_optimization_disable">DAVdroid 用にオフにする</string>
|
||||
<string name="startup_dont_show_again">次回から表示しない</string>
|
||||
<string name="startup_development_version">DAVdroid プレビュー リリース</string>
|
||||
<string name="startup_development_version_message">これは DAVdroid の開発版です。期待した通りに動作しない可能性があることにご注意ください。私たちが DAVdroid を改善するために、建設的なフィードバックをお願いします。</string>
|
||||
@@ -54,11 +57,12 @@
|
||||
<string name="app_settings_reset_hints_summary">以前非表示にしたヒントを、再度有効にします</string>
|
||||
<string name="app_settings_reset_hints_success">すべてのヒントが再度表示されます</string>
|
||||
<string name="app_settings_security">セキュリティ</string>
|
||||
<string name="app_settings_reset_trusted_certificates">信頼済証明書をリセット</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">以前承認されたすべての証明書を忘れます</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="other">%d 証明書の信頼を解除しました</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">システム証明書の信頼を解除</string>
|
||||
<string name="app_settings_distrust_system_certs_on">システムとユーザーが追加したCAを信頼しない</string>
|
||||
<string name="app_settings_distrust_system_certs_off">システムとユーザーが追加したCAを信頼する (推奨)</string>
|
||||
<string name="app_settings_reset_certificates">(未)信頼済証明書をリセット</string>
|
||||
<string name="app_settings_reset_certificates_summary">すべてのカスタム証明書の信頼をリセット</string>
|
||||
<string name="app_settings_reset_certificates_success">すべてのカスタム証明書をクリアしました</string>
|
||||
<string name="app_settings_debug">デバッグ</string>
|
||||
<string name="app_settings_log_to_external_storage">外部ファイルにログ出力</string>
|
||||
<string name="app_settings_log_to_external_storage_on">(可能な場合) 外部ストレージにログ出力します</string>
|
||||
@@ -100,7 +104,6 @@
|
||||
<string name="login_user_name">ユーザー名</string>
|
||||
<string name="login_user_name_required">ユーザー名が必要です</string>
|
||||
<string name="login_base_url">ベース URL</string>
|
||||
<string name="login_auth_preemptive">プリエンプティブ認証 (推奨ですが、ダイジェスト認証と互換性がありません)</string>
|
||||
<string name="login_login">ログイン</string>
|
||||
<string name="login_back">戻る</string>
|
||||
<string name="login_create_account">アカウントを作成</string>
|
||||
@@ -121,9 +124,6 @@
|
||||
<string name="settings_password">パスワード</string>
|
||||
<string name="settings_password_summary">ご利用のサーバーに従ってパスワードを更新します。</string>
|
||||
<string name="settings_enter_password">パスワードを入力:</string>
|
||||
<string name="settings_preemptive">プリエンプティブ認証</string>
|
||||
<string name="settings_preemptive_on">すべてのリクエストで資格情報を送信します (推奨)</string>
|
||||
<string name="settings_preemptive_off">サーバーが要求した後、資格情報を送信します</string>
|
||||
<string name="settings_sync">同期</string>
|
||||
<string name="settings_sync_interval_contacts">連絡先同期間隔</string>
|
||||
<string name="settings_sync_summary_manually">手動のみ</string>
|
||||
@@ -235,4 +235,7 @@
|
||||
<item>同期の状態を保存中</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">ユーザー名/パスワードが間違っています</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: 接続セキュリティ</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">DAVdroidは、未知の証明書を検出しました。それを信頼しますか?</string>
|
||||
</resources>
|
||||
@@ -54,12 +54,6 @@
|
||||
<string name="app_settings_reset_hints_summary">Hints die al gezien zijn opnieuw weergeven</string>
|
||||
<string name="app_settings_reset_hints_success">Alle hints worden opnieuw weergegeven</string>
|
||||
<string name="app_settings_security">Beveiliging</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Vertrouwde certificaten resetten</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Vergeet alle eerder geaccepteerde certificaten</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Onbetrouwbaar certificaat</item>
|
||||
<item quantity="other">Onbetrouwbaar %d certificaten</item>
|
||||
</plurals>
|
||||
<string name="app_settings_debug">Debuggen</string>
|
||||
<string name="app_settings_log_to_external_storage">Log naar extern bestand</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Loggen naar externe opslag (wanneer beschikbaar)</string>
|
||||
@@ -101,12 +95,12 @@
|
||||
<string name="login_user_name">Gebruikersnaam</string>
|
||||
<string name="login_user_name_required">Gebruikersnaam vereist</string>
|
||||
<string name="login_base_url">Basis URL</string>
|
||||
<string name="login_auth_preemptive">Preëmptieve authenticatie (aanbevolen, maar werkt niet met Digest-auth)</string>
|
||||
<string name="login_login">Login</string>
|
||||
<string name="login_back">Terug</string>
|
||||
<string name="login_create_account">Maak een account</string>
|
||||
<string name="login_account_name">Accountnaam</string>
|
||||
<string name="login_account_name_info">Gebruik je email adres als account naam want Android zal je account naam gebruiken als ORGANIZER veld voor gemaakte afspraken. Je kunt geen 2 accounts met dezelfde naam hebben,</string>
|
||||
<string name="login_account_contact_group_method">Contact groep methode:</string>
|
||||
<string name="login_account_name_required">Accountnaam vereist</string>
|
||||
<string name="login_account_not_created">Account kon niet gemaakt worden.</string>
|
||||
<string name="login_configuration_detection">Configuratie detectie</string>
|
||||
@@ -121,9 +115,6 @@
|
||||
<string name="settings_password">Wachtwoord</string>
|
||||
<string name="settings_password_summary">Gebruik het zelfde wachtwoord als op de server.</string>
|
||||
<string name="settings_enter_password">Wachtwoord invoeren:</string>
|
||||
<string name="settings_preemptive">Preëmptieve authenticatie</string>
|
||||
<string name="settings_preemptive_on">Credentials worden met elk verzoek verzonden (aanbevolen)</string>
|
||||
<string name="settings_preemptive_off">Credentials worden alleen op aanvraag verzonden</string>
|
||||
<string name="settings_sync">Synchronisatie</string>
|
||||
<string name="settings_sync_interval_contacts">Contacten verversen</string>
|
||||
<string name="settings_sync_summary_manually">Alleen handmatig</string>
|
||||
@@ -158,6 +149,19 @@
|
||||
<string name="settings_sync_wifi_only_ssid_on">Zal alleen synchroniseren over %s</string>
|
||||
<string name="settings_sync_wifi_only_ssid_off">Alle WiFI verbindingen mogen worden gebruikt</string>
|
||||
<string name="settings_sync_wifi_only_ssid_message">Type de naam van het WiFi netwerk (SSID) om synchronisatie tot dit netwerk te beperken. Leeg laten voor sync over alle netwerken.</string>
|
||||
<string name="settings_carddav">CardDAV</string>
|
||||
<string name="settings_contact_group_method">Contact groep methode</string>
|
||||
<string-array name="settings_contact_group_method_values">
|
||||
<item>GROUP_VCARDS</item>
|
||||
<item>CATEGORIES</item>
|
||||
</string-array>
|
||||
<string-array name="settings_contact_group_method_entries">
|
||||
<item>Groepen zijn apparte VCards</item>
|
||||
<item>Groepen zijn per-contact categories</item>
|
||||
</string-array>
|
||||
<string name="settings_rfc6868_for_vcards">Gebruik RFC6868 voor VCards</string>
|
||||
<string name="settings_rfc6868_for_vcards_on">Aanhalingstekens kunnen worden gebruikt voor parameter waardes</string>
|
||||
<string name="settings_rfc6868_for_vcards_off">Aanhalingstekens kunnen niet worden gebruikt voor parameter waardes</string>
|
||||
<string name="settings_caldav">CalDAV</string>
|
||||
<string name="settings_sync_time_range_past">Tijdslimiet verleden afspraken</string>
|
||||
<string name="settings_sync_time_range_past_none">Alle afspraken worden gesynchronizeerd</string>
|
||||
@@ -208,5 +212,20 @@
|
||||
<string name="sync_error">Fout tijdens %s</string>
|
||||
<string name="sync_error_http_dav">Serverfout tijdens %s</string>
|
||||
<string name="sync_error_local_storage">Database fout tijdens %s</string>
|
||||
<string-array name="sync_error_phases">
|
||||
<item>synchronisatie voorbereiden</item>
|
||||
<item>querying mogelijkheden</item>
|
||||
<item>verwerken van lokaal verwijderde data</item>
|
||||
<item>voorberteiding maken/wijzigen data</item>
|
||||
<item>uploaden maken/bewerken data</item>
|
||||
<item>controleren syngronisatie voortgang</item>
|
||||
<item>lijst lokale data</item>
|
||||
<item>lijst remote data</item>
|
||||
<item>vergelijken lokale/remote data</item>
|
||||
<item>downloaden remote data</item>
|
||||
<item>nabewerking</item>
|
||||
<item>opslaan sync voortgang</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Gebruikersnaam/wachtwoord onjuist</string>
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -7,13 +7,19 @@
|
||||
<string name="please_wait">Proszę czekać</string>
|
||||
<string name="send">Wyślij</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Optymalizacja baterii</string>
|
||||
<string name="startup_battery_optimization_message">Android może wyłączyć/zmniejszyć synchronizacje DAVdroid po kilku dniach. Aby temu zapobiec należy wyłączyć optymalizację baterii.</string>
|
||||
<string name="startup_battery_optimization_disable">Wyłącz dla DAVdroid</string>
|
||||
<string name="startup_dont_show_again">Nie pokazuj ponownie</string>
|
||||
<string name="startup_development_version">DAVdroid Preview Release</string>
|
||||
<string name="startup_development_version_message">Jest to wersja rozwojowa DAVdroid. Należy pamiętać, że rzeczy mogą nie działać zgodnie z oczekiwaniami. Prosimy o konstruktywny informacje zwrotne, aby ulepszyć DAVdroid.</string>
|
||||
<string name="startup_development_version_give_feedback">Przekaż opinię</string>
|
||||
<string name="startup_donate">Informacje Open-Source</string>
|
||||
<string name="startup_donate_message">Jesteśmy szczęśliwi, że używasz DAVdroid, który jest oprogramowaniem open-source (GPLv3). Ponieważ rozwijanie DAVdroid jest ciężką pracą i zajęło nam tysiące godzin pracy, prosimy o rozważenie darowizny.</string>
|
||||
<string name="startup_donate_now">Pokaż stronę darowizny</string>
|
||||
<string name="startup_donate_later">Może później</string>
|
||||
<string name="startup_google_play_accounts_removed">Informacje o błędzie DRM Sklepu Play</string>
|
||||
<string name="startup_google_play_accounts_removed_message">Pod pewnymi warunkami, DRM Sklepu Play może powodować, że wszystkie konta DAVdroid mogą zostać usunięte po uruchomieniu lub po uaktualnieniu DAVdroid. Jeśli jesteś dotknięty tym problemem (i tylko wtedy) należy zainstalować \"DAVdroid JB Obejście\" ze Sklepu Play.</string>
|
||||
<string name="startup_google_play_accounts_removed_more_info">Więcej informacji</string>
|
||||
<string name="startup_opentasks_not_installed">OpenTasks nie jest zainstalowany</string>
|
||||
<string name="startup_opentasks_not_installed_message">Aplikacja Open Tasks nie jest dostępna, więc DAVdroid nie będzie mógł synchronizować listy zadań. </string>
|
||||
@@ -21,6 +27,7 @@
|
||||
<string name="startup_opentasks_not_installed_install">Zainstaluj OpenTasks</string>
|
||||
<!--AboutActivity-->
|
||||
<string name="about_license_terms">Warunki licencji</string>
|
||||
<string name="about_license_info_no_warranty">Ten program jest ABSOLUTNIE BEZ GWARANCJI. To jest wolne oprogramowanie i mile widziane jest dalsze rozpowszechnianie go pod pewnymi warunkami.</string>
|
||||
<!--global settings-->
|
||||
<string name="logging_davdroid_file_logging">Plik logów DAVdroid</string>
|
||||
<string name="logging_to_external_storage">Logowanie do zewnątrznej pamięci: %s</string>
|
||||
@@ -33,31 +40,42 @@
|
||||
<string name="navigation_drawer_subtitle">Adapter synchronizacji CalDAV/CardDAV</string>
|
||||
<string name="navigation_drawer_about">O DAVdroid / Licencja</string>
|
||||
<string name="navigation_drawer_settings">Ustawienia</string>
|
||||
<string name="navigation_drawer_news_updates">Nowości & aktualizacje
|
||||
</string>
|
||||
<string name="navigation_drawer_news_updates">Nowości & aktualizacje</string>
|
||||
<string name="navigation_drawer_external_links">Zewnętrzne odnośniki</string>
|
||||
<string name="navigation_drawer_website">Strona WWW</string>
|
||||
<string name="navigation_drawer_faq">FQA</string>
|
||||
<string name="navigation_drawer_forums">Społeczność</string>
|
||||
<string name="navigation_drawer_donate">Dotacja</string>
|
||||
<string name="account_list_empty">Witamy w DAVdroid!\n\nMożesz teraz dodać konto CalDAV/CardDAV.</string>
|
||||
<!--DavService-->
|
||||
<string name="dav_service_refresh_failed">Wykrycie serwisu nie powiodło się</string>
|
||||
<string name="dav_service_refresh_couldnt_refresh">Nie można odświeżyć listy kolekcji</string>
|
||||
<!--AppSettingsActivity-->
|
||||
<string name="app_settings">Ustawienia</string>
|
||||
<string name="app_settings_user_interface">
|
||||
Interfejs użytkownika</string>
|
||||
<string name="app_settings_user_interface">Interfejs użytkownika</string>
|
||||
<string name="app_settings_reset_hints">Zresetuj podpowiedzi</string>
|
||||
<string name="app_settings_reset_hints_summary">Ponownie włącz wskazówki, które zostały usunięte wcześniej</string>
|
||||
<string name="app_settings_reset_hints_success">Wszystkie wskazówki pojawią się ponownie</string>
|
||||
<string name="app_settings_security">Bezpieczeństwo</string>
|
||||
<string name="app_settings_distrust_system_certs">Usuń certyfikaty systemowe</string>
|
||||
<string name="app_settings_distrust_system_certs_on">CA systemowe i użytkownika nie zostaną dodane</string>
|
||||
<string name="app_settings_distrust_system_certs_off">CA systemowe i użytkownika zostaną dodane (zalecane)</string>
|
||||
<string name="app_settings_reset_certificates">Zresetuj (nie)zaufane certyfikaty</string>
|
||||
<string name="app_settings_reset_certificates_summary">Zresetuj wszystkie niestandardowe certyfikaty.</string>
|
||||
<string name="app_settings_reset_certificates_success">Wszystkie niestandardowe certyfikaty zostały wyczyszczone</string>
|
||||
<string name="app_settings_debug">Debugowanie</string>
|
||||
<string name="app_settings_log_to_external_storage">Loguj to zewnętrznego pliku</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Logowanie do zewnętrznej pamięci (jeśli jest dostępna)</string>
|
||||
<string name="app_settings_log_to_external_storage_off">Logowanie do zewnętrznego pliku jest niedostępne</string>
|
||||
<string name="app_settings_show_debug_info">Pokaż informacje do debug\'owania</string>
|
||||
<string name="app_settings_show_debug_info_details">Przeglądaj/udostępnij oprogramowanie i szczegóły konfiguracji </string>
|
||||
<!--AccountActivity-->
|
||||
<string name="account_synchronize_now">Synchronizuj teraz</string>
|
||||
<string name="account_synchronizing_now">Synchronizcja w toku</string>
|
||||
<string name="account_settings">Ustawienia konta</string>
|
||||
<string name="account_delete">Usuń konto</string>
|
||||
<string name="account_delete_confirmation_title">Naprawdę chcesz usunąć konto?</string>
|
||||
<string name="account_delete_confirmation_text">Wszystkie lokalne kopie książek adresowych, kalendarzy i list zadań zostaną usunięte.</string>
|
||||
<string name="account_refresh_address_book_list">Odśwież list książek adresowych</string>
|
||||
<string name="account_create_new_address_book">Stwórz nową książkę adresową</string>
|
||||
<string name="account_refresh_calendar_list">Odśwież liste kalendarzy</string>
|
||||
@@ -65,10 +83,13 @@ Interfejs użytkownika</string>
|
||||
<!--PermissionsActivity-->
|
||||
<string name="permissions_title">Uprawnienia DAVdroid</string>
|
||||
<string name="permissions_calendar">Uprawnienia kalendarza</string>
|
||||
<string name="permissions_calendar_details">Aby synchronizować wydarzenia CalDav z lokalnymi kalendarzami, DAVdroid potrzebuje dostępu do twoich kalendarzy.</string>
|
||||
<string name="permissions_calendar_request">Zezwól na uprawnienia kalendarza</string>
|
||||
<string name="permissions_contacts">Uprawnienia kontaktów</string>
|
||||
<string name="permissions_contacts_details">Aby synchronizować książki adresowe CardDAV z lokalnymi kontaktami, DAVdroid potrzebuje dostępu do twoich kontaktów.</string>
|
||||
<string name="permissions_contacts_request">Zezwól na uprawnienia kontaktów</string>
|
||||
<string name="permissions_opentasks">Uprawnienia OpenTasks</string>
|
||||
<string name="permissions_opentasks_details">Aby synchronizować zadania CalDav z lokalnymi listami zadań, DAVdroid potrzebuje dostępu do OpenTasks.</string>
|
||||
<string name="permissions_opentasks_request">Zezwól na uprawnienia OpenTasks</string>
|
||||
<!--AddAccountActivity-->
|
||||
<string name="login_title">Dodaj konto</string>
|
||||
@@ -78,20 +99,22 @@ Interfejs użytkownika</string>
|
||||
<string name="login_password">Hasło</string>
|
||||
<string name="login_password_required">Wymagane hasło</string>
|
||||
<string name="login_type_url">Logowanie za pomocą adresu URL i nazwy użytkownika</string>
|
||||
<string name="login_url_must_be_http_or_https">URL musi zaczynać się z http(s)://</string>
|
||||
<string name="login_url_host_name_required">Wymagana nazwa hosta</string>
|
||||
<string name="login_user_name">Nazwa użytkownika</string>
|
||||
<string name="login_user_name_required">Wymagana nazwa użtkonika</string>
|
||||
<string name="login_base_url">Podstawowy URL</string>
|
||||
<string name="login_auth_preemptive">Autoryzacja prewencyjna (zalecana, ale niezgodna z autoryzacją Digest)</string>
|
||||
<string name="login_login">Zaloguj</string>
|
||||
<string name="login_back">Wróć</string>
|
||||
<string name="login_create_account">Stwórz konto</string>
|
||||
<string name="login_account_name">Nazwa konta</string>
|
||||
<string name="login_account_name_info">Użyj swojego adresu e-mail jako nazwy konta, ponieważ Android będzie używał nazwy konta jako pola ORGANIZATOR dla wydarzeń, które stworzysz. Nie możesz posiadać dwóch kont o takiej samej nazwie.</string>
|
||||
<string name="login_account_contact_group_method">Metoda grupowania kontaktów:</string>
|
||||
<string name="login_account_name_required">Wymagana nazwa konta</string>
|
||||
<string name="login_account_not_created">Konto nie mogło zostać stworzone</string>
|
||||
<string name="login_configuration_detection">Wykrywanie konfiguracji</string>
|
||||
<string name="login_querying_server">Proszę czekać, odpytywanie serwera...</string>
|
||||
<string name="login_no_caldav_carddav">Nie można znaleźć usługi CalDAV lub CardDAV.</string>
|
||||
<string name="login_view_logs">Pokaż logi</string>
|
||||
<!--AccountSettingsActivity-->
|
||||
<string name="settings_title">Ustawienia: %s</string>
|
||||
@@ -101,9 +124,6 @@ Interfejs użytkownika</string>
|
||||
<string name="settings_password">Hasło</string>
|
||||
<string name="settings_password_summary">Zaktualizuj hasło zgodnie z serwerem.</string>
|
||||
<string name="settings_enter_password">Wpisz hasło:</string>
|
||||
<string name="settings_preemptive">Autoryzacja prewencyjna</string>
|
||||
<string name="settings_preemptive_on">Listy uwierzytelniające są wysyłane przy każdym zapytaniu (zalecane)</string>
|
||||
<string name="settings_preemptive_off">Listy uwierzytelniające są wysyłane po zapytaniu serwera o nie</string>
|
||||
<string name="settings_sync">Synchronizacja</string>
|
||||
<string name="settings_sync_interval_contacts">Okres synchronizacji kontktów</string>
|
||||
<string name="settings_sync_summary_manually">Tylko ręcznie</string>
|
||||
@@ -131,6 +151,13 @@ Interfejs użytkownika</string>
|
||||
<item>Co 4 godziny</item>
|
||||
<item>Raz dziennie</item>
|
||||
</string-array>
|
||||
<string name="settings_sync_wifi_only">Synchronizuj tylko przez WiFi</string>
|
||||
<string name="settings_sync_wifi_only_on">Synchronizacja jest ograniczony do połączeń WiFi</string>
|
||||
<string name="settings_sync_wifi_only_off">Rodzaj połączenia nie jest brany pod uwagę</string>
|
||||
<string name="settings_sync_wifi_only_ssid">Organicznie WiFi SSID</string>
|
||||
<string name="settings_sync_wifi_only_ssid_on">Będzie synchronizować tylko przez %s.</string>
|
||||
<string name="settings_sync_wifi_only_ssid_off">Wszystkie połączenia WiFi mogą zostać wykorzystane</string>
|
||||
<string name="settings_sync_wifi_only_ssid_message">Wprowadź nazwę sieci WiFi (SSID), aby ograniczyć synchronizację do tej sieci lub pozostaw puste dla wszystkich połączeń WiFi.</string>
|
||||
<string name="settings_carddav">CardDAV</string>
|
||||
<string name="settings_contact_group_method">Metoda grupowania kontaktów</string>
|
||||
<string-array name="settings_contact_group_method_values">
|
||||
@@ -138,11 +165,22 @@ Interfejs użytkownika</string>
|
||||
<item>CATEGORIES</item>
|
||||
</string-array>
|
||||
<string name="settings_rfc6868_for_vcards">Użyj RFC6868 dla VCards</string>
|
||||
<string name="settings_rfc6868_for_vcards_on">Podwójne apostrofy można stosować w wartościach parametrów</string>
|
||||
<string name="settings_rfc6868_for_vcards_off">Podwójne apostrofy nie można stosować w wartościach parametrów</string>
|
||||
<string name="settings_caldav">CalDAV</string>
|
||||
<string name="settings_sync_time_range_past">Limit czasowy przeszłych wydarzeń</string>
|
||||
<string name="settings_sync_time_range_past_none">Wszystkie wydarzenia zostaną synchronizowane</string>
|
||||
<plurals name="settings_sync_time_range_past_days">
|
||||
<item quantity="one">Wydarzenia starsze niż jeden dzień zostaną zignorowane.</item>
|
||||
<item quantity="few">Wydarzenia starsze niż %d dni zostaną zignorowane.</item>
|
||||
<item quantity="other">Wydarzenia starsze niż %d dni zostaną zignorowane.</item>
|
||||
</plurals>
|
||||
<string name="settings_sync_time_range_past_message">Wydarzenia, które są starsze niż podana liczba dni zostaną zignorowane (może być 0). Zostaw puste, aby synchronizować wszystkie wydarzenia.</string>
|
||||
<string name="settings_manage_calendar_colors">Zarządzaj kolorami kalendarza</string>
|
||||
<string name="settings_manage_calendar_colors_on">Kolory kalendarza są zarządzane przez DAVdroid</string>
|
||||
<string name="settings_manage_calendar_colors_off">Kolory kalendarze nie są ustawiane przez DAVdroid</string>
|
||||
<string name="settings_version_update">Aktualizacji wersji DAVdroid</string>
|
||||
<string name="settings_version_update_settings_updated">Ustawienia wewnętrzne zostały zaktualizowane.</string>
|
||||
<string name="settings_version_update_install_hint">Problemy? Odinstaluj DAVdroid i zainstaluj ponownie.</string>
|
||||
<!--collection management-->
|
||||
<string name="create_addressbook">Stwórz książkę adresową</string>
|
||||
@@ -180,5 +218,22 @@ Interfejs użytkownika</string>
|
||||
<string name="sync_error">Błąd podczas %s</string>
|
||||
<string name="sync_error_http_dav">Błąd servera podczas %s</string>
|
||||
<string name="sync_error_local_storage">Bład bazy danych podczas %s</string>
|
||||
<string-array name="sync_error_phases">
|
||||
<item>przygotowanie synchronizacji</item>
|
||||
<item>odpytywanie możliwości</item>
|
||||
<item>przetwarzanie lokalnie usuniętych wpisów</item>
|
||||
<item>przygotowanie stworzonych/zmodyfikowanych wpisów</item>
|
||||
<item>wysyłanie stworzonych/zmodyfikowanych wpisów</item>
|
||||
<item>sprawdzanie stanu synchronizacji</item>
|
||||
<item>listowanie lokalnych wpisów</item>
|
||||
<item>listowanie zdalnych wpisów</item>
|
||||
<item>porównywanie lokalnych/zdalnych wpisów</item>
|
||||
<item>pobieranie zdalnych wpisów</item>
|
||||
<item>przetwarzanie końcowe</item>
|
||||
<item>zapisywanie stanu synchronizacji</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Błędna nazwa użytkownika lub hasło</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: Bezpieczeństwo połączenia</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">DAVdroid napotkał nieznany certyfikat. Czy chcesz go dodać?</string>
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">Por favor, aguarde...</string>
|
||||
<string name="send">Enviar</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Otimização da bateria</string>
|
||||
<string name="startup_battery_optimization_message">O Android pode desativar/reduzir a sincronização do DAVdroid depois de alguns dias. Para evitar isso, desligue a otimização da bateria.</string>
|
||||
<string name="startup_battery_optimization_disable">Desligar para o DAVdroid</string>
|
||||
<string name="startup_dont_show_again">Não mostrar novamente</string>
|
||||
<string name="startup_development_version">Versão prévia do DAVdroid</string>
|
||||
<string name="startup_development_version_message">Esta é uma versão de desenvolvimento do DAVdroid. Lembre-se de que as coisas podem não funcionar como esperado. Por favor, envie sugestões e comentários construtivos para melhorar o DAVdroid.</string>
|
||||
@@ -54,18 +57,18 @@
|
||||
<string name="app_settings_reset_hints_summary">Restaura as sugestões que foram descartadas anteriormente</string>
|
||||
<string name="app_settings_reset_hints_success">Todas as sugestões serão exibidas novamente</string>
|
||||
<string name="app_settings_security">Segurança</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Restaurar certificados confiáveis</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Esquece de todos os certificados que foram aceitos anteriormente</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Retirada a confiança de um certificado</item>
|
||||
<item quantity="other">Retirada a confiança de %d certificados</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">Desconfiar dos certificados de sistema</string>
|
||||
<string name="app_settings_distrust_system_certs_on">ACs adicionadas pelo usuário e pelo sistema não serão confiáveis</string>
|
||||
<string name="app_settings_distrust_system_certs_off">ACs adicionadas pelo usuário e pelo sistema serão confiáveis (recomendado)</string>
|
||||
<string name="app_settings_reset_certificates">Restaurar certificados não-confiáveis</string>
|
||||
<string name="app_settings_reset_certificates_summary">Restaura a confiança de todos os certificados personalizados</string>
|
||||
<string name="app_settings_reset_certificates_success">Todos os certificados personalizados foram restaurados</string>
|
||||
<string name="app_settings_debug">Depuração</string>
|
||||
<string name="app_settings_log_to_external_storage">Registrar em arquivo externo</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Registrando no armazenamento externo (se disponível)</string>
|
||||
<string name="app_settings_log_to_external_storage_off">O registro em arquivo externo está desativado</string>
|
||||
<string name="app_settings_show_debug_info">Mostrar informações de depuração</string>
|
||||
<string name="app_settings_show_debug_info_details">Exibir/compartilhar o software e os detalhes da configuração</string>
|
||||
<string name="app_settings_show_debug_info_details">Exibe/compartilha o software e os detalhes da configuração</string>
|
||||
<!--AccountActivity-->
|
||||
<string name="account_synchronize_now">Sincronizar agora</string>
|
||||
<string name="account_synchronizing_now">Sincronizando</string>
|
||||
@@ -101,7 +104,6 @@
|
||||
<string name="login_user_name">Usuário</string>
|
||||
<string name="login_user_name_required">É necessário um nome de usuário</string>
|
||||
<string name="login_base_url">URL base</string>
|
||||
<string name="login_auth_preemptive">Autenticação preferencial (recomendado, mas incompatível com autenticação Digest)</string>
|
||||
<string name="login_login">Autenticar</string>
|
||||
<string name="login_back">Voltar</string>
|
||||
<string name="login_create_account">Criar conta</string>
|
||||
@@ -122,9 +124,6 @@
|
||||
<string name="settings_password">Senha</string>
|
||||
<string name="settings_password_summary">Atualize a senha de acordo com seu servidor</string>
|
||||
<string name="settings_enter_password">Digite sua senha:</string>
|
||||
<string name="settings_preemptive">Autenticação preferencial</string>
|
||||
<string name="settings_preemptive_on">Credenciais enviadas a cada requisição (recomendado)</string>
|
||||
<string name="settings_preemptive_off">Credenciais enviadas após a requisição do servidor</string>
|
||||
<string name="settings_sync">Sincronização</string>
|
||||
<string name="settings_sync_interval_contacts">Intervalo sinc. de contatos</string>
|
||||
<string name="settings_sync_summary_manually">Apenas manualmente</string>
|
||||
@@ -237,4 +236,7 @@
|
||||
<item>salvando o estado da sincronização</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Usuário/senha incorreto</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: Segurança da conexão</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">O DAVdroid encontrou um certificado desconhecido. Deseja torná-lo confiável?</string>
|
||||
</resources>
|
||||
@@ -14,7 +14,6 @@
|
||||
<!--AddAccountActivity-->
|
||||
<string name="login_type_email">Login com seu enderço de email</string>
|
||||
<string name="login_type_url">Login com URL e nome do usuário</string>
|
||||
<string name="login_auth_preemptive">Autenticação preferida (recomendado, mas incompatível com Digest)</string>
|
||||
<!--AccountSettingsActivity-->
|
||||
<string name="settings_authentication">Autenticação</string>
|
||||
<string name="settings_username">Nome de usuário</string>
|
||||
@@ -22,9 +21,6 @@
|
||||
<string name="settings_password">Senha</string>
|
||||
<string name="settings_password_summary">Atualize sua denha de acordo com a do seu servidor.</string>
|
||||
<string name="settings_enter_password">Informe sua senha:</string>
|
||||
<string name="settings_preemptive">Pre-emptive authentication</string>
|
||||
<string name="settings_preemptive_on">Credenciais são enviadas com cadas requisição (recomendado)</string>
|
||||
<string name="settings_preemptive_off">Credenciais são enviadas apos o servidor requisitar</string>
|
||||
<string name="settings_sync">Sincronização</string>
|
||||
<string name="settings_sync_interval_contacts">Intervalo de sincronização dos contatos</string>
|
||||
<string name="settings_sync_summary_manually">Manualmente apenas</string>
|
||||
@@ -54,4 +50,5 @@
|
||||
<!--collection management-->
|
||||
<!--ExceptionInfoFragment-->
|
||||
<!--sync errors and DebugInfoActivity-->
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -15,7 +15,6 @@
|
||||
<!--AddAccountActivity-->
|
||||
<string name="login_type_email">Вход по адресу email</string>
|
||||
<string name="login_type_url">Вход через URL и имя пользователя</string>
|
||||
<string name="login_auth_preemptive">Упреждающая идентификация (рекомендовано, но несовместимо с Digest идентификацией)</string>
|
||||
<!--AccountSettingsActivity-->
|
||||
<string name="settings_authentication">Идентификация</string>
|
||||
<string name="settings_username">Имя</string>
|
||||
@@ -23,9 +22,6 @@
|
||||
<string name="settings_password">Пароль</string>
|
||||
<string name="settings_password_summary">Обновить пароль в соответствии с вашим сервером.</string>
|
||||
<string name="settings_enter_password">Введите свой пароль:</string>
|
||||
<string name="settings_preemptive">Упреждающая идентификация</string>
|
||||
<string name="settings_preemptive_on">Учетные данные посылаются с каждым запросом (рекомендовано)</string>
|
||||
<string name="settings_preemptive_off">Учетные данные посылаются после их запроса сервером</string>
|
||||
<string name="settings_sync">Синхронизация</string>
|
||||
<string name="settings_sync_interval_contacts">Интервал синхронизации контактов</string>
|
||||
<string name="settings_sync_summary_manually">Вручную</string>
|
||||
@@ -64,4 +60,5 @@
|
||||
<string name="sync_error_http_dav">Ошибка сервера %s</string>
|
||||
<string name="sync_error_local_storage">Ошибка базы данных в процессе %s</string>
|
||||
<string name="sync_error_unauthorized">Имя пользователя/пароль неверные</string>
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">Сачекајте…</string>
|
||||
<string name="send">Пошаљи</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Оптимизација батерије</string>
|
||||
<string name="startup_battery_optimization_message">Андроид може да искључи/умањи синхронизацију ДАВдроида након неколико дана. Да бисте спречили ово, искључите оптимизацију батерије.</string>
|
||||
<string name="startup_battery_optimization_disable">Искључи за ДАВдроид</string>
|
||||
<string name="startup_dont_show_again">Не приказуј поново</string>
|
||||
<string name="startup_development_version">ДАВдроид прелиминарно издање</string>
|
||||
<string name="startup_development_version_message">Ово је развојно издање ДАВдроида. Имајте на уму да можда неће радити очекивано. Замољавамо вас за конструктивне повратне информације како бисмо га побољшали.</string>
|
||||
@@ -54,13 +57,12 @@
|
||||
<string name="app_settings_reset_hints_summary">Поновно приказивање претходно одбачених савета</string>
|
||||
<string name="app_settings_reset_hints_success">Сви савети ће поново бити приказани</string>
|
||||
<string name="app_settings_security">Безбедност</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Ресетуј поуздане сертификате</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Заборављање претходно прихваћених сертификата</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Посумњано у један сертификат</item>
|
||||
<item quantity="few">Посумњано у %d сертификата</item>
|
||||
<item quantity="other">Посумњано у %d сертификата</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">Посумњај у системске сертификате</string>
|
||||
<string name="app_settings_distrust_system_certs_on">Системски и кориснички додати сертификати неће бити поуздани</string>
|
||||
<string name="app_settings_distrust_system_certs_off">Системски и кориснички додати сертификати ће бити поуздани (препоручљиво)</string>
|
||||
<string name="app_settings_reset_certificates">Ресетуј (не)поуздане сертификате</string>
|
||||
<string name="app_settings_reset_certificates_summary">Ресетуј поуздање свих прилагођених сертификата</string>
|
||||
<string name="app_settings_reset_certificates_success">Сви прилагођени сертификати су уклоњени</string>
|
||||
<string name="app_settings_debug">Тражење грешака</string>
|
||||
<string name="app_settings_log_to_external_storage">Уписуј у спољашњи фајл</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Уписивање евиденције у спољашње складиште (ако је доступно)</string>
|
||||
@@ -102,7 +104,6 @@
|
||||
<string name="login_user_name">Корисничко име</string>
|
||||
<string name="login_user_name_required">Корисничко име је обавезно</string>
|
||||
<string name="login_base_url">Корени УРЛ</string>
|
||||
<string name="login_auth_preemptive">Превентивна аутентификација (препоручено, али некомпатибилно са Дигест аутентификацијом)</string>
|
||||
<string name="login_login">Пријава</string>
|
||||
<string name="login_back">Назад</string>
|
||||
<string name="login_create_account">Направи налог</string>
|
||||
@@ -123,9 +124,6 @@
|
||||
<string name="settings_password">Лозинка</string>
|
||||
<string name="settings_password_summary">Ажурирајте лозинку за ваш сервер.</string>
|
||||
<string name="settings_enter_password">Унесите лозинку:</string>
|
||||
<string name="settings_preemptive">Превентивна аутентификација</string>
|
||||
<string name="settings_preemptive_on">Слање акредитива са сваким захтевом (препоручено)</string>
|
||||
<string name="settings_preemptive_off">Слање акредитива по захтеву сервера</string>
|
||||
<string name="settings_sync">Синхронизација</string>
|
||||
<string name="settings_sync_interval_contacts">Интервал синх. контаката</string>
|
||||
<string name="settings_sync_summary_manually">Само ручно</string>
|
||||
@@ -239,4 +237,7 @@
|
||||
<item>уписујем стање синхронизације</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Корисничко име или лозинка погрешни</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">ДАВдроид: Безбедност везе</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">ДАВдроид је наишао на непознат сертификат. Желите ли да се поуздате у њега?</string>
|
||||
</resources>
|
||||
@@ -54,11 +54,6 @@
|
||||
<string name="app_settings_reset_hints_summary">Daha önceden azat edilen ipuçlarını yeniden etkinleştirir</string>
|
||||
<string name="app_settings_reset_hints_success">Tüm ipuçları artık gösterilecek</string>
|
||||
<string name="app_settings_security">Güvenlik</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Güvenilen sertifikaları sıfırla</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Daha önceden kabul edilmiş tüm sertifikaları unutur</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="other">Güvenilmeyen %d sertifikaları</item>
|
||||
</plurals>
|
||||
<string name="app_settings_debug">Hata ayıklama</string>
|
||||
<string name="app_settings_log_to_external_storage">Harici dosyaya jurnalle</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Harici depolamaya jurnalleniyor (eğer uygunsa)</string>
|
||||
@@ -101,7 +96,6 @@
|
||||
<string name="login_user_name">Kullanıcı adı</string>
|
||||
<string name="login_user_name_required">Kullanıcı adı zorunludur</string>
|
||||
<string name="login_base_url">Baz URL</string>
|
||||
<string name="login_auth_preemptive">Önleyici doğrulama (tavsiye edilir, fakat Digest doğrulama ile uyumsuz)</string>
|
||||
<string name="login_login">Giriş</string>
|
||||
<string name="login_back">Geri</string>
|
||||
<string name="login_create_account">Hesap yarat</string>
|
||||
@@ -121,9 +115,6 @@
|
||||
<string name="settings_password">Parola</string>
|
||||
<string name="settings_password_summary">Parolayı sunucunuza göre güncelleyin.</string>
|
||||
<string name="settings_enter_password">Parola girin:</string>
|
||||
<string name="settings_preemptive">Önleyici doğrulama</string>
|
||||
<string name="settings_preemptive_on">Giriş bilgileri her istek ile gönderilir (tavsiye edilir)</string>
|
||||
<string name="settings_preemptive_off">Giriş bilgileri sunucu istedikten sonra gönderilir</string>
|
||||
<string name="settings_sync">Senkronizasyon</string>
|
||||
<string name="settings_sync_interval_contacts">Kişiler senk. aralığı</string>
|
||||
<string name="settings_sync_summary_manually">Sadece elle</string>
|
||||
@@ -209,4 +200,5 @@
|
||||
<string name="sync_error_http_dav">%s yaparken sunucu hatası</string>
|
||||
<string name="sync_error_local_storage">%s yaparken veritabanı hatası</string>
|
||||
<string name="sync_error_unauthorized">Kullanıcı adı/parola yanlış</string>
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -14,7 +14,6 @@
|
||||
<!--AddAccountActivity-->
|
||||
<string name="login_type_email">Увійти за допомогою електронної пошти</string>
|
||||
<string name="login_type_url">Увійти за допомогою URL та імені користувача</string>
|
||||
<string name="login_auth_preemptive">Випереджаюча автентифікація (рекомендовано, але несумісно із Digest auth)</string>
|
||||
<!--AccountSettingsActivity-->
|
||||
<string name="settings_authentication">Автентифікація</string>
|
||||
<string name="settings_username">Ім\'я користувача</string>
|
||||
@@ -22,9 +21,6 @@
|
||||
<string name="settings_password">Пароль</string>
|
||||
<string name="settings_password_summary">Оновити пароль, згідно налаштувань Вашого сервера.</string>
|
||||
<string name="settings_enter_password">Введіть Ваш пароль:</string>
|
||||
<string name="settings_preemptive">Випереджаюча автентифікація</string>
|
||||
<string name="settings_preemptive_on">Дані автентифікації будуть надсилатися із кожним запитом (рекомендовано)</string>
|
||||
<string name="settings_preemptive_off">Дані автентифікації будуть надіслані після відповідного запиту сервера</string>
|
||||
<string name="settings_sync">Синхронізація</string>
|
||||
<string name="settings_sync_interval_contacts">Інтервал синхронізації контактів</string>
|
||||
<string name="settings_sync_summary_manually">Лише вручну</string>
|
||||
@@ -55,4 +51,5 @@
|
||||
<!--collection management-->
|
||||
<!--ExceptionInfoFragment-->
|
||||
<!--sync errors and DebugInfoActivity-->
|
||||
<!--cert4android-->
|
||||
</resources>
|
||||
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">请稍等...</string>
|
||||
<string name="send">发送</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">电池优化</string>
|
||||
<string name="startup_battery_optimization_message">系统可能会在几天后减少或停用 DAVdroid 同步。为了避免这一情况,请对 DAVdroid 忽略电池优化。</string>
|
||||
<string name="startup_battery_optimization_disable">忽略电池优化</string>
|
||||
<string name="startup_dont_show_again">不再显示</string>
|
||||
<string name="startup_development_version">DAVdroid 预览版</string>
|
||||
<string name="startup_development_version_message">这是 DAVdroid 的开发版本,部分功能可能无法正常工作。请您提出建设性反馈,帮助我们完善 DAVdroid。</string>
|
||||
@@ -54,11 +57,12 @@
|
||||
<string name="app_settings_reset_hints_summary">重新显示之前忽略过的提示</string>
|
||||
<string name="app_settings_reset_hints_success">所有提示将会再次显示</string>
|
||||
<string name="app_settings_security">安全</string>
|
||||
<string name="app_settings_reset_trusted_certificates">重设受信任证书</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">取消信任所有之前接受的证书</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="other">已删除 %d 个证书</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">不信任系统证书</string>
|
||||
<string name="app_settings_distrust_system_certs_on">系统和用户增加的发布者不会被信任</string>
|
||||
<string name="app_settings_distrust_system_certs_off">系统和用户增加的发布者会被信任(推荐)</string>
|
||||
<string name="app_settings_reset_certificates">重设证书信任状态</string>
|
||||
<string name="app_settings_reset_certificates_summary">重设所有自定义证书的信任状态</string>
|
||||
<string name="app_settings_reset_certificates_success">所有自定义证书已清除</string>
|
||||
<string name="app_settings_debug">调试</string>
|
||||
<string name="app_settings_log_to_external_storage">外部文件日志</string>
|
||||
<string name="app_settings_log_to_external_storage_on">记录日志到外部存储(如果可用)</string>
|
||||
@@ -100,7 +104,6 @@
|
||||
<string name="login_user_name">用户名</string>
|
||||
<string name="login_user_name_required">请输入用户名</string>
|
||||
<string name="login_base_url">根地址</string>
|
||||
<string name="login_auth_preemptive">强制认证模式(推荐使用,但不兼容 Digest 认证方式)</string>
|
||||
<string name="login_login">登录</string>
|
||||
<string name="login_back">返回</string>
|
||||
<string name="login_create_account">创建账户</string>
|
||||
@@ -121,9 +124,6 @@
|
||||
<string name="settings_password">密码</string>
|
||||
<string name="settings_password_summary">修改服务器密码</string>
|
||||
<string name="settings_enter_password">输入密码</string>
|
||||
<string name="settings_preemptive">强制认证模式</string>
|
||||
<string name="settings_preemptive_on">认证信息在每次请求中发送(推荐)</string>
|
||||
<string name="settings_preemptive_off">认证信息在服务器要求后才发送</string>
|
||||
<string name="settings_sync">同步</string>
|
||||
<string name="settings_sync_interval_contacts">通讯录自动同步间隔</string>
|
||||
<string name="settings_sync_summary_manually">手动同步</string>
|
||||
@@ -235,4 +235,7 @@
|
||||
<item>保存同步状态</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">用户名或密码错误</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: 连接安全性</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">DAVdroid 遇到了未知证书。你是否要信任该证书?</string>
|
||||
</resources>
|
||||
@@ -16,7 +16,7 @@
|
||||
android:title="@string/navigation_drawer_about"/>
|
||||
<item
|
||||
android:id="@+id/nav_app_settings"
|
||||
android:icon="@drawable/ic_settings_dark"
|
||||
android:icon="@drawable/ic_settings_action"
|
||||
android:title="@string/navigation_drawer_settings"/>
|
||||
|
||||
<item android:title="@string/navigation_drawer_news_updates">
|
||||
@@ -37,7 +37,7 @@
|
||||
android:title="@string/navigation_drawer_website"/>
|
||||
<item
|
||||
android:id="@+id/nav_faq"
|
||||
android:icon="@drawable/ic_help_dark"
|
||||
android:icon="@drawable/ic_help_action"
|
||||
android:title="@string/navigation_drawer_faq"/>
|
||||
<item
|
||||
android:id="@+id/nav_forums"
|
||||
@@ -46,9 +46,8 @@
|
||||
<item
|
||||
android:id="@+id/nav_donate"
|
||||
android:icon="@drawable/ic_attach_money_dark"
|
||||
android:title="(entry disabled)"
|
||||
android:visible="false"
|
||||
tools:ignore="HardcodedText"/>
|
||||
android:title="@string/navigation_drawer_donate"
|
||||
android:visible="false"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
|
||||
@@ -15,28 +15,22 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.READ_SYNC_STATS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||
|
||||
<!-- account management permissions not required for own accounts since API level 22 -->
|
||||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" android:maxSdkVersion="22"/>
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" android:maxSdkVersion="22"/>
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" android:maxSdkVersion="22"/>
|
||||
|
||||
<!-- legacy permissions -->
|
||||
<uses-permission
|
||||
android:name="android.permission.AUTHENTICATE_ACCOUNTS"
|
||||
android:maxSdkVersion="22"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
<!--
|
||||
for writing external log files; permission only required for SDK <= 18 because since then,
|
||||
writing to app-private directory doesn't require extra permissions
|
||||
-->
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="18"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="18"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
|
||||
|
||||
<!-- other permissions -->
|
||||
<!-- android.permission-group.CONTACTS -->
|
||||
@@ -52,17 +46,18 @@
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<receiver
|
||||
android:name=".App$ReinitLoggingReceiver"
|
||||
android:name=".App$ReinitSettingsReceiver"
|
||||
android:exported="false"
|
||||
android:process=":sync">
|
||||
<intent-filter>
|
||||
<action android:name="at.bitfire.davdroid.REINIT_LOGGER"/>
|
||||
<action android:name="at.bitfire.davdroid.REINIT_SETTINGS"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
@@ -191,11 +186,6 @@
|
||||
android:label="@string/debug_info_title">
|
||||
</activity>
|
||||
|
||||
<!-- MemorizingTrustManager -->
|
||||
<activity
|
||||
android:name="de.duenndns.ssl.MemorizingActivity"
|
||||
android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -10,8 +10,9 @@ package at.bitfire.davdroid;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
@@ -20,12 +21,13 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.PeriodicSync;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@@ -55,7 +57,6 @@ public class AccountSettings {
|
||||
KEY_SETTINGS_VERSION = "version",
|
||||
|
||||
KEY_USERNAME = "user_name",
|
||||
KEY_AUTH_PREEMPTIVE = "auth_preemptive",
|
||||
|
||||
KEY_WIFI_ONLY = "wifi_only", // sync on WiFi only (default: false)
|
||||
KEY_WIFI_ONLY_SSID = "wifi_only_ssid"; // restrict sync to specific WiFi SSID
|
||||
@@ -92,6 +93,7 @@ public class AccountSettings {
|
||||
final Account account;
|
||||
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public AccountSettings(@NonNull Context context, @NonNull Account account) throws InvalidAccountException {
|
||||
this.context = context;
|
||||
this.account = account;
|
||||
@@ -112,8 +114,8 @@ public class AccountSettings {
|
||||
|
||||
if (version < CURRENT_VERSION) {
|
||||
Notification notify = new NotificationCompat.Builder(context)
|
||||
.setSmallIcon(R.drawable.ic_new_releases_light)
|
||||
.setLargeIcon(((BitmapDrawable)context.getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
||||
.setSmallIcon(R.drawable.ic_error_light)
|
||||
.setLargeIcon(App.getLauncherBitmap(context))
|
||||
.setContentTitle(context.getString(R.string.settings_version_update))
|
||||
.setContentText(context.getString(R.string.settings_version_update_settings_updated))
|
||||
.setSubText(context.getString(R.string.settings_version_update_install_hint))
|
||||
@@ -121,9 +123,12 @@ public class AccountSettings {
|
||||
.bigText(context.getString(R.string.settings_version_update_settings_updated)))
|
||||
.setCategory(NotificationCompat.CATEGORY_SYSTEM)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setContentIntent(PendingIntent.getActivity(context, 0,
|
||||
new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("faq/entry/davdroid-not-working-after-update/").build()),
|
||||
PendingIntent.FLAG_CANCEL_CURRENT))
|
||||
.setLocalOnly(true)
|
||||
.build();
|
||||
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
NotificationManagerCompat nm = NotificationManagerCompat.from(context);
|
||||
nm.notify(Constants.NOTIFICATION_ACCOUNT_SETTINGS_UPDATED, notify);
|
||||
|
||||
update(version);
|
||||
@@ -131,11 +136,10 @@ public class AccountSettings {
|
||||
}
|
||||
}
|
||||
|
||||
public static Bundle initialUserData(String userName, boolean preemptive) {
|
||||
public static Bundle initialUserData(String userName) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
|
||||
bundle.putString(KEY_USERNAME, userName);
|
||||
bundle.putString(KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@@ -148,9 +152,6 @@ public class AccountSettings {
|
||||
public String password() { return accountManager.getPassword(account); }
|
||||
public void password(@NonNull String password) { accountManager.setPassword(account, password); }
|
||||
|
||||
public boolean preemptiveAuth() { return Boolean.parseBoolean(accountManager.getUserData(account, KEY_AUTH_PREEMPTIVE)); }
|
||||
public void preemptiveAuth(boolean preemptive) { accountManager.setUserData(account, KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive)); }
|
||||
|
||||
|
||||
// sync. settings
|
||||
|
||||
@@ -198,11 +199,17 @@ public class AccountSettings {
|
||||
// CardDAV settings
|
||||
|
||||
public boolean getVCardRFC6868() {
|
||||
if (BuildConfig.settingVCardRFC6868 != null)
|
||||
return BuildConfig.settingVCardRFC6868;
|
||||
|
||||
return accountManager.getUserData(account, KEY_VCARD_RFC6868) == null;
|
||||
}
|
||||
|
||||
public void setVCardRFC6868(boolean use) {
|
||||
accountManager.setUserData(account, KEY_VCARD_RFC6868, use ? null : "0");
|
||||
if (BuildConfig.settingVCardRFC6868 == null)
|
||||
accountManager.setUserData(account, KEY_VCARD_RFC6868, use ? null : "0");
|
||||
else if (BuildConfig.settingVCardRFC6868 != use)
|
||||
throw new UnsupportedOperationException("Setting is read-only");
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +242,9 @@ public class AccountSettings {
|
||||
|
||||
@NonNull
|
||||
public GroupMethod getGroupMethod() {
|
||||
if (BuildConfig.settingContactGroupMethod != null)
|
||||
return BuildConfig.settingContactGroupMethod;
|
||||
|
||||
final String name = accountManager.getUserData(account, KEY_CONTACT_GROUP_METHOD);
|
||||
return name != null ?
|
||||
GroupMethod.valueOf(name) :
|
||||
@@ -242,8 +252,11 @@ public class AccountSettings {
|
||||
}
|
||||
|
||||
public void setGroupMethod(@NonNull GroupMethod method) {
|
||||
final String name = method == GroupMethod.GROUP_VCARDS ? null : method.name();
|
||||
accountManager.setUserData(account, KEY_CONTACT_GROUP_METHOD, name);
|
||||
if (BuildConfig.settingContactGroupMethod == null) {
|
||||
final String name = method == GroupMethod.GROUP_VCARDS ? null : method.name();
|
||||
accountManager.setUserData(account, KEY_CONTACT_GROUP_METHOD, name);
|
||||
} else if (BuildConfig.settingContactGroupMethod != method)
|
||||
throw new UnsupportedOperationException("Setting is read-only");
|
||||
}
|
||||
|
||||
|
||||
@@ -428,13 +441,13 @@ public class AccountSettings {
|
||||
public static class AppUpdatedReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
@SuppressLint("UnsafeProtectedBroadcastReceiver")
|
||||
@SuppressLint("UnsafeProtectedBroadcastReceiver,MissingPermission")
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
App.log.info("DAVdroid was updated, checking for AccountSettings version");
|
||||
|
||||
// peek into AccountSettings to initiate a possible migration
|
||||
AccountManager accountManager = AccountManager.get(context);
|
||||
for (Account account : accountManager.getAccountsByType(Constants.ACCOUNT_TYPE))
|
||||
for (Account account : accountManager.getAccountsByType(context.getString(R.string.account_type)))
|
||||
try {
|
||||
App.log.info("Checking account " + account.name);
|
||||
new AccountSettings(context, account);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
package at.bitfire.davdroid;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.OnAccountsUpdateListener;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -22,12 +23,14 @@ public class AccountsChangedReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Intent serviceIntent = new Intent(context, DavService.class);
|
||||
serviceIntent.setAction(DavService.ACTION_ACCOUNTS_UPDATED);
|
||||
context.startService(serviceIntent);
|
||||
if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
|
||||
Intent serviceIntent = new Intent(context, DavService.class);
|
||||
serviceIntent.setAction(DavService.ACTION_ACCOUNTS_UPDATED);
|
||||
context.startService(serviceIntent);
|
||||
|
||||
for (OnAccountsUpdateListener listener : listeners)
|
||||
listener.onAccountsUpdated(null);
|
||||
for (OnAccountsUpdateListener listener : listeners)
|
||||
listener.onAccountsUpdated(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerListener(OnAccountsUpdateListener listener, boolean callImmediately) {
|
||||
|
||||
@@ -8,12 +8,18 @@
|
||||
|
||||
package at.bitfire.davdroid;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Application;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -28,22 +34,27 @@ import java.util.logging.Logger;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
|
||||
import at.bitfire.cert4android.CustomCertManager;
|
||||
import at.bitfire.davdroid.log.LogcatHandler;
|
||||
import at.bitfire.davdroid.log.PlainTextFormatter;
|
||||
import at.bitfire.davdroid.model.ServiceDB;
|
||||
import at.bitfire.davdroid.model.Settings;
|
||||
import de.duenndns.ssl.MemorizingTrustManager;
|
||||
import lombok.Cleanup;
|
||||
import lombok.Getter;
|
||||
import okhttp3.internal.tls.OkHostnameVerifier;
|
||||
|
||||
public class App extends Application {
|
||||
public static final String FLAVOR_GOOGLE_PLAY = "gplay";
|
||||
public static final String
|
||||
FLAVOR_GOOGLE_PLAY = "gplay",
|
||||
FLAVOR_ICLOUD = "icloud",
|
||||
FLAVOR_STANDARD = "standard";
|
||||
|
||||
public static final String LOG_TO_EXTERNAL_STORAGE = "logToExternalStorage";
|
||||
public static final String
|
||||
DISTRUST_SYSTEM_CERTIFICATES = "distrustSystemCerts",
|
||||
LOG_TO_EXTERNAL_STORAGE = "logToExternalStorage";
|
||||
|
||||
@Getter
|
||||
private static MemorizingTrustManager memorizingTrustManager;
|
||||
private CustomCertManager certManager;
|
||||
|
||||
@Getter
|
||||
private static SSLSocketFactoryCompat sslSocketFactoryCompat;
|
||||
@@ -54,21 +65,30 @@ public class App extends Application {
|
||||
public final static Logger log = Logger.getLogger("davdroid");
|
||||
static {
|
||||
at.bitfire.dav4android.Constants.log = Logger.getLogger("davdroid.dav4android");
|
||||
at.bitfire.cert4android.Constants.log = Logger.getLogger("davdroid.cert4android");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
// initialize MemorizingTrustManager
|
||||
memorizingTrustManager = new MemorizingTrustManager(this);
|
||||
sslSocketFactoryCompat = new SSLSocketFactoryCompat(memorizingTrustManager);
|
||||
hostnameVerifier = memorizingTrustManager.wrapHostnameVerifier(OkHostnameVerifier.INSTANCE);
|
||||
|
||||
// initializer logger
|
||||
reinitCertManager();
|
||||
reinitLogger();
|
||||
}
|
||||
|
||||
public void reinitCertManager() {
|
||||
if (BuildConfig.customCerts) {
|
||||
if (certManager != null)
|
||||
certManager.close();
|
||||
|
||||
@Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(this);
|
||||
Settings settings = new Settings(dbHelper.getReadableDatabase());
|
||||
|
||||
certManager = new CustomCertManager(this, !settings.getBoolean(DISTRUST_SYSTEM_CERTIFICATES, false));
|
||||
sslSocketFactoryCompat = new SSLSocketFactoryCompat(certManager);
|
||||
hostnameVerifier = certManager.hostnameVerifier(OkHostnameVerifier.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
public void reinitLogger() {
|
||||
// don't use Android default logging, we have our own handlers
|
||||
log.setUseParentHandlers(false);
|
||||
@@ -89,12 +109,12 @@ public class App extends Application {
|
||||
// add logcat handler
|
||||
log.addHandler(LogcatHandler.INSTANCE);
|
||||
|
||||
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManagerCompat nm = NotificationManagerCompat.from(this);
|
||||
// log to external file according to preferences
|
||||
if (logToFile) {
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
|
||||
builder .setSmallIcon(R.drawable.ic_sd_storage_light)
|
||||
.setLargeIcon(((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
||||
.setLargeIcon(getLauncherBitmap(this))
|
||||
.setContentTitle(getString(R.string.logging_davdroid_file_logging))
|
||||
.setLocalOnly(true);
|
||||
|
||||
@@ -130,15 +150,30 @@ public class App extends Application {
|
||||
nm.cancel(Constants.NOTIFICATION_EXTERNAL_FILE_LOGGING);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Bitmap getLauncherBitmap(@NonNull Context context) {
|
||||
Bitmap bitmapLogo = null;
|
||||
Drawable drawableLogo = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP ?
|
||||
context.getDrawable(R.mipmap.ic_launcher) :
|
||||
context.getResources().getDrawable(R.mipmap.ic_launcher);
|
||||
if (drawableLogo instanceof BitmapDrawable)
|
||||
bitmapLogo = ((BitmapDrawable)drawableLogo).getBitmap();
|
||||
return bitmapLogo;
|
||||
}
|
||||
|
||||
public static class ReinitLoggingReceiver extends BroadcastReceiver {
|
||||
|
||||
public static class ReinitSettingsReceiver extends BroadcastReceiver {
|
||||
|
||||
public static final String ACTION_REINIT_SETTINGS = "at.bitfire.davdroid.REINIT_SETTINGS";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
log.info("Received broadcast: re-initializing logger");
|
||||
log.info("Received broadcast: re-initializing settings (logger/cert manager)");
|
||||
|
||||
App app = (App)context.getApplicationContext();
|
||||
app.reinitLogger();
|
||||
app.reinitCertManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ import android.net.Uri;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public static final String
|
||||
ACCOUNT_TYPE = "bitfire.at.davdroid";
|
||||
|
||||
// notification IDs
|
||||
public final static int
|
||||
NOTIFICATION_ACCOUNT_SETTINGS_UPDATED = 0,
|
||||
@@ -22,8 +19,11 @@ public class Constants {
|
||||
NOTIFICATION_CONTACTS_SYNC = 10,
|
||||
NOTIFICATION_CALENDAR_SYNC = 11,
|
||||
NOTIFICATION_TASK_SYNC = 12,
|
||||
NOTIFICATION_PERMISSIONS = 20;
|
||||
NOTIFICATION_PERMISSIONS = 20,
|
||||
NOTIFICATION_SUBSCRIPTION = 21;
|
||||
|
||||
public static final Uri webUri = Uri.parse("https://davdroid.bitfire.at/?pk_campaign=davdroid-app");
|
||||
public static final Uri webUri = BuildConfig.FLAVOR == App.FLAVOR_ICLOUD ?
|
||||
Uri.parse("https://multisync.cloud/?pk_campaign=multisync-app") :
|
||||
Uri.parse("https://davdroid.bitfire.at/?pk_campaign=davdroid-app");
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ package at.bitfire.davdroid;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.ContentValues;
|
||||
@@ -19,11 +19,11 @@ import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@@ -140,6 +140,7 @@ public class DavService extends Service {
|
||||
which actually do the work
|
||||
*/
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
void cleanupAccounts() {
|
||||
App.log.info("Cleaning up orphaned accounts");
|
||||
|
||||
@@ -149,7 +150,7 @@ public class DavService extends Service {
|
||||
|
||||
List<String> sqlAccountNames = new LinkedList<>();
|
||||
AccountManager am = AccountManager.get(this);
|
||||
for (Account account : am.getAccountsByType(Constants.ACCOUNT_TYPE))
|
||||
for (Account account : am.getAccountsByType(getString(R.string.account_type)))
|
||||
sqlAccountNames.add(DatabaseUtils.sqlEscapeString(account.name));
|
||||
|
||||
if (sqlAccountNames.isEmpty())
|
||||
@@ -290,8 +291,8 @@ public class DavService extends Service {
|
||||
info.selected = true;
|
||||
}
|
||||
|
||||
db.beginTransactionNonExclusive();
|
||||
try {
|
||||
db.beginTransactionNonExclusive();
|
||||
saveHomeSets(homeSets);
|
||||
saveCollections(collections.values());
|
||||
db.setTransactionSuccessful();
|
||||
@@ -309,10 +310,10 @@ public class DavService extends Service {
|
||||
if (account != null)
|
||||
debugIntent.putExtra(DebugInfoActivity.KEY_ACCOUNT, account);
|
||||
|
||||
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManagerCompat nm = NotificationManagerCompat.from(DavService.this);
|
||||
Notification notify = new NotificationCompat.Builder(DavService.this)
|
||||
.setSmallIcon(R.drawable.ic_error_light)
|
||||
.setLargeIcon(((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
||||
.setLargeIcon(App.getLauncherBitmap(DavService.this))
|
||||
.setContentTitle(getString(R.string.dav_service_refresh_failed))
|
||||
.setContentText(getString(R.string.dav_service_refresh_couldnt_refresh))
|
||||
.setContentIntent(PendingIntent.getActivity(DavService.this, 0, debugIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
@@ -357,7 +358,7 @@ public class DavService extends Service {
|
||||
private Account account() {
|
||||
@Cleanup Cursor cursor = db.query(Services._TABLE, new String[] { Services.ACCOUNT_NAME }, Services.ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
|
||||
if (cursor.moveToNext()) {
|
||||
return new Account(cursor.getString(0), Constants.ACCOUNT_TYPE);
|
||||
return new Account(cursor.getString(0), getString(R.string.account_type));
|
||||
} else
|
||||
throw new IllegalArgumentException("Service not found");
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -21,9 +22,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import at.bitfire.dav4android.BasicDigestAuthenticator;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import okhttp3.Credentials;
|
||||
import at.bitfire.dav4android.BasicDigestAuthHandler;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
@@ -43,40 +42,40 @@ public class HttpClient {
|
||||
private HttpClient() {
|
||||
}
|
||||
|
||||
public static OkHttpClient create(@NonNull Context context, @NonNull Account account, @NonNull final Logger logger) throws InvalidAccountException {
|
||||
OkHttpClient.Builder builder = defaultBuilder(logger);
|
||||
public static OkHttpClient create(@Nullable Context context, @NonNull Account account, @NonNull final Logger logger) throws InvalidAccountException {
|
||||
OkHttpClient.Builder builder = defaultBuilder(context, logger);
|
||||
|
||||
// use account settings for authentication and logging
|
||||
// use account settings for authentication
|
||||
AccountSettings settings = new AccountSettings(context, account);
|
||||
|
||||
if (settings.preemptiveAuth())
|
||||
builder.addNetworkInterceptor(new PreemptiveAuthenticationInterceptor(settings.username(), settings.password()));
|
||||
else
|
||||
builder.authenticator(new BasicDigestAuthenticator(null, settings.username(), settings.password()));
|
||||
builder = addAuthentication(builder, null, settings.username(), settings.password());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static OkHttpClient create(@NonNull Logger logger) {
|
||||
return defaultBuilder(logger).build();
|
||||
public static OkHttpClient create(@NonNull Context context, @NonNull Logger logger) {
|
||||
return defaultBuilder(context, logger).build();
|
||||
}
|
||||
|
||||
public static OkHttpClient create(@NonNull Context context, @NonNull Account account) throws InvalidAccountException {
|
||||
return create(context, account, App.log);
|
||||
}
|
||||
|
||||
public static OkHttpClient create() {
|
||||
return create(App.log);
|
||||
public static OkHttpClient create(@Nullable Context context) {
|
||||
return create(context, App.log);
|
||||
}
|
||||
|
||||
private static OkHttpClient.Builder defaultBuilder(@NonNull final Logger logger) {
|
||||
|
||||
private static OkHttpClient.Builder defaultBuilder(@Nullable Context context, @NonNull final Logger logger) {
|
||||
OkHttpClient.Builder builder = client.newBuilder();
|
||||
|
||||
// use MemorizingTrustManager to manage self-signed certificates
|
||||
if (App.getSslSocketFactoryCompat() != null)
|
||||
builder.sslSocketFactory(App.getSslSocketFactoryCompat(), App.getMemorizingTrustManager());
|
||||
if (App.getHostnameVerifier() != null)
|
||||
builder.hostnameVerifier(App.getHostnameVerifier());
|
||||
if (context != null) {
|
||||
App app = (App)context.getApplicationContext();
|
||||
if (App.getSslSocketFactoryCompat() != null && app.getCertManager() != null)
|
||||
builder.sslSocketFactory(App.getSslSocketFactoryCompat(), app.getCertManager());
|
||||
if (App.getHostnameVerifier() != null)
|
||||
builder.hostnameVerifier(App.getHostnameVerifier());
|
||||
}
|
||||
|
||||
// set timeouts
|
||||
builder.connectTimeout(30, TimeUnit.SECONDS);
|
||||
@@ -107,24 +106,23 @@ public class HttpClient {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static OkHttpClient.Builder addAuthentication(@NonNull OkHttpClient.Builder builder, @NonNull String username, @NonNull String password, boolean preemptive) {
|
||||
if (preemptive)
|
||||
builder.addNetworkInterceptor(new PreemptiveAuthenticationInterceptor(username, password));
|
||||
else
|
||||
builder.authenticator(new BasicDigestAuthenticator(null, username, password));
|
||||
return builder;
|
||||
private static OkHttpClient.Builder addAuthentication(@NonNull OkHttpClient.Builder builder, @Nullable String host, @NonNull String username, @NonNull String password) {
|
||||
BasicDigestAuthHandler authHandler = new BasicDigestAuthHandler(host, username, password);
|
||||
return builder
|
||||
.addNetworkInterceptor(authHandler)
|
||||
.authenticator(authHandler);
|
||||
}
|
||||
|
||||
public static OkHttpClient addAuthentication(@NonNull OkHttpClient client, @NonNull String username, @NonNull String password, boolean preemptive) {
|
||||
public static OkHttpClient addAuthentication(@NonNull OkHttpClient client, @NonNull String username, @NonNull String password) {
|
||||
OkHttpClient.Builder builder = client.newBuilder();
|
||||
addAuthentication(builder, username, password, preemptive);
|
||||
addAuthentication(builder, null, username, password);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static OkHttpClient addAuthentication(@NonNull OkHttpClient client, @NonNull String host, @NonNull String username, @NonNull String password) {
|
||||
return client.newBuilder()
|
||||
.authenticator(new BasicDigestAuthenticator(host, username, password))
|
||||
.build();
|
||||
OkHttpClient.Builder builder = client.newBuilder();
|
||||
addAuthentication(builder, host, username, password);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -140,18 +138,4 @@ public class HttpClient {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
static class PreemptiveAuthenticationInterceptor implements Interceptor {
|
||||
final String username, password;
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
App.log.fine("Adding basic authorization header for user " + username);
|
||||
Request request = chain.request().newBuilder()
|
||||
.header("Authorization", Credentials.basic(username, password))
|
||||
.build();
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import de.duenndns.ssl.MemorizingTrustManager;
|
||||
import lombok.Cleanup;
|
||||
|
||||
public class SSLSocketFactoryCompat extends SSLSocketFactory {
|
||||
@@ -99,10 +98,10 @@ public class SSLSocketFactoryCompat extends SSLSocketFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public SSLSocketFactoryCompat(@NonNull MemorizingTrustManager mtm) {
|
||||
public SSLSocketFactoryCompat(@NonNull X509TrustManager trustManager) {
|
||||
try {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, new X509TrustManager[] { mtm }, null);
|
||||
sslContext.init(null, new X509TrustManager[] { trustManager }, null);
|
||||
delegate = sslContext.getSocketFactory();
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new AssertionError(); // The system has no TLS. Just give up.
|
||||
|
||||
@@ -175,7 +175,7 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
|
||||
|
||||
// SYNC STATE
|
||||
|
||||
@SuppressWarnings("Recycle")
|
||||
@SuppressWarnings("ParcelClassLoader,Recycle")
|
||||
protected void readSyncState() throws ContactsStorageException {
|
||||
@Cleanup("recycle") Parcel parcel = Parcel.obtain();
|
||||
byte[] raw = getSyncState();
|
||||
|
||||
@@ -30,7 +30,6 @@ import net.fortuna.ical4j.model.component.VTimeZone;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -51,10 +50,6 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||
|
||||
public static final String COLUMN_CTAG = Calendars.CAL_SYNC1;
|
||||
|
||||
protected static final int
|
||||
DIRTY_INCREASE_SEQUENCE = 1,
|
||||
DIRTY_DONT_INCREASE_SEQUENCE = 2;
|
||||
|
||||
static String[] BASE_INFO_COLUMNS = new String[] {
|
||||
Events._ID,
|
||||
Events._SYNC_ID,
|
||||
@@ -140,14 +135,11 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||
public LocalResource[] getDirty() throws CalendarStorageException, FileNotFoundException {
|
||||
List<LocalResource> dirty = new LinkedList<>();
|
||||
|
||||
// get dirty events which are not required to have an increased SEQUENCE value
|
||||
Collections.addAll(dirty, (LocalEvent[])queryEvents(Events.DIRTY + "=" + DIRTY_DONT_INCREASE_SEQUENCE + " AND " + Events.ORIGINAL_ID + " IS NULL", null));
|
||||
|
||||
// get dirty events which are required to have an increased SEQUENCE value
|
||||
for (LocalEvent event : (LocalEvent[])queryEvents(Events.DIRTY + "=" + DIRTY_INCREASE_SEQUENCE + " AND " + Events.ORIGINAL_ID + " IS NULL", null)) {
|
||||
for (LocalEvent event : (LocalEvent[])queryEvents(Events.DIRTY + "!=0 AND " + Events.ORIGINAL_ID + " IS NULL", null)) {
|
||||
if (event.getEvent().sequence == null) // sequence has not been assigned yet (i.e. this event was just locally created)
|
||||
event.getEvent().sequence = 0;
|
||||
else
|
||||
else if (event.weAreOrganizer)
|
||||
event.getEvent().sequence++;
|
||||
dirty.add(event);
|
||||
}
|
||||
@@ -203,14 +195,15 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||
|
||||
BatchOperation batch = new BatchOperation(provider);
|
||||
// re-schedule original event and set it to DIRTY
|
||||
batch.enqueue(ContentProviderOperation.newUpdate(
|
||||
syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, originalID)))
|
||||
.withValue(LocalEvent.COLUMN_SEQUENCE, originalSequence + 1)
|
||||
.withValue(Events.DIRTY, DIRTY_INCREASE_SEQUENCE)
|
||||
.build());
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newUpdate(syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, originalID)))
|
||||
.withValue(LocalEvent.COLUMN_SEQUENCE, originalSequence + 1)
|
||||
.withValue(Events.DIRTY, 1)
|
||||
));
|
||||
// remove exception
|
||||
batch.enqueue(ContentProviderOperation.newDelete(
|
||||
syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, id))).build());
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newDelete(syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, id)))
|
||||
));
|
||||
batch.commit();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@@ -232,16 +225,16 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||
|
||||
BatchOperation batch = new BatchOperation(provider);
|
||||
// original event to DIRTY
|
||||
batch.enqueue(ContentProviderOperation.newUpdate(
|
||||
syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, originalID)))
|
||||
.withValue(Events.DIRTY, DIRTY_DONT_INCREASE_SEQUENCE)
|
||||
.build());
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newUpdate(syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, originalID)))
|
||||
.withValue(Events.DIRTY, 1)
|
||||
));
|
||||
// increase SEQUENCE and set DIRTY to 0
|
||||
batch.enqueue(ContentProviderOperation.newUpdate(
|
||||
syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, id)))
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newUpdate(syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, id)))
|
||||
.withValue(LocalEvent.COLUMN_SEQUENCE, sequence + 1)
|
||||
.withValue(Events.DIRTY, 0)
|
||||
.build());
|
||||
));
|
||||
batch.commit();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -98,14 +98,17 @@ public class LocalContact extends AndroidContact implements LocalResource {
|
||||
super.insertDataRows(batch);
|
||||
|
||||
if (contact.unknownProperties != null) {
|
||||
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(dataSyncURI());
|
||||
if (id == null)
|
||||
builder.withValueBackReference(UnknownProperties.RAW_CONTACT_ID, 0);
|
||||
else
|
||||
final BatchOperation.Operation op;
|
||||
final ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(dataSyncURI());
|
||||
if (id == null) {
|
||||
op = new BatchOperation.Operation(builder, UnknownProperties.RAW_CONTACT_ID, 0);
|
||||
} else {
|
||||
op = new BatchOperation.Operation(builder);
|
||||
builder.withValue(UnknownProperties.RAW_CONTACT_ID, id);
|
||||
}
|
||||
builder .withValue(UnknownProperties.MIMETYPE, UnknownProperties.CONTENT_ITEM_TYPE)
|
||||
.withValue(UnknownProperties.UNKNOWN_PROPERTIES, contact.unknownProperties);
|
||||
batch.enqueue(builder.build());
|
||||
batch.enqueue(op);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -113,35 +116,32 @@ public class LocalContact extends AndroidContact implements LocalResource {
|
||||
|
||||
public void addToGroup(BatchOperation batch, long groupID) {
|
||||
assertID();
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newInsert(dataSyncURI())
|
||||
.withValue(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE)
|
||||
.withValue(GroupMembership.RAW_CONTACT_ID, id)
|
||||
.withValue(GroupMembership.GROUP_ROW_ID, groupID)
|
||||
.build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newInsert(dataSyncURI())
|
||||
.withValue(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE)
|
||||
.withValue(GroupMembership.RAW_CONTACT_ID, id)
|
||||
.withValue(GroupMembership.GROUP_ROW_ID, groupID)
|
||||
));
|
||||
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newInsert(dataSyncURI())
|
||||
.withValue(CachedGroupMembership.MIMETYPE, CachedGroupMembership.CONTENT_ITEM_TYPE)
|
||||
.withValue(CachedGroupMembership.RAW_CONTACT_ID, id)
|
||||
.withValue(CachedGroupMembership.GROUP_ID, groupID)
|
||||
.withYieldAllowed(true)
|
||||
.build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newInsert(dataSyncURI())
|
||||
.withValue(CachedGroupMembership.MIMETYPE, CachedGroupMembership.CONTENT_ITEM_TYPE)
|
||||
.withValue(CachedGroupMembership.RAW_CONTACT_ID, id)
|
||||
.withValue(CachedGroupMembership.GROUP_ID, groupID)
|
||||
.withYieldAllowed(true)
|
||||
));
|
||||
}
|
||||
|
||||
public void removeGroupMemberships(BatchOperation batch) {
|
||||
assertID();
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newDelete(dataSyncURI())
|
||||
.withSelection(
|
||||
Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + " IN (?,?)",
|
||||
new String[] { String.valueOf(id), GroupMembership.CONTENT_ITEM_TYPE, CachedGroupMembership.CONTENT_ITEM_TYPE }
|
||||
)
|
||||
.withYieldAllowed(true)
|
||||
.build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newDelete(dataSyncURI())
|
||||
.withSelection(
|
||||
Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + " IN (?,?)",
|
||||
new String[] { String.valueOf(id), GroupMembership.CONTENT_ITEM_TYPE, CachedGroupMembership.CONTENT_ITEM_TYPE }
|
||||
)
|
||||
.withYieldAllowed(true)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,6 +41,8 @@ public class LocalEvent extends AndroidEvent implements LocalResource {
|
||||
@Getter protected String fileName;
|
||||
@Getter @Setter protected String eTag;
|
||||
|
||||
public boolean weAreOrganizer = true;
|
||||
|
||||
public LocalEvent(@NonNull AndroidCalendar calendar, Event event, String fileName, String eTag) {
|
||||
super(calendar, event);
|
||||
this.fileName = fileName;
|
||||
@@ -66,6 +68,8 @@ public class LocalEvent extends AndroidEvent implements LocalResource {
|
||||
event.uid = values.getAsString(COLUMN_UID);
|
||||
|
||||
event.sequence = values.getAsInteger(COLUMN_SEQUENCE);
|
||||
if (values.getAsInteger(Events.IS_ORGANIZER) == 0)
|
||||
weAreOrganizer = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,7 +19,6 @@ import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
|
||||
import android.provider.ContactsContract.Groups;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.provider.ContactsContract.RawContacts.Data;
|
||||
import android.provider.ContactsContract.RawContactsEntity;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@@ -66,24 +65,23 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
|
||||
BatchOperation batch = new BatchOperation(addressBook.provider);
|
||||
|
||||
// delete cached group memberships
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newDelete(addressBook.syncAdapterURI(ContactsContract.Data.CONTENT_URI))
|
||||
.withSelection(
|
||||
CachedGroupMembership.MIMETYPE + "=? AND " + CachedGroupMembership.GROUP_ID + "=?",
|
||||
new String[] { CachedGroupMembership.CONTENT_ITEM_TYPE, String.valueOf(id) }
|
||||
).build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newDelete(addressBook.syncAdapterURI(ContactsContract.Data.CONTENT_URI))
|
||||
.withSelection(
|
||||
CachedGroupMembership.MIMETYPE + "=? AND " + CachedGroupMembership.GROUP_ID + "=?",
|
||||
new String[] { CachedGroupMembership.CONTENT_ITEM_TYPE, String.valueOf(id) }
|
||||
)
|
||||
));
|
||||
|
||||
// insert updated cached group memberships
|
||||
for (long member : getMembers())
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newInsert(addressBook.syncAdapterURI(ContactsContract.Data.CONTENT_URI))
|
||||
.withValue(CachedGroupMembership.MIMETYPE, CachedGroupMembership.CONTENT_ITEM_TYPE)
|
||||
.withValue(CachedGroupMembership.RAW_CONTACT_ID, member)
|
||||
.withValue(CachedGroupMembership.GROUP_ID, id)
|
||||
.withYieldAllowed(true)
|
||||
.build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newInsert(addressBook.syncAdapterURI(ContactsContract.Data.CONTENT_URI))
|
||||
.withValue(CachedGroupMembership.MIMETYPE, CachedGroupMembership.CONTENT_ITEM_TYPE)
|
||||
.withValue(CachedGroupMembership.RAW_CONTACT_ID, member)
|
||||
.withValue(CachedGroupMembership.GROUP_ID, id)
|
||||
.withYieldAllowed(true)
|
||||
));
|
||||
|
||||
batch.commit();
|
||||
}
|
||||
@@ -120,12 +118,11 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
|
||||
BatchOperation batch = new BatchOperation(addressBook.provider);
|
||||
|
||||
for (long member : getMembers())
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(RawContacts.CONTENT_URI, member)))
|
||||
.withValue(RawContacts.DIRTY, 1)
|
||||
.withYieldAllowed(true)
|
||||
.build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(RawContacts.CONTENT_URI, member)))
|
||||
.withValue(RawContacts.DIRTY, 1)
|
||||
.withYieldAllowed(true)
|
||||
));
|
||||
|
||||
batch.commit();
|
||||
}
|
||||
@@ -151,15 +148,14 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
|
||||
Constants.log.fine("Assigning members to group " + id);
|
||||
|
||||
// delete all memberships and cached memberships for this group
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newDelete(addressBook.syncAdapterURI(ContactsContract.Data.CONTENT_URI))
|
||||
.withSelection(
|
||||
"(" + GroupMembership.MIMETYPE + "=? AND " + GroupMembership.GROUP_ROW_ID + "=?) OR (" +
|
||||
CachedGroupMembership.MIMETYPE + "=? AND " + CachedGroupMembership.GROUP_ID + "=?)",
|
||||
new String[] { GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(id), CachedGroupMembership.CONTENT_ITEM_TYPE, String.valueOf(id) })
|
||||
.withYieldAllowed(true)
|
||||
.build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newDelete(addressBook.syncAdapterURI(ContactsContract.Data.CONTENT_URI))
|
||||
.withSelection(
|
||||
"(" + GroupMembership.MIMETYPE + "=? AND " + GroupMembership.GROUP_ROW_ID + "=?) OR (" +
|
||||
CachedGroupMembership.MIMETYPE + "=? AND " + CachedGroupMembership.GROUP_ID + "=?)",
|
||||
new String[] { GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(id), CachedGroupMembership.CONTENT_ITEM_TYPE, String.valueOf(id) })
|
||||
.withYieldAllowed(true)
|
||||
));
|
||||
|
||||
// extract list of member UIDs
|
||||
List<String> members = new LinkedList<>();
|
||||
@@ -181,12 +177,11 @@ public class LocalGroup extends AndroidGroup implements LocalResource {
|
||||
}
|
||||
|
||||
// remove pending memberships
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(Groups.CONTENT_URI, id)))
|
||||
.withValue(COLUMN_PENDING_MEMBERS, null)
|
||||
.withYieldAllowed(true)
|
||||
.build()
|
||||
);
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(Groups.CONTENT_URI, id)))
|
||||
.withValue(COLUMN_PENDING_MEMBERS, null)
|
||||
.withYieldAllowed(true)
|
||||
));
|
||||
|
||||
batch.commit();
|
||||
}
|
||||
|
||||
@@ -21,68 +21,69 @@ import android.os.IBinder;
|
||||
import at.bitfire.davdroid.ui.setup.LoginActivity;
|
||||
|
||||
public class AccountAuthenticatorService extends Service {
|
||||
private static AccountAuthenticator accountAuthenticator;
|
||||
|
||||
private AccountAuthenticator getAuthenticator() {
|
||||
if (accountAuthenticator != null)
|
||||
return accountAuthenticator;
|
||||
return accountAuthenticator = new AccountAuthenticator(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT))
|
||||
return getAuthenticator().getIBinder();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static class AccountAuthenticator extends AbstractAccountAuthenticator {
|
||||
final Context context;
|
||||
|
||||
public AccountAuthenticator(Context context) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
}
|
||||
private AccountAuthenticator accountAuthenticator;
|
||||
|
||||
@Override
|
||||
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType,
|
||||
String[] requiredFeatures, Bundle options) throws NetworkErrorException {
|
||||
Intent intent = new Intent(context, LoginActivity.class);
|
||||
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
return bundle;
|
||||
}
|
||||
@Override
|
||||
public void onCreate() {
|
||||
accountAuthenticator = new AccountAuthenticator(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT))
|
||||
return accountAuthenticator.getIBinder();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class AccountAuthenticator extends AbstractAccountAuthenticator {
|
||||
final Context context;
|
||||
|
||||
public AccountAuthenticator(Context context) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType,
|
||||
String[] requiredFeatures, Bundle options) throws NetworkErrorException {
|
||||
Intent intent = new Intent(context, LoginActivity.class);
|
||||
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthTokenLabel(String authTokenType) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthTokenLabel(String authTokenType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,9 +53,7 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
|
||||
super.onPerformSync(account, extras, authority, provider, syncResult);
|
||||
|
||||
public void sync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
|
||||
try {
|
||||
AccountSettings settings = new AccountSettings(getContext(), account);
|
||||
if (!extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL) && !checkSyncConditions(settings))
|
||||
|
||||
@@ -47,9 +47,7 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
|
||||
super.onPerformSync(account, extras, authority, provider, syncResult);
|
||||
|
||||
public void sync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
|
||||
SQLiteOpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
|
||||
try {
|
||||
AccountSettings settings = new AccountSettings(getContext(), account);
|
||||
|
||||
@@ -47,6 +47,7 @@ import at.bitfire.dav4android.property.AddressData;
|
||||
import at.bitfire.dav4android.property.GetCTag;
|
||||
import at.bitfire.dav4android.property.GetContentType;
|
||||
import at.bitfire.dav4android.property.GetETag;
|
||||
import at.bitfire.dav4android.property.ResourceType;
|
||||
import at.bitfire.dav4android.property.SupportedAddressData;
|
||||
import at.bitfire.davdroid.AccountSettings;
|
||||
import at.bitfire.davdroid.App;
|
||||
@@ -211,12 +212,11 @@ public class ContactsSyncManager extends SyncManager {
|
||||
currentGroups = contact.getGroupMemberships();
|
||||
for (Long groupID : SetUtils.disjunction(cachedGroups, currentGroups)) {
|
||||
App.log.fine("Marking group as dirty: " + groupID);
|
||||
batch.enqueue(ContentProviderOperation
|
||||
.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(Groups.CONTENT_URI, groupID)))
|
||||
batch.enqueue(new BatchOperation.Operation(
|
||||
ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(Groups.CONTENT_URI, groupID)))
|
||||
.withValue(Groups.DIRTY, 1)
|
||||
.withYieldAllowed(true)
|
||||
.build()
|
||||
);
|
||||
));
|
||||
}
|
||||
} catch(FileNotFoundException ignored) {
|
||||
}
|
||||
@@ -270,26 +270,15 @@ public class ContactsSyncManager extends SyncManager {
|
||||
@Override
|
||||
protected void listRemote() throws IOException, HttpException, DavException {
|
||||
// fetch list of remote VCards and build hash table to index file name
|
||||
|
||||
try {
|
||||
davAddressBook().addressbookQuery();
|
||||
} catch(HttpException e) {
|
||||
/* non-successful responses to CARDDAV:addressbook-query with empty filter, tested on 2015/10/21
|
||||
* fastmail.com 403 Forbidden (DAV:error CARDDAV:supported-filter)
|
||||
* mailbox.org (OpenXchange) 400 Bad Request
|
||||
* SOGo 207 Multi-status, but without entries http://www.sogo.nu/bugs/view.php?id=3370
|
||||
* Zimbra ZCS 500 Server Error https://bugzilla.zimbra.com/show_bug.cgi?id=101902
|
||||
*/
|
||||
if (e.status == 400 || e.status == 403 || e.status == 500 || e.status == 501) {
|
||||
App.log.log(Level.WARNING, "Server error on REPORT addressbook-query, falling back to PROPFIND", e);
|
||||
davAddressBook().propfind(1, GetETag.NAME);
|
||||
} else
|
||||
// no defined fallback, pass through exception
|
||||
throw e;
|
||||
}
|
||||
davAddressBook().propfind(1, ResourceType.NAME, GetETag.NAME);
|
||||
|
||||
remoteResources = new HashMap<>(davCollection.members.size());
|
||||
for (DavResource vCard : davCollection.members) {
|
||||
// ignore member collections
|
||||
ResourceType type = (ResourceType)vCard.properties.get(ResourceType.NAME);
|
||||
if (type != null && type.types.contains(ResourceType.COLLECTION))
|
||||
continue;
|
||||
|
||||
String fileName = vCard.fileName();
|
||||
App.log.fine("Found remote VCard: " + fileName);
|
||||
remoteResources.put(fileName, vCard);
|
||||
@@ -495,7 +484,7 @@ public class ContactsSyncManager extends SyncManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
OkHttpClient resourceClient = HttpClient.create();
|
||||
OkHttpClient resourceClient = HttpClient.create(context);
|
||||
|
||||
// authenticate only against a certain host, and only upon request
|
||||
resourceClient = HttpClient.addAuthentication(resourceClient, baseUrl.host(), settings.username(), settings.password());
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package at.bitfire.davdroid.syncadapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
interface ISyncPlugin {
|
||||
|
||||
boolean beforeSync(@NonNull Context context);
|
||||
void afterSync(@NonNull Context context);
|
||||
|
||||
}
|
||||
@@ -28,7 +28,14 @@ import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
|
||||
//import com.android.vending.billing.IInAppBillingService;
|
||||
|
||||
import org.apache.commons.collections4.IteratorUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.davdroid.AccountSettings;
|
||||
@@ -50,16 +57,39 @@ public abstract class SyncAdapterService extends Service {
|
||||
|
||||
public static abstract class SyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
|
||||
private static final ServiceLoader<ISyncPlugin> syncPluginLoader = ServiceLoader.load(ISyncPlugin.class);
|
||||
private final List<ISyncPlugin> syncPlugins = IteratorUtils.toList(syncPluginLoader.iterator());
|
||||
|
||||
|
||||
public SyncAdapter(Context context) {
|
||||
super(context, false);
|
||||
|
||||
for (ISyncPlugin plugin : syncPlugins)
|
||||
App.log.info("Registered sync plugin: " + plugin.getClass().getName());
|
||||
}
|
||||
|
||||
abstract void sync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult);
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
|
||||
App.log.info("Sync for " + authority + " has been initiated");
|
||||
|
||||
// required for dav4android (ServiceLoader)
|
||||
Thread.currentThread().setContextClassLoader(getContext().getClassLoader());
|
||||
final Context context = getContext();
|
||||
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||
|
||||
boolean runSync = true;
|
||||
for (ISyncPlugin plugin : syncPlugins)
|
||||
if (!plugin.beforeSync(context))
|
||||
runSync = false;
|
||||
|
||||
if (runSync)
|
||||
sync(account, extras, authority, provider, syncResult);
|
||||
|
||||
for (ISyncPlugin plugin : syncPlugins)
|
||||
plugin.afterSync(context);
|
||||
|
||||
App.log.info("Sync for " + authority + " complete");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,14 +102,13 @@ public abstract class SyncAdapterService extends Service {
|
||||
|
||||
Notification notify = new NotificationCompat.Builder(getContext())
|
||||
.setSmallIcon(R.drawable.ic_error_light)
|
||||
.setLargeIcon(((BitmapDrawable)getContext().getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
||||
.setLargeIcon(App.getLauncherBitmap(getContext()))
|
||||
.setContentTitle(getContext().getString(R.string.sync_error_permissions))
|
||||
.setContentText(getContext().getString(R.string.sync_error_permissions_text))
|
||||
.setContentIntent(PendingIntent.getActivity(getContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT))
|
||||
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
||||
.setLocalOnly(true)
|
||||
.build();
|
||||
NotificationManager nm = (NotificationManager)getContext().getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManagerCompat nm = NotificationManagerCompat.from(getContext());
|
||||
nm.notify(Constants.NOTIFICATION_PERMISSIONS, notify);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,15 +9,14 @@ package at.bitfire.davdroid.syncadapter;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SyncResult;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@@ -69,7 +68,7 @@ abstract public class SyncManager {
|
||||
SYNC_PHASE_POST_PROCESSING = 10,
|
||||
SYNC_PHASE_SAVE_SYNC_STATE = 11;
|
||||
|
||||
protected final NotificationManager notificationManager;
|
||||
protected final NotificationManagerCompat notificationManager;
|
||||
protected final String uniqueCollectionId;
|
||||
|
||||
protected final Context context;
|
||||
@@ -113,7 +112,7 @@ abstract public class SyncManager {
|
||||
|
||||
// dismiss previous error notifications
|
||||
this.uniqueCollectionId = uniqueCollectionId;
|
||||
notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager = NotificationManagerCompat.from(context);
|
||||
notificationManager.cancel(uniqueCollectionId, notificationId());
|
||||
}
|
||||
|
||||
@@ -230,11 +229,10 @@ abstract public class SyncManager {
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
builder .setSmallIcon(R.drawable.ic_error_light)
|
||||
.setLargeIcon(((BitmapDrawable)context.getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
||||
.setLargeIcon(App.getLauncherBitmap(context))
|
||||
.setContentTitle(getSyncErrorTitle())
|
||||
.setContentIntent(PendingIntent.getActivity(context, 0, detailsIntent, PendingIntent.FLAG_CANCEL_CURRENT))
|
||||
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
||||
.setLocalOnly(true);
|
||||
.setCategory(NotificationCompat.CATEGORY_ERROR);
|
||||
|
||||
try {
|
||||
String[] phases = context.getResources().getStringArray(R.array.sync_error_phases);
|
||||
|
||||
@@ -58,9 +58,7 @@ public class TasksSyncAdapterService extends SyncAdapterService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient providerClient, SyncResult syncResult) {
|
||||
super.onPerformSync(account, extras, authority, providerClient, syncResult);
|
||||
|
||||
public void sync(Account account, Bundle extras, String authority, ContentProviderClient providerClient, SyncResult syncResult) {
|
||||
try {
|
||||
@Cleanup TaskProvider provider = TaskProvider.acquire(getContext().getContentResolver(), TaskProvider.ProviderName.OpenTasks);
|
||||
if (provider == null)
|
||||
|
||||
@@ -65,15 +65,15 @@ public class AboutActivity extends AppCompatActivity {
|
||||
@RequiredArgsConstructor
|
||||
private static class ComponentInfo {
|
||||
final String title, version, website, copyright;
|
||||
final int licenseInfo;
|
||||
final Integer licenseInfo;
|
||||
final String licenseTextFile;
|
||||
}
|
||||
|
||||
private final static ComponentInfo components[] = {
|
||||
new ComponentInfo(
|
||||
"DAVdroid", BuildConfig.VERSION_NAME, "https://davdroid.bitfire.at",
|
||||
null, BuildConfig.VERSION_NAME, "https://davdroid.bitfire.at",
|
||||
DateFormatUtils.format(BuildConfig.buildTime, "yyyy") + " Ricki Hirner, Bernhard Stockmann (bitfire web engineering)",
|
||||
R.string.about_license_info_no_warranty, "gpl-3.0-standalone.html"
|
||||
null, null
|
||||
), new ComponentInfo(
|
||||
"AmbilWarna", null, "https://github.com/yukuku/ambilwarna",
|
||||
"Yuku", R.string.about_license_info_no_warranty, "apache2.html"
|
||||
@@ -89,9 +89,6 @@ public class AboutActivity extends AppCompatActivity {
|
||||
), new ComponentInfo(
|
||||
"ical4j", "2.x", "https://ical4j.github.io/",
|
||||
"Ben Fortuna", R.string.about_license_info_no_warranty, "bsd-3clause.html"
|
||||
), new ComponentInfo(
|
||||
"MemorizingTrustManager", null, "https://github.com/ge0rg/MemorizingTrustManager",
|
||||
"Georg Lukas", R.string.about_license_info_no_warranty, "mit.html"
|
||||
), new ComponentInfo(
|
||||
"OkHttp", null, "https://square.github.io/okhttp/",
|
||||
"Square, Inc.", R.string.about_license_info_no_warranty, "apache2.html"
|
||||
@@ -102,7 +99,7 @@ public class AboutActivity extends AppCompatActivity {
|
||||
};
|
||||
|
||||
|
||||
private static class TabsAdapter extends FragmentPagerAdapter {
|
||||
private class TabsAdapter extends FragmentPagerAdapter {
|
||||
public TabsAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
@@ -114,7 +111,7 @@ public class AboutActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return components[position].title;
|
||||
return components[position].title != null ? components[position].title : getString(R.string.app_name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,7 +142,8 @@ public class AboutActivity extends AppCompatActivity {
|
||||
View v = inflater.inflate(R.layout.about_component, container, false);
|
||||
|
||||
TextView tv = (TextView)v.findViewById(R.id.title);
|
||||
tv.setText(info.title + (info.version != null ? (" " + info.version) : ""));
|
||||
tv.setText((info.title == null ? getString(R.string.app_name) : info.title) +
|
||||
(info.version != null ? (" " + info.version) : ""));
|
||||
|
||||
tv = (TextView)v.findViewById(R.id.website);
|
||||
tv.setAutoLinkMask(Linkify.WEB_URLS);
|
||||
@@ -155,12 +153,20 @@ public class AboutActivity extends AppCompatActivity {
|
||||
tv.setText("© " + info.copyright);
|
||||
|
||||
tv = (TextView)v.findViewById(R.id.license_info);
|
||||
tv.setText(info.licenseInfo);
|
||||
if (info.licenseInfo == null)
|
||||
tv.setVisibility(View.GONE);
|
||||
else
|
||||
tv.setText(info.licenseInfo);
|
||||
|
||||
// load and format license text
|
||||
Bundle args = new Bundle(1);
|
||||
args.putString(KEY_FILE_NAME, info.licenseTextFile);
|
||||
getLoaderManager().initLoader(0, args, this);
|
||||
if (info.licenseTextFile == null) {
|
||||
v.findViewById(R.id.license_header).setVisibility(View.GONE);
|
||||
v.findViewById(R.id.license_text).setVisibility(View.GONE);
|
||||
} else {
|
||||
Bundle args = new Bundle(1);
|
||||
args.putString(KEY_FILE_NAME, info.licenseTextFile);
|
||||
getLoaderManager().initLoader(0, args, this);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.accounts.AccountManagerCallback;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.LoaderManager;
|
||||
import android.content.AsyncTaskLoader;
|
||||
import android.content.ComponentName;
|
||||
@@ -24,6 +25,7 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.Loader;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.SyncStatusObserver;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
@@ -62,6 +64,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.cert4android.CustomCertManager;
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.DavService;
|
||||
import at.bitfire.davdroid.R;
|
||||
@@ -73,6 +76,8 @@ import at.bitfire.davdroid.model.ServiceDB.Services;
|
||||
import at.bitfire.ical4android.TaskProvider;
|
||||
import lombok.Cleanup;
|
||||
|
||||
import static android.content.ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
|
||||
|
||||
public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener, PopupMenu.OnMenuItemClickListener, LoaderManager.LoaderCallbacks<AccountActivity.AccountInfo> {
|
||||
public static final String EXTRA_ACCOUNT = "account";
|
||||
|
||||
@@ -83,6 +88,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
Toolbar tbCardDAV, tbCalDAV;
|
||||
|
||||
@Override
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@@ -110,6 +116,22 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
getLoaderManager().initLoader(0, getIntent().getExtras(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
CustomCertManager certManager = ((App)getApplicationContext()).getCertManager();
|
||||
if (certManager != null)
|
||||
certManager.appInForeground = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
CustomCertManager certManager = ((App)getApplicationContext()).getCertManager();
|
||||
if (certManager != null)
|
||||
certManager.appInForeground = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.activity_account, menu);
|
||||
@@ -267,7 +289,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
|
||||
@Override
|
||||
public Loader<AccountInfo> onCreateLoader(int id, Bundle args) {
|
||||
return new AccountLoader(this, account.name);
|
||||
return new AccountLoader(this, account);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
@@ -333,19 +355,22 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
}
|
||||
|
||||
|
||||
private static class AccountLoader extends AsyncTaskLoader<AccountInfo> implements DavService.RefreshingStatusListener, ServiceConnection {
|
||||
private final String accountName;
|
||||
private static class AccountLoader extends AsyncTaskLoader<AccountInfo> implements DavService.RefreshingStatusListener, ServiceConnection, SyncStatusObserver {
|
||||
private final Account account;
|
||||
private final OpenHelper dbHelper;
|
||||
private DavService.InfoBinder davService;
|
||||
private Object syncStatusListener;
|
||||
|
||||
public AccountLoader(Context context, String accountName) {
|
||||
public AccountLoader(Context context, Account account) {
|
||||
super(context);
|
||||
this.accountName = accountName;
|
||||
this.account = account;
|
||||
dbHelper = new OpenHelper(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
syncStatusListener = ContentResolver.addStatusChangeListener(SYNC_OBSERVER_TYPE_ACTIVE, this);
|
||||
|
||||
getContext().bindService(new Intent(getContext(), DavService.class), this, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
@@ -353,6 +378,9 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
protected void onStopLoading() {
|
||||
davService.removeRefreshingStatusListener(this);
|
||||
getContext().unbindService(this);
|
||||
|
||||
if (syncStatusListener != null)
|
||||
ContentResolver.removeStatusChangeListener(syncStatusListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -373,6 +401,11 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(int which) {
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountInfo loadInBackground() {
|
||||
AccountInfo info = new AccountInfo();
|
||||
@@ -382,7 +415,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
@Cleanup Cursor cursor = db.query(
|
||||
Services._TABLE,
|
||||
new String[] { Services.ID, Services.SERVICE },
|
||||
Services.ACCOUNT_NAME + "=?", new String[] { accountName },
|
||||
Services.ACCOUNT_NAME + "=?", new String[] { account.name },
|
||||
null, null, null);
|
||||
|
||||
if (cursor.getCount() == 0)
|
||||
@@ -395,14 +428,16 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
if (Services.SERVICE_CARDDAV.equals(service)) {
|
||||
info.carddav = new AccountInfo.ServiceInfo();
|
||||
info.carddav.id = id;
|
||||
info.carddav.refreshing = davService.isRefreshing(id);
|
||||
info.carddav.refreshing = davService.isRefreshing(id) || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY);
|
||||
info.carddav.hasHomeSets = hasHomeSets(db, id);
|
||||
info.carddav.collections = readCollections(db, id);
|
||||
|
||||
} else if (Services.SERVICE_CALDAV.equals(service)) {
|
||||
info.caldav = new AccountInfo.ServiceInfo();
|
||||
info.caldav.id = id;
|
||||
info.caldav.refreshing = davService.isRefreshing(id);
|
||||
info.caldav.refreshing = davService.isRefreshing(id) ||
|
||||
ContentResolver.isSyncActive(account, CalendarContract.AUTHORITY) ||
|
||||
ContentResolver.isSyncActive(account, TaskProvider.ProviderName.OpenTasks.authority);
|
||||
info.caldav.hasHomeSets = hasHomeSets(db, id);
|
||||
info.caldav.collections = readCollections(db, id);
|
||||
}
|
||||
@@ -430,6 +465,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
}
|
||||
return collections;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ package at.bitfire.davdroid.ui;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.OnAccountsUpdateListener;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -103,8 +104,9 @@ public class AccountListFragment extends ListFragment implements LoaderManager.L
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("MissingPermission")
|
||||
public Account[] loadInBackground() {
|
||||
return accountManager.getAccountsByType(Constants.ACCOUNT_TYPE);
|
||||
return accountManager.getAccountsByType(getContext().getString(R.string.account_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.davdroid.AccountSettings;
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.BuildConfig;
|
||||
import at.bitfire.davdroid.InvalidAccountException;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.ical4android.TaskProvider;
|
||||
@@ -114,17 +115,6 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
final SwitchPreferenceCompat prefPreemptive = (SwitchPreferenceCompat)findPreference("preemptive");
|
||||
prefPreemptive.setChecked(settings.preemptiveAuth());
|
||||
prefPreemptive.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.preemptiveAuth((Boolean)newValue);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// category: synchronization
|
||||
final ListPreference prefSyncContacts = (ListPreference)findPreference("sync_interval_contacts");
|
||||
final Long syncIntervalContacts = settings.getSyncInterval(ContactsContract.AUTHORITY);
|
||||
@@ -221,14 +211,17 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
final SwitchPreferenceCompat prefRFC6868 = (SwitchPreferenceCompat)findPreference("vcard_rfc6868");
|
||||
if (syncIntervalContacts != null) {
|
||||
prefRFC6868.setChecked(settings.getVCardRFC6868());
|
||||
prefRFC6868.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
settings.setVCardRFC6868((Boolean)o);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (BuildConfig.settingVCardRFC6868 == null)
|
||||
prefRFC6868.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
settings.setVCardRFC6868((Boolean)o);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
else
|
||||
prefRFC6868.setEnabled(false);
|
||||
} else
|
||||
prefRFC6868.setEnabled(false);
|
||||
|
||||
@@ -236,15 +229,18 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
if (syncIntervalContacts != null) {
|
||||
prefGroupMethod.setValue(settings.getGroupMethod().name());
|
||||
prefGroupMethod.setSummary(prefGroupMethod.getEntry());
|
||||
prefGroupMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
String name = (String)o;
|
||||
settings.setGroupMethod(GroupMethod.valueOf(name));
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (BuildConfig.settingContactGroupMethod == null)
|
||||
prefGroupMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
String name = (String)o;
|
||||
settings.setGroupMethod(GroupMethod.valueOf(name));
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
else
|
||||
prefGroupMethod.setEnabled(false);
|
||||
} else
|
||||
prefGroupMethod.setEnabled(false);
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
package at.bitfire.davdroid.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.NavigationView;
|
||||
@@ -23,14 +21,16 @@ import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.BuildConfig;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.ui.setup.LoginActivity;
|
||||
|
||||
public class AccountsActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
|
||||
|
||||
private static final ServiceLoader<IAccountsDrawerHandler> serviceLoader = ServiceLoader.load(IAccountsDrawerHandler.class);
|
||||
private static final IAccountsDrawerHandler accountsDrawerHandler = serviceLoader.iterator().next();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -76,34 +76,12 @@ public class AccountsActivity extends AppCompatActivity implements NavigationVie
|
||||
|
||||
@Override
|
||||
public boolean onNavigationItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.nav_about:
|
||||
startActivity(new Intent(this, AboutActivity.class));
|
||||
break;
|
||||
case R.id.nav_app_settings:
|
||||
startActivity(new Intent(this, AppSettingsActivity.class));
|
||||
break;
|
||||
case R.id.nav_twitter:
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/davdroidapp")));
|
||||
break;
|
||||
case R.id.nav_website:
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri));
|
||||
break;
|
||||
case R.id.nav_faq:
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("faq/").build()));
|
||||
break;
|
||||
case R.id.nav_forums:
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("forums/").build()));
|
||||
break;
|
||||
case R.id.nav_donate:
|
||||
if (BuildConfig.FLAVOR != App.FLAVOR_GOOGLE_PLAY)
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("donate/").build()));
|
||||
break;
|
||||
}
|
||||
boolean processed = accountsDrawerHandler.onNavigationItemSelected(this, item);
|
||||
|
||||
DrawerLayout drawer = (DrawerLayout)findViewById(R.id.drawer_layout);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,15 +16,10 @@ import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
import android.support.v7.preference.SwitchPreferenceCompat;
|
||||
|
||||
import java.security.KeyStoreException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.model.ServiceDB;
|
||||
import at.bitfire.davdroid.model.Settings;
|
||||
import de.duenndns.ssl.MemorizingTrustManager;
|
||||
import lombok.Cleanup;
|
||||
|
||||
public class AppSettingsActivity extends AppCompatActivity {
|
||||
@@ -42,19 +37,47 @@ public class AppSettingsActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
public static class SettingsFragment extends PreferenceFragmentCompat {
|
||||
Preference prefResetHints,
|
||||
prefResetCertificates;
|
||||
SwitchPreferenceCompat prefLogToExternalStorage;
|
||||
ServiceDB.OpenHelper dbHelper;
|
||||
Settings settings;
|
||||
|
||||
Preference
|
||||
prefResetHints,
|
||||
prefResetCertificates;
|
||||
SwitchPreferenceCompat
|
||||
prefDistrustSystemCerts,
|
||||
prefLogToExternalStorage;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
dbHelper = new ServiceDB.OpenHelper(getContext());
|
||||
settings = new Settings(dbHelper.getReadableDatabase());
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
dbHelper.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle bundle, String s) {
|
||||
addPreferencesFromResource(R.xml.settings_app);
|
||||
|
||||
prefResetHints = findPreference("reset_hints");
|
||||
prefResetCertificates = findPreference("reset_certificates");
|
||||
|
||||
@Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
|
||||
Settings settings = new Settings(dbHelper.getReadableDatabase());
|
||||
prefDistrustSystemCerts = (SwitchPreferenceCompat)findPreference("distrust_system_certs");
|
||||
App app = (App)getContext().getApplicationContext();
|
||||
if (app.getCertManager() == null)
|
||||
prefDistrustSystemCerts.setVisible(false);
|
||||
else
|
||||
prefDistrustSystemCerts.setChecked(settings.getBoolean(App.DISTRUST_SYSTEM_CERTIFICATES, false));
|
||||
|
||||
prefResetCertificates = findPreference("reset_certificates");
|
||||
if (app.getCertManager() == null)
|
||||
prefResetCertificates.setVisible(false);
|
||||
|
||||
prefLogToExternalStorage = (SwitchPreferenceCompat)findPreference("log_to_external_storage");
|
||||
prefLogToExternalStorage.setChecked(settings.getBoolean(App.LOG_TO_EXTERNAL_STORAGE, false));
|
||||
}
|
||||
@@ -63,6 +86,8 @@ public class AppSettingsActivity extends AppCompatActivity {
|
||||
public boolean onPreferenceTreeClick(Preference preference) {
|
||||
if (preference == prefResetHints)
|
||||
resetHints();
|
||||
else if (preference == prefDistrustSystemCerts)
|
||||
setDistrustSystemCerts(((SwitchPreferenceCompat)preference).isChecked());
|
||||
else if (preference == prefResetCertificates)
|
||||
resetCertificates();
|
||||
else if (preference == prefLogToExternalStorage)
|
||||
@@ -73,31 +98,29 @@ public class AppSettingsActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void resetHints() {
|
||||
@Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
|
||||
Settings settings = new Settings(dbHelper.getWritableDatabase());
|
||||
settings.remove(StartupDialogFragment.HINT_BATTERY_OPTIMIZATIONS);
|
||||
settings.remove(StartupDialogFragment.HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED);
|
||||
settings.remove(StartupDialogFragment.HINT_OPENTASKS_NOT_INSTALLED);
|
||||
Snackbar.make(getView(), R.string.app_settings_reset_hints_success, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void resetCertificates() {
|
||||
MemorizingTrustManager mtm = App.getMemorizingTrustManager();
|
||||
private void setDistrustSystemCerts(boolean distrust) {
|
||||
settings.putBoolean(App.DISTRUST_SYSTEM_CERTIFICATES, distrust);
|
||||
|
||||
int deleted = 0;
|
||||
Enumeration<String> iterator = mtm.getCertificates();
|
||||
while (iterator.hasMoreElements())
|
||||
try {
|
||||
mtm.deleteCertificate(iterator.nextElement());
|
||||
deleted++;
|
||||
} catch (KeyStoreException e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't distrust certificate", e);
|
||||
}
|
||||
Snackbar.make(getView(), getResources().getQuantityString(R.plurals.app_settings_reset_trusted_certificates_success, deleted, deleted), Snackbar.LENGTH_LONG).show();
|
||||
// re-initialize certificate manager
|
||||
App app = (App)getContext().getApplicationContext();
|
||||
app.reinitCertManager();
|
||||
|
||||
// reinitialize certificate manager of :sync process
|
||||
getContext().sendBroadcast(new Intent(App.ReinitSettingsReceiver.ACTION_REINIT_SETTINGS));
|
||||
}
|
||||
|
||||
private void resetCertificates() {
|
||||
((App)getContext().getApplicationContext()).getCertManager().resetCertificates();
|
||||
Snackbar.make(getView(), getString(R.string.app_settings_reset_certificates_success), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void setExternalLogging(boolean externalLogging) {
|
||||
@Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
|
||||
Settings settings = new Settings(dbHelper.getWritableDatabase());
|
||||
settings.putBoolean(App.LOG_TO_EXTERNAL_STORAGE, externalLogging);
|
||||
|
||||
// reinitialize logger of default process
|
||||
@@ -105,7 +128,7 @@ public class AppSettingsActivity extends AppCompatActivity {
|
||||
app.reinitLogger();
|
||||
|
||||
// reinitialize logger of :sync process
|
||||
getContext().sendBroadcast(new Intent("at.bitfire.davdroid.REINIT_LOGGER"));
|
||||
getContext().sendBroadcast(new Intent(App.ReinitSettingsReceiver.ACTION_REINIT_SETTINGS));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ package at.bitfire.davdroid.ui;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.LoaderManager;
|
||||
import android.content.AsyncTaskLoader;
|
||||
import android.content.ContentResolver;
|
||||
@@ -144,6 +145,7 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("MissingPermission")
|
||||
public String loadInBackground() {
|
||||
Throwable throwable = null;
|
||||
String logs = null,
|
||||
@@ -195,9 +197,10 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
||||
workaroundInstalled = pm.getPackageInfo("at.bitfire.davdroid.jbworkaround", 0) != null;
|
||||
} catch(PackageManager.NameNotFoundException ignored) {}
|
||||
report.append("\nSOFTWARE INFORMATION\n" +
|
||||
"DAVdroid version: ").append(BuildConfig.VERSION_NAME).append(" (").append(BuildConfig.VERSION_CODE).append(") ").append(new Date(BuildConfig.buildTime)).append("\n")
|
||||
.append("Installed from: ").append(installedFrom).append("\n")
|
||||
.append("JB Workaround installed: ").append(workaroundInstalled ? "yes" : "no").append("\n\n");
|
||||
"Package: ").append(BuildConfig.APPLICATION_ID).append("\n" +
|
||||
"Version: ").append(BuildConfig.VERSION_NAME).append(" (").append(BuildConfig.VERSION_CODE).append(") ").append(new Date(BuildConfig.buildTime)).append("\n")
|
||||
.append("Installed from: ").append(installedFrom).append("\n")
|
||||
.append("JB Workaround installed: ").append(workaroundInstalled ? "yes" : "no").append("\n\n");
|
||||
} catch(Exception ex) {
|
||||
App.log.log(Level.SEVERE, "Couldn't get software information", ex);
|
||||
}
|
||||
@@ -206,14 +209,13 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
||||
"CONFIGURATION\n" +
|
||||
"System-wide synchronization: ").append(ContentResolver.getMasterSyncAutomatically() ? "automatically" : "manually").append("\n");
|
||||
AccountManager accountManager = AccountManager.get(getContext());
|
||||
for (Account acct : accountManager.getAccountsByType(Constants.ACCOUNT_TYPE))
|
||||
for (Account acct : accountManager.getAccountsByType(getContext().getString(R.string.account_type)))
|
||||
try {
|
||||
AccountSettings settings = new AccountSettings(getContext(), acct);
|
||||
report.append("Account: ").append(acct.name).append("\n" +
|
||||
" Address book sync. interval: ").append(syncStatus(settings, ContactsContract.AUTHORITY)).append("\n" +
|
||||
" Calendar sync. interval: ").append(syncStatus(settings, CalendarContract.AUTHORITY)).append("\n" +
|
||||
" OpenTasks sync. interval: ").append(syncStatus(settings, "org.dmfs.tasks")).append("\n" +
|
||||
" Preemptive auth: ").append(settings.preemptiveAuth()).append("\n" +
|
||||
" WiFi only: ").append(settings.getSyncWifiOnly());
|
||||
if (settings.getSyncWifiOnlySSID() != null)
|
||||
report.append(", SSID: ").append(settings.getSyncWifiOnlySSID());
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package at.bitfire.davdroid.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.MenuItem;
|
||||
|
||||
public interface IAccountsDrawerHandler {
|
||||
|
||||
public boolean onNavigationItemSelected(@NonNull Activity activity, MenuItem item);
|
||||
|
||||
}
|
||||
@@ -9,12 +9,12 @@
|
||||
package at.bitfire.davdroid.ui;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
|
||||
@@ -63,7 +63,7 @@ public class PermissionsActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
if (!noCalendarPermissions && !noContactsPermissions && !noTaskPermissions) {
|
||||
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManagerCompat nm = NotificationManagerCompat.from(this);
|
||||
nm.cancel(Constants.NOTIFICATION_PERMISSIONS);
|
||||
|
||||
finish();
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
package at.bitfire.davdroid.ui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -17,6 +19,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
@@ -37,14 +40,15 @@ import lombok.Cleanup;
|
||||
|
||||
public class StartupDialogFragment extends DialogFragment {
|
||||
public static final String
|
||||
HINT_BATTERY_OPTIMIZATIONS = "hint_BatteryOptimizations",
|
||||
HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED = "hint_GooglePlayAccountsRemoved",
|
||||
HINT_OPENTASKS_NOT_INSTALLED = "hint_OpenTasksNotInstalled";
|
||||
|
||||
private static final String ARGS_MODE = "mode";
|
||||
|
||||
enum Mode {
|
||||
BATTERY_OPTIMIZATIONS,
|
||||
DEVELOPMENT_VERSION,
|
||||
FDROID_DONATE,
|
||||
GOOGLE_PLAY_ACCOUNTS_REMOVED,
|
||||
OPENTASKS_NOT_INSTALLED
|
||||
}
|
||||
@@ -64,17 +68,18 @@ public class StartupDialogFragment extends DialogFragment {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && // only on Android <5
|
||||
settings.getBoolean(HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED, true)) // and only when "Don't show again" hasn't been clicked yet
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.GOOGLE_PLAY_ACCOUNTS_REMOVED));
|
||||
} else {
|
||||
// other stores
|
||||
final String installedFrom = installedFrom(context);
|
||||
if (installedFrom == null || installedFrom.startsWith("org.fdroid"))
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.FDROID_DONATE));
|
||||
}
|
||||
}
|
||||
|
||||
// battery optimization whitelisting
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && settings.getBoolean(HINT_BATTERY_OPTIMIZATIONS, true)) {
|
||||
PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
|
||||
if (!powerManager.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID))
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.BATTERY_OPTIMIZATIONS));
|
||||
}
|
||||
|
||||
// OpenTasks information
|
||||
if (!LocalTaskList.tasksProviderAvailable(context) &&
|
||||
settings.getBoolean(HINT_OPENTASKS_NOT_INSTALLED, true))
|
||||
if (!LocalTaskList.tasksProviderAvailable(context) && settings.getBoolean(HINT_OPENTASKS_NOT_INSTALLED, true))
|
||||
dialogs.add(StartupDialogFragment.instantiate(Mode.OPENTASKS_NOT_INSTALLED));
|
||||
|
||||
Collections.reverse(dialogs);
|
||||
@@ -91,6 +96,8 @@ public class StartupDialogFragment extends DialogFragment {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
@SuppressLint("BatteryLife")
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
setCancelable(false);
|
||||
|
||||
@@ -98,9 +105,35 @@ public class StartupDialogFragment extends DialogFragment {
|
||||
|
||||
Mode mode = Mode.valueOf(getArguments().getString(ARGS_MODE));
|
||||
switch (mode) {
|
||||
case BATTERY_OPTIMIZATIONS:
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.startup_battery_optimization)
|
||||
.setMessage(R.string.startup_battery_optimization_message)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.startup_battery_optimization_disable, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
|
||||
Uri.parse("package:" + BuildConfig.APPLICATION_ID));
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.startup_dont_show_again, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Settings settings = new Settings(dbHelper.getWritableDatabase());
|
||||
settings.putBoolean(HINT_BATTERY_OPTIMIZATIONS, false);
|
||||
}
|
||||
})
|
||||
.create();
|
||||
|
||||
case DEVELOPMENT_VERSION:
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setIcon(R.drawable.ic_launcher)
|
||||
.setIcon(R.mipmap.ic_launcher)
|
||||
.setTitle(R.string.startup_development_version)
|
||||
.setMessage(R.string.startup_development_version_message)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@@ -116,27 +149,6 @@ public class StartupDialogFragment extends DialogFragment {
|
||||
})
|
||||
.create();
|
||||
|
||||
case FDROID_DONATE:
|
||||
if (BuildConfig.FLAVOR != App.FLAVOR_GOOGLE_PLAY)
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setIcon(R.drawable.ic_launcher)
|
||||
.setTitle(R.string.startup_donate)
|
||||
.setMessage(R.string.startup_donate_message)
|
||||
.setPositiveButton(R.string.startup_donate_now, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("donate/").build()));
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.startup_donate_later, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.create();
|
||||
else
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
case GOOGLE_PLAY_ACCOUNTS_REMOVED:
|
||||
Drawable icon = null;
|
||||
try {
|
||||
|
||||
@@ -10,6 +10,7 @@ package at.bitfire.davdroid.ui.setup;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
@@ -32,6 +33,7 @@ import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.davdroid.AccountSettings;
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.BuildConfig;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.DavService;
|
||||
import at.bitfire.davdroid.InvalidAccountException;
|
||||
@@ -78,11 +80,13 @@ public class AccountDetailsFragment extends Fragment {
|
||||
DavResourceFinder.Configuration config = (DavResourceFinder.Configuration)getArguments().getSerializable(KEY_CONFIG);
|
||||
|
||||
final EditText editName = (EditText)v.findViewById(R.id.account_name);
|
||||
editName.setText(config.userName);
|
||||
editName.setText((config.calDAV != null && config.calDAV.email != null) ? config.calDAV.email : config.userName);
|
||||
|
||||
// CardDAV-specific
|
||||
v.findViewById(R.id.carddav).setVisibility(config.cardDAV != null ? View.VISIBLE : View.GONE);
|
||||
spnrGroupMethod = (Spinner)v.findViewById(R.id.contact_group_method);
|
||||
if (BuildConfig.settingContactGroupMethod != null)
|
||||
spnrGroupMethod.setEnabled(false);
|
||||
|
||||
Button btnCreate = (Button)v.findViewById(R.id.create_account);
|
||||
btnCreate.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -92,9 +96,10 @@ public class AccountDetailsFragment extends Fragment {
|
||||
if (name.isEmpty())
|
||||
editName.setError(getString(R.string.login_account_name_required));
|
||||
else {
|
||||
if (createAccount(name, (DavResourceFinder.Configuration)getArguments().getSerializable(KEY_CONFIG)))
|
||||
if (createAccount(name, (DavResourceFinder.Configuration)getArguments().getSerializable(KEY_CONFIG))) {
|
||||
getActivity().setResult(Activity.RESULT_OK);
|
||||
getActivity().finish();
|
||||
else
|
||||
} else
|
||||
Snackbar.make(v, R.string.login_account_not_created, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
@@ -104,10 +109,10 @@ public class AccountDetailsFragment extends Fragment {
|
||||
}
|
||||
|
||||
protected boolean createAccount(String accountName, DavResourceFinder.Configuration config) {
|
||||
Account account = new Account(accountName, Constants.ACCOUNT_TYPE);
|
||||
Account account = new Account(accountName, getString(R.string.account_type));
|
||||
|
||||
// create Android account
|
||||
Bundle userData = AccountSettings.initialUserData(config.userName, config.preemptive);
|
||||
Bundle userData = AccountSettings.initialUserData(config.userName);
|
||||
App.log.log(Level.INFO, "Creating Android account with initial config", new Object[] { account, userData });
|
||||
|
||||
AccountManager accountManager = AccountManager.get(getContext());
|
||||
@@ -157,13 +162,23 @@ public class AccountDetailsFragment extends Fragment {
|
||||
settings.setSyncInterval(CalendarContract.AUTHORITY, DEFAULT_SYNC_INTERVAL);
|
||||
|
||||
// enable task sync, if possible
|
||||
if (Build.VERSION.SDK_INT >= 23 || LocalTaskList.tasksProviderAvailable(getContext())) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
/* Android >=6, it's possible to gain OpenTasks permissions dynamically, so
|
||||
* OpenTasks sync will be enabled by default. Setting the sync interval to "manually"
|
||||
* if OpenTasks is not installed avoids the "sync error" in Android settings / Accounts. */
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 1);
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, DEFAULT_SYNC_INTERVAL);
|
||||
} else
|
||||
// Android <6 only: disable OpenTasks sync forever when OpenTasks is not installed
|
||||
// because otherwise, there will be a non-catchable SecurityException as soon as OpenTasks is installed
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 0);
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority,
|
||||
LocalTaskList.tasksProviderAvailable(getContext()) ? DEFAULT_SYNC_INTERVAL : AccountSettings.SYNC_INTERVAL_MANUALLY);
|
||||
} else {
|
||||
// Android <6: enable task sync according to whether OpenTasks is accessible
|
||||
if (LocalTaskList.tasksProviderAvailable(getContext())) {
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 1);
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, DEFAULT_SYNC_INTERVAL);
|
||||
} else
|
||||
// Android <6 only: disable OpenTasks sync forever when OpenTasks is not installed
|
||||
// because otherwise, there will be a non-catchable SecurityException as soon as OpenTasks is installed
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 0);
|
||||
}
|
||||
} else {
|
||||
// disable calendar and task sync when CalDAV is not available
|
||||
ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 0);
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.xbill.DNS.Type;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
@@ -28,6 +29,7 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import at.bitfire.dav4android.Constants;
|
||||
import at.bitfire.dav4android.DavResource;
|
||||
import at.bitfire.dav4android.UrlUtils;
|
||||
import at.bitfire.dav4android.exception.DavException;
|
||||
@@ -39,6 +41,7 @@ import at.bitfire.dav4android.property.CalendarColor;
|
||||
import at.bitfire.dav4android.property.CalendarDescription;
|
||||
import at.bitfire.dav4android.property.CalendarHomeSet;
|
||||
import at.bitfire.dav4android.property.CalendarTimezone;
|
||||
import at.bitfire.dav4android.property.CalendarUserAddressSet;
|
||||
import at.bitfire.dav4android.property.CurrentUserPrincipal;
|
||||
import at.bitfire.dav4android.property.CurrentUserPrivilegeSet;
|
||||
import at.bitfire.dav4android.property.DisplayName;
|
||||
@@ -77,8 +80,8 @@ public class DavResourceFinder {
|
||||
log.setLevel(Level.FINEST);
|
||||
log.addHandler(logBuffer);
|
||||
|
||||
httpClient = HttpClient.create(log);
|
||||
httpClient = HttpClient.addAuthentication(httpClient, credentials.userName, credentials.password, credentials.authPreemptive);
|
||||
httpClient = HttpClient.create(context, log);
|
||||
httpClient = HttpClient.addAuthentication(httpClient, credentials.userName, credentials.password);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +91,7 @@ public class DavResourceFinder {
|
||||
calDavConfig = findInitialConfiguration(Service.CALDAV);
|
||||
|
||||
return new Configuration(
|
||||
credentials.userName, credentials.password, credentials.authPreemptive,
|
||||
credentials.userName, credentials.password,
|
||||
cardDavConfig, calDavConfig,
|
||||
logBuffer.toString()
|
||||
);
|
||||
@@ -140,6 +143,26 @@ public class DavResourceFinder {
|
||||
}
|
||||
}
|
||||
|
||||
if (config.principal != null && service == Service.CALDAV) {
|
||||
// query email address (CalDAV scheduling: calendar-user-address-set)
|
||||
DavResource davPrincipal = new DavResource(httpClient, HttpUrl.get(config.principal), log);
|
||||
try {
|
||||
davPrincipal.propfind(0, CalendarUserAddressSet.NAME);
|
||||
CalendarUserAddressSet addressSet = (CalendarUserAddressSet)davPrincipal.properties.get(CalendarUserAddressSet.NAME);
|
||||
if (addressSet != null)
|
||||
for (String href : addressSet.hrefs)
|
||||
try {
|
||||
URI uri = new URI(href);
|
||||
if ("mailto".equals(uri.getScheme()))
|
||||
config.email = uri.getSchemeSpecificPart();
|
||||
} catch(URISyntaxException e) {
|
||||
Constants.log.log(Level.WARNING, "Unparseable user address", e);
|
||||
}
|
||||
} catch(IOException | HttpException | DavException e) {
|
||||
Constants.log.log(Level.WARNING, "Couldn't query user email address", e);
|
||||
}
|
||||
}
|
||||
|
||||
// return config or null if config doesn't contain useful information
|
||||
boolean serviceAvailable = config.principal != null || !config.homeSets.isEmpty() || !config.collections.isEmpty();
|
||||
return serviceAvailable ? config : null;
|
||||
@@ -368,10 +391,11 @@ public class DavResourceFinder {
|
||||
public URI principal;
|
||||
public final Set<URI> homeSets = new HashSet<>();
|
||||
public final Map<URI, CollectionInfo> collections = new HashMap<>();
|
||||
|
||||
public String email;
|
||||
}
|
||||
|
||||
public final String userName, password;
|
||||
public final boolean preemptive;
|
||||
|
||||
public final ServiceInfo cardDAV;
|
||||
public final ServiceInfo calDAV;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package at.bitfire.davdroid.ui.setup;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
public interface ILoginCredentialsFragment {
|
||||
|
||||
Fragment getFragment();
|
||||
|
||||
}
|
||||
@@ -14,23 +14,70 @@ import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
|
||||
/**
|
||||
* Activity to initially connect to a server and create an account.
|
||||
* Fields for server/user data can be pre-filled with extras in the Intent.
|
||||
*/
|
||||
public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
/**
|
||||
* When set, "login by URL" will be activated by default, and the URL field will be set to this value.
|
||||
* When not set, "login by email" will be activated by default.
|
||||
*/
|
||||
public static final String EXTRA_URL = "url";
|
||||
|
||||
/**
|
||||
* When set, and {@link #EXTRA_PASSWORD} is set too, the user name field will be set to this value.
|
||||
* When set, and {@link #EXTRA_URL} is not set, the email address field will be set to this value.
|
||||
*/
|
||||
public static final String EXTRA_USERNAME = "username";
|
||||
|
||||
/**
|
||||
* When set, the password field will be set to this value.
|
||||
*/
|
||||
public static final String EXTRA_PASSWORD = "password";
|
||||
|
||||
|
||||
private static final ServiceLoader<ILoginCredentialsFragment> loginFragmentLoader = ServiceLoader.load(ILoginCredentialsFragment.class);
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (savedInstanceState == null)
|
||||
// first call, add fragment
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, new LoginCredentialsFragment())
|
||||
.commit();
|
||||
for (ILoginCredentialsFragment fragment : loginFragmentLoader)
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, fragment.getFragment())
|
||||
.commit();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
App app = (App)getApplicationContext();
|
||||
if (app.getCertManager() != null)
|
||||
app.getCertManager().appInForeground = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
App app = (App)getApplicationContext();
|
||||
if (app.getCertManager() != null)
|
||||
app.getCertManager().appInForeground = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.activity_login, menu);
|
||||
|
||||
@@ -19,7 +19,6 @@ import lombok.RequiredArgsConstructor;
|
||||
public class LoginCredentials implements Parcelable {
|
||||
public final URI uri;
|
||||
public final String userName, password;
|
||||
public final boolean authPreemptive;
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
@@ -31,7 +30,6 @@ public class LoginCredentials implements Parcelable {
|
||||
dest.writeSerializable(uri);
|
||||
dest.writeString(userName);
|
||||
dest.writeString(password);
|
||||
dest.writeValue(authPreemptive);
|
||||
}
|
||||
|
||||
public static final Creator CREATOR = new Creator<LoginCredentials>() {
|
||||
@@ -39,8 +37,7 @@ public class LoginCredentials implements Parcelable {
|
||||
public LoginCredentials createFromParcel(Parcel source) {
|
||||
return new LoginCredentials(
|
||||
(URI)source.readSerializable(),
|
||||
source.readString(), source.readString(),
|
||||
(boolean)source.readValue(null)
|
||||
source.readString(), source.readString()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,17 +0,0 @@
|
||||
<!--
|
||||
~ Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
||||
~ All rights reserved. This program and the accompanying materials
|
||||
~ are made available under the terms of the GNU Public License v3.0
|
||||
~ which accompanies this distribution, and is available at
|
||||
~ http://www.gnu.org/licenses/gpl.html
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zm-10,5h-2v-2h2v2zm0,-4h-2V7h2v6z"/>
|
||||
</vector>
|
||||
@@ -1,16 +0,0 @@
|
||||
<!--
|
||||
~ Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
||||
~ All rights reserved. This program and the accompanying materials
|
||||
~ are made available under the terms of the GNU Public License v3.0
|
||||
~ which accompanies this distribution, and is available at
|
||||
~ http://www.gnu.org/licenses/gpl.html
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<gradient
|
||||
android:angle="135"
|
||||
android:endColor="@color/light_green300"
|
||||
android:startColor="@color/green700"
|
||||
android:type="linear"/>
|
||||
</shape>
|
||||
@@ -51,6 +51,7 @@
|
||||
android:layout_marginBottom="32dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/license_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextView.Heading"
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||
android:textColor="@color/white"
|
||||
android:textColor="@android:color/white"
|
||||
tools:text="Account Name"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -20,11 +20,10 @@
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
|
||||
android:theme="@style/AppTheme.ActionBar"
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"/>
|
||||
android:layout_height="?attr/actionBarSize"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
style="@style/tablayout"
|
||||
app:tabMode="scrollable"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
android:theme="@style/toolbar_theme"
|
||||
style="@style/toolbar_style"
|
||||
app:navigationIcon="@drawable/ic_people_light"
|
||||
app:title="CardDAV"
|
||||
app:title="@string/account_carddav"
|
||||
android:elevation="2dp" tools:ignore="UnusedAttribute"/>
|
||||
|
||||
<ProgressBar
|
||||
@@ -79,7 +79,7 @@
|
||||
android:theme="@style/toolbar_theme"
|
||||
style="@style/toolbar_style"
|
||||
app:navigationIcon="@drawable/ic_event_light"
|
||||
app:title="CalDAV"
|
||||
app:title="@string/account_caldav"
|
||||
android:elevation="2dp" tools:ignore="UnusedAttribute"/>
|
||||
|
||||
<ProgressBar
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:typeface="monospace"
|
||||
android:inputType="textPassword"/>
|
||||
|
||||
<CheckBox
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/nav_header_height"
|
||||
android:background="@drawable/side_nav_bar"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/grey700"
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/activity_margin"
|
||||
@@ -21,14 +21,14 @@
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:layout_marginTop="24dp"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:layout_marginTop="@dimen/nav_header_vertical_spacing"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:id="@+id/sync_now"
|
||||
android:icon="@drawable/ic_sync_dark"
|
||||
android:icon="@drawable/ic_sync_action"
|
||||
android:title="@string/account_synchronize_now"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/settings"
|
||||
android:icon="@drawable/ic_settings_dark"
|
||||
android:icon="@drawable/ic_settings_action"
|
||||
android:title="@string/account_settings"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
android:title="@string/navigation_drawer_about"/>
|
||||
<item
|
||||
android:id="@+id/nav_app_settings"
|
||||
android:icon="@drawable/ic_settings_dark"
|
||||
android:icon="@drawable/ic_settings_action"
|
||||
android:title="@string/navigation_drawer_settings"/>
|
||||
|
||||
<item android:title="@string/navigation_drawer_news_updates">
|
||||
@@ -37,7 +37,7 @@
|
||||
android:title="@string/navigation_drawer_website"/>
|
||||
<item
|
||||
android:id="@+id/nav_faq"
|
||||
android:icon="@drawable/ic_help_dark"
|
||||
android:icon="@drawable/ic_help_action"
|
||||
android:title="@string/navigation_drawer_faq"/>
|
||||
<item
|
||||
android:id="@+id/nav_forums"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:icon="@drawable/ic_share_dark"
|
||||
android:icon="@drawable/ic_share_action"
|
||||
android:title="@string/send"
|
||||
app:showAsAction="always"
|
||||
android:onClick="onShare"/>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<item
|
||||
android:id="@+id/help"
|
||||
android:title="@string/help"
|
||||
android:icon="@drawable/ic_help_dark"
|
||||
android:icon="@drawable/ic_help_action"
|
||||
app:showAsAction="always"
|
||||
android:onClick="showHelp">
|
||||
</item>
|
||||
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/mipmap/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
@@ -7,6 +7,9 @@
|
||||
<string name="please_wait">Bitte warten …</string>
|
||||
<string name="send">Senden</string>
|
||||
<!--startup dialogs-->
|
||||
<string name="startup_battery_optimization">Akku-Leistungsoptimierung</string>
|
||||
<string name="startup_battery_optimization_message">Android kann die DAVdroid-Synchronisierung in ein paar Tagen reduzieren/deaktivieren. Um dies zu verhindern, muss die Akku-Leistungsoptimierung deaktiviert werden.</string>
|
||||
<string name="startup_battery_optimization_disable">Für DAVdroid deaktivieren</string>
|
||||
<string name="startup_dont_show_again">Nicht mehr anzeigen</string>
|
||||
<string name="startup_development_version">DAVdroid Vorab-Version</string>
|
||||
<string name="startup_development_version_message">Dies ist eine Vorschauversion von DAVdroid. Mit konstruktiven Rückmeldungen und Vorschlägen können Sie uns helfen, DAVdroid zu verbessern.</string>
|
||||
@@ -54,12 +57,12 @@
|
||||
<string name="app_settings_reset_hints_summary">Hinweise, die deaktiviert wurden, wieder anzeigen</string>
|
||||
<string name="app_settings_reset_hints_success">Alle Hinweise werden wieder angezeigt</string>
|
||||
<string name="app_settings_security">Sicherheit</string>
|
||||
<string name="app_settings_reset_trusted_certificates">Vertrauenswürdige Zertifikate zurücksetzen</string>
|
||||
<string name="app_settings_reset_trusted_certificates_summary">Entzieht allen zuvor akzeptierten Zertifikaten die Vertrauenswürdigkeit</string>
|
||||
<plurals name="app_settings_reset_trusted_certificates_success">
|
||||
<item quantity="one">Dem Zertifikat wird nicht mehr vertraut</item>
|
||||
<item quantity="other">%d Zertifikaten wird nicht mehr vertraut</item>
|
||||
</plurals>
|
||||
<string name="app_settings_distrust_system_certs">Systemzertifikaten nicht vertrauen</string>
|
||||
<string name="app_settings_distrust_system_certs_on">System- und installierten CAs wird nicht vertraut</string>
|
||||
<string name="app_settings_distrust_system_certs_off">System- und installierten CAs wird vertraut (empfohlen)</string>
|
||||
<string name="app_settings_reset_certificates">Zertifikat-Vertrauen zurücksetzen</string>
|
||||
<string name="app_settings_reset_certificates_summary">Setzt angenommene/abgelehnte Zertifikate zurück</string>
|
||||
<string name="app_settings_reset_certificates_success">Alle Informationen über angenommene/abgelehnte Zertifikate wurden zurückgesetzt</string>
|
||||
<string name="app_settings_debug">Fehlersuche</string>
|
||||
<string name="app_settings_log_to_external_storage">Protokollierung in externe Datei</string>
|
||||
<string name="app_settings_log_to_external_storage_on">Protokolliert auf externen Speicher, falls möglich</string>
|
||||
@@ -101,7 +104,6 @@
|
||||
<string name="login_user_name">Benutzername</string>
|
||||
<string name="login_user_name_required">Benutzername wird benötigt</string>
|
||||
<string name="login_base_url">Basis-URL</string>
|
||||
<string name="login_auth_preemptive">Präemptive Authentifizierung (empfohlen, aber nicht kompatibel mit Digest-Auth.)</string>
|
||||
<string name="login_login">Anmelden</string>
|
||||
<string name="login_back">Zurück</string>
|
||||
<string name="login_create_account">Konto anlegen</string>
|
||||
@@ -122,9 +124,6 @@
|
||||
<string name="settings_password">Passwort</string>
|
||||
<string name="settings_password_summary">Aktualisieren Sie Ihr Passwort gemäß den Server-Einstellungen.</string>
|
||||
<string name="settings_enter_password">Passwort eingeben:</string>
|
||||
<string name="settings_preemptive">Präemptive Authentifizierung</string>
|
||||
<string name="settings_preemptive_on">Anmeldeinformationen werden bei jeder Anfrage gesendet (empfohlen)</string>
|
||||
<string name="settings_preemptive_off">Anmeldeinformationen werden nur auf Anforderung gesendet</string>
|
||||
<string name="settings_sync">Synchronisierung</string>
|
||||
<string name="settings_sync_interval_contacts">Häufigkeit der Kontakte-Synchronisierung</string>
|
||||
<string name="settings_sync_summary_manually">Nur manuell</string>
|
||||
@@ -237,4 +236,7 @@
|
||||
<item>Speichern des Synchronisierungzustands</item>
|
||||
</string-array>
|
||||
<string name="sync_error_unauthorized">Benutzername/Passwort falsch</string>
|
||||
<!--cert4android-->
|
||||
<string name="certificate_notification_connection_security">DAVdroid: Verbindungssicherheit</string>
|
||||
<string name="trust_certificate_unknown_certificate_found">DAVdroid ist auf ein unbekanntes Zertifikat gestoßen. Ist dieses vertrauenswürdig?</string>
|
||||
</resources>
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- AddAccountActivity -->
|
||||
|
||||
<style name="account_list_card">
|
||||
<item name="android:layout_width">600dp</item>
|
||||
</style>
|
||||