Compare commits

...

12 Commits

Author SHA1 Message Date
Geno e21d49efc8 Merge tag '2.9.13' into develop 2021-05-10 12:38:11 +02:00
Daniel Gultsch a5ad2b7fc6 version bump to 2.9.13 + changelog 2021-05-03 16:21:10 +02:00
Daniel Gultsch 5d3ad6e36b pulled translations from transifex 2021-05-03 13:14:09 +02:00
Daniel Gultsch 6d91551f59 use onAddTrack instead of deprecated onAddStream 2021-05-03 13:06:42 +02:00
Daniel Gultsch 0717f9ba18 upgrade libwebrtc to m90 and enable extmap-allow-mixed 2021-05-03 09:48:46 +02:00
Daniel Gultsch ac7855a332 show domains in manual cert accept dialog 2021-05-03 08:28:03 +02:00
Daniel Gultsch a40b82b85b version bump to 2.9.12 + changelog 2021-05-02 08:23:00 +02:00
Daniel Gultsch c5e90199c3 trigger registration dialog on roster;ibr=y only if no accounts are configured
fixes #4065
2021-04-30 11:32:42 +02:00
Daniel Gultsch 53908dd56e pulled translations from transifex 2021-04-30 11:00:03 +02:00
Daniel Gultsch 9d9514a091 Add User-Agent to all HTTP calls 2021-04-30 10:54:36 +02:00
Daniel Gultsch bc58fb0fbd Always verify hostname/domain
There might be corner cases where it is required to use self signed
certificates. However there should be no corner cases where it is
required to use a wrong domain name. This commit swaps out the
MemorizingHostnameVerifier that let users accept wrong domains with the
standard XmppDomainVerifier.

closes #4066
2021-04-30 09:55:22 +02:00
Daniel Gultsch ec061bedc1 always show contact permission explain dialog on Quicksy
Until now Conversations and Quicksy would only disply the dialog that explains
why we want contact read permissions after the user rejected the request once

(following Android design guidelines and `shouldShowRequestPermissionRationale()`)

However for PlayStore policy this is no longer enough and the app needs to
explain and ask for consent before starting to upload the data.

This commit now displays the explain dialog immediately before asking for the
first time.
2021-04-24 08:20:30 +02:00
39 changed files with 796 additions and 399 deletions

View File

@ -11,7 +11,7 @@ android:
- '.+'
before_script:
- mkdir libs
- wget -O libs/libwebrtc-m89.aar https://gultsch.de/files/libwebrtc-m89.aar
- wget -O libs/libwebrtc-m90.aar https://gultsch.de/files/libwebrtc-m90.aar
script:
- ./gradlew assembleQuicksyFreeCompatDebug
- ./gradlew assembleQuicksyFreeSystemDebug

View File

@ -1,5 +1,14 @@
# Changelog
### Version 2.9.13
* minor A/V improvements
### Version 2.9.12
* Always verify domain name. No user overwrite
* Support roster pre authentication
### Version 2.9.11
* Fixed 'No Connectivity' issues on Android 7.1

View File

@ -77,7 +77,7 @@ dependencies {
implementation 'com.google.guava:guava:30.1-android'
quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.12.18'
// implementation fileTree(include: ['libwebrtc-m89.aar'], dir: 'libs')
// implementation fileTree(include: ['libwebrtc-m90.aar'], dir: 'libs')
implementation 'org.webrtc:google-webrtc:1.0.32006'
}
@ -93,13 +93,14 @@ android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
versionCode 42013
versionName "2.9.11"
versionCode 42015
versionName "2.9.13"
archivesBaseName += "-$versionName"
applicationId "eu.sum7.conversations"
resValue "string", "applicationId", applicationId
resValue "string", "app_name", "Conv6ations"
buildConfigField "String", "LOGTAG", "\"conver6ations\""
def appName = "Conv6ations"
resValue "string", "app_name", appName
buildConfigField "String", "APP_NAME", "\"$appName\"";
}
@ -129,9 +130,11 @@ android {
quicksy {
dimension "mode"
applicationId = "im.quicksy.client"
resValue "string", "app_name", "Quicksy"
resValue "string", "applicationId", applicationId
buildConfigField "String", "LOGTAG", "\"quicksy\""
def appName = "Quicksy"
resValue "string", "app_name", appName
buildConfigField "String", "APP_NAME", "\"$appName\"";
}
conversations {

View File

@ -0,0 +1,3 @@
• Always verify domain name. No user overwrite
• Support roster pre authentication
• minor A/V improvements

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pick_a_server">Chọn nhà cung cấp XMPP của bạn</string>
<string name="use_conversations.im">Sử dụng conversations.im</string>
<string name="create_new_account">Tạo tài khoản mới</string>
<string name="do_you_have_an_account">Bạn đã có tài khoản XMPP chưa? Điều này có thể đúng nếu bạn đang dùng một ứng dụng khách cho XMPP khác hoặc đã sử dụng Conversations trước đó. Nếu không, bạn có thể tạo tài khoản XMPP mới ngay bây giờ.\nGợi ý: Một số nhà cung cấp email cũng cung cấp tài khoản XMPP.</string>
<string name="server_select_text">XMPP là một mạng nhắn tin ngay lập tức không phụ thuộc vào nhà cung cấp. Bạn có thể sử dụng ứng dụng khách này với bất kỳ máy chủ XMPP nào mà bạn chọn.\nTuy nhiên, vì sự thuận tiện của bạn, chúng tôi đã làm cho việc tạo tài khoản trên conversations.im¹ được dễ dàng; một nhà cung cấp đặc biệt phù hợp với việc sử dụng Conversations.</string>
<string name="magic_create_text_on_x">Bạn đã được mời vào %1$s. Chúng tôi sẽ hướng dẫn bạn trong quá trình tạo tài khoản.\nKhi chọn %1$s là nhà cung cấp, bạn sẽ có thể giao tiếp với những người dùng của các nhà cung cấp khác bằng cách đưa cho họ địa chỉ XMPP đầy đủ của bạn.</string>
<string name="magic_create_text_fixed">Bạn đã được mời vào %1$s. Một tên người dùng đã được chọn sẵn cho bạn. Chúng tôi sẽ hướng dẫn bạn trong quá trình tạo tài khoản.\nBạn sẽ có thể giao tiếp với những người dùng của các nhà cung cấp khác bằng cách đưa cho họ địa chỉ XMPP đầy đủ của bạn.</string>
<string name="your_server_invitation">Lời mời vào máy chủ của bạn</string>
<string name="improperly_formatted_provisioning">Mã cung cấp không được định dạng đúng</string>
<string name="tap_share_button_send_invite">Nhấn nút chia sẻ để gửi lời mời vào %1$s đến liên hệ của bạn.</string>
<string name="if_contact_is_nearby_use_qr">Nếu liên hệ của bạn ở gần đây, họ cũng có thể quét mã ở dưới để chấp nhận lời mời của bạn.</string>
<string name="easy_invite_share_text">Hãy tham gia vào %1$s và trò chuyện với tôi: %2$s</string>
<string name="share_invite_with">Chia sẻ lời mời với...</string>
</resources>

View File

@ -6,6 +6,7 @@ import android.net.Uri;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import eu.siacs.conversations.crypto.XmppDomainVerifier;
import eu.siacs.conversations.xmpp.Jid;
@ -35,7 +36,7 @@ public final class Config {
return (ENCRYPTION_MASK & (ENCRYPTION_MASK - 1)) != 0;
}
public static final String LOGTAG = BuildConfig.LOGTAG;
public static final String LOGTAG = BuildConfig.APP_NAME.toLowerCase(Locale.US);
public static final Jid BUG_REPORTS = Jid.of("bugs@chat.sum7.eu");
public static final Uri HELP = Uri.parse("https://sum7.eu/chat");
@ -107,7 +108,6 @@ public final class Config {
public static final boolean USE_BOOKMARKS2 = false;
public static final boolean PROCESS_EXTMAP_ALLOW_MIXED = false;
public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb
public static final boolean USE_DIRECT_JINGLE_CANDIDATES = true;
public static final boolean DISABLE_HTTP_UPLOAD = false;

View File

@ -1,10 +1,11 @@
package eu.siacs.conversations.crypto;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
public interface DomainHostnameVerifier extends HostnameVerifier {
boolean verify(String domain, String hostname, SSLSession sslSession);
boolean verify(String domain, String hostname, SSLSession sslSession) throws SSLPeerUnverifiedException;
}

View File

@ -3,6 +3,8 @@ package eu.siacs.conversations.crypto;
import android.util.Log;
import android.util.Pair;
import com.google.common.collect.ImmutableList;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERTaggedObject;
@ -18,15 +20,17 @@ import java.io.IOException;
import java.net.IDN;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
public class XmppDomainVerifier implements DomainHostnameVerifier {
public class XmppDomainVerifier {
private static final String LOGTAG = "XmppDomainVerifier";
@ -94,68 +98,93 @@ public class XmppDomainVerifier implements DomainHostnameVerifier {
return false;
}
@Override
public boolean verify(final String unicodeDomain,final String unicodeHostname, SSLSession sslSession) {
public boolean verify(final String unicodeDomain, final String unicodeHostname, SSLSession sslSession) throws SSLPeerUnverifiedException {
final String domain = IDN.toASCII(unicodeDomain);
final String hostname = unicodeHostname == null ? null : IDN.toASCII(unicodeHostname);
final Certificate[] chain = sslSession.getPeerCertificates();
if (chain.length == 0 || !(chain[0] instanceof X509Certificate)) {
return false;
}
final X509Certificate certificate = (X509Certificate) chain[0];
final List<String> commonNames = getCommonNames(certificate);
if (isSelfSigned(certificate)) {
if (commonNames.size() == 1 && matchDomain(domain, commonNames)) {
Log.d(LOGTAG, "accepted CN in self signed cert as work around for " + domain);
return true;
}
}
try {
final Certificate[] chain = sslSession.getPeerCertificates();
if (chain.length == 0 || !(chain[0] instanceof X509Certificate)) {
return false;
}
final X509Certificate certificate = (X509Certificate) chain[0];
final List<String> commonNames = getCommonNames(certificate);
if (isSelfSigned(certificate)) {
if (commonNames.size() == 1 && matchDomain(domain, commonNames)) {
Log.d(LOGTAG, "accepted CN in self signed cert as work around for " + domain);
return true;
}
}
final Collection<List<?>> alternativeNames = certificate.getSubjectAlternativeNames();
final List<String> xmppAddrs = new ArrayList<>();
final List<String> srvNames = new ArrayList<>();
final List<String> domains = new ArrayList<>();
if (alternativeNames != null) {
for (List<?> san : alternativeNames) {
final Integer type = (Integer) san.get(0);
if (type == 0) {
final Pair<String, String> otherName = parseOtherName((byte[]) san.get(1));
if (otherName != null && otherName.first != null && otherName.second != null) {
switch (otherName.first) {
case SRV_NAME:
srvNames.add(otherName.second.toLowerCase(Locale.US));
break;
case XMPP_ADDR:
xmppAddrs.add(otherName.second.toLowerCase(Locale.US));
break;
default:
Log.d(LOGTAG, "oid: " + otherName.first + " value: " + otherName.second);
}
}
} else if (type == 2) {
final Object value = san.get(1);
if (value instanceof String) {
domains.add(((String) value).toLowerCase(Locale.US));
}
}
}
}
if (srvNames.size() == 0 && xmppAddrs.size() == 0 && domains.size() == 0) {
domains.addAll(commonNames);
}
Log.d(LOGTAG, "searching for " + domain + " in srvNames: " + srvNames + " xmppAddrs: " + xmppAddrs + " domains:" + domains);
final ValidDomains validDomains = parseValidDomains(certificate);
Log.d(LOGTAG, "searching for " + domain + " in srvNames: " + validDomains.srvNames + " xmppAddrs: " + validDomains.xmppAddrs + " domains:" + validDomains.domains);
if (hostname != null) {
Log.d(LOGTAG, "also trying to verify hostname " + hostname);
}
return xmppAddrs.contains(domain)
|| srvNames.contains("_xmpp-client." + domain)
|| matchDomain(domain, domains)
|| (hostname != null && matchDomain(hostname, domains));
return validDomains.xmppAddrs.contains(domain)
|| validDomains.srvNames.contains("_xmpp-client." + domain)
|| matchDomain(domain, validDomains.domains)
|| (hostname != null && matchDomain(hostname, validDomains.domains));
} catch (final Exception e) {
return false;
}
}
public static ValidDomains parseValidDomains(final X509Certificate certificate) throws CertificateParsingException {
final List<String> commonNames = getCommonNames(certificate);
final Collection<List<?>> alternativeNames = certificate.getSubjectAlternativeNames();
final List<String> xmppAddrs = new ArrayList<>();
final List<String> srvNames = new ArrayList<>();
final List<String> domains = new ArrayList<>();
if (alternativeNames != null) {
for (List<?> san : alternativeNames) {
final Integer type = (Integer) san.get(0);
if (type == 0) {
final Pair<String, String> otherName = parseOtherName((byte[]) san.get(1));
if (otherName != null && otherName.first != null && otherName.second != null) {
switch (otherName.first) {
case SRV_NAME:
srvNames.add(otherName.second.toLowerCase(Locale.US));
break;
case XMPP_ADDR:
xmppAddrs.add(otherName.second.toLowerCase(Locale.US));
break;
default:
Log.d(LOGTAG, "oid: " + otherName.first + " value: " + otherName.second);
}
}
} else if (type == 2) {
final Object value = san.get(1);
if (value instanceof String) {
domains.add(((String) value).toLowerCase(Locale.US));
}
}
}
}
if (srvNames.size() == 0 && xmppAddrs.size() == 0 && domains.size() == 0) {
domains.addAll(commonNames);
}
return new ValidDomains(xmppAddrs, srvNames, domains);
}
public static final class ValidDomains {
final List<String> xmppAddrs;
final List<String> srvNames;
final List<String> domains;
private ValidDomains(List<String> xmppAddrs, List<String> srvNames, List<String> domains) {
this.xmppAddrs = xmppAddrs;
this.srvNames = srvNames;
this.domains = domains;
}
public List<String> all() {
ImmutableList.Builder<String> all = new ImmutableList.Builder<>();
all.addAll(xmppAddrs);
all.addAll(srvNames);
all.addAll(domains);
return all.build();
}
}
private boolean isSelfSigned(X509Certificate certificate) {
try {
certificate.verify(certificate.getPublicKey());
@ -164,9 +193,4 @@ public class XmppDomainVerifier implements DomainHostnameVerifier {
return false;
}
}
@Override
public boolean verify(String domain, SSLSession sslSession) {
return verify(domain, null, sslSession);
}
}

View File

@ -635,6 +635,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
REGISTRATION_INVALID_TOKEN(true,false),
REGISTRATION_PASSWORD_TOO_WEAK(true, false),
TLS_ERROR,
TLS_ERROR_DOMAIN,
INCOMPATIBLE_SERVER,
TOR_NOT_AVAILABLE,
DOWNGRADE_ATTACK,
@ -701,6 +702,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
return R.string.account_status_regis_invalid_token;
case TLS_ERROR:
return R.string.account_status_tls_error;
case TLS_ERROR_DOMAIN:
return R.string.account_status_tls_error_domain;
case INCOMPATIBLE_SERVER:
return R.string.account_status_incompatible_server;
case TOR_NOT_AVAILABLE:

View File

@ -12,6 +12,7 @@ import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import eu.siacs.conversations.BuildConfig;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@ -65,7 +66,6 @@ public abstract class AbstractGenerator {
Namespace.JINGLE_MESSAGE
};
protected XmppConnectionService mXmppConnectionService;
private String mVersion = null;
AbstractGenerator(XmppConnectionService service) {
this.mXmppConnectionService = service;
@ -77,18 +77,11 @@ public abstract class AbstractGenerator {
}
String getIdentityVersion() {
if (mVersion == null) {
this.mVersion = PhoneHelper.getVersionName(mXmppConnectionService);
}
return this.mVersion;
return BuildConfig.VERSION_NAME;
}
String getIdentityName() {
return mXmppConnectionService.getString(R.string.app_name);
}
public String getUserAgent() {
return mXmppConnectionService.getString(R.string.app_name) + '/' + getIdentityVersion();
return BuildConfig.APP_NAME;
}
String getIdentityType() {

View File

@ -25,12 +25,19 @@ public class PresenceGenerator extends AbstractGenerator {
return packet;
}
public PresencePacket requestPresenceUpdatesFrom(Contact contact) {
public PresencePacket requestPresenceUpdatesFrom(final Contact contact) {
return requestPresenceUpdatesFrom(contact, null);
}
public PresencePacket requestPresenceUpdatesFrom(final Contact contact, final String preAuth) {
PresencePacket packet = subscription("subscribe", contact);
String displayName = contact.getAccount().getDisplayName();
if (!TextUtils.isEmpty(displayName)) {
packet.addChild("nick", Namespace.NICK).setContent(displayName);
}
if (preAuth != null) {
packet.addChild("preauth", Namespace.PARS).setAttribute("token", preAuth);
}
return packet;
}

View File

@ -19,10 +19,10 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import eu.siacs.conversations.BuildConfig;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Message;
@ -41,7 +41,24 @@ public class HttpConnectionManager extends AbstractConnectionManager {
public static final Executor EXECUTOR = Executors.newFixedThreadPool(4);
private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient();
public static final OkHttpClient OK_HTTP_CLIENT;
static {
OK_HTTP_CLIENT = new OkHttpClient.Builder()
.addInterceptor(chain -> {
final Request original = chain.request();
final Request modified = original.newBuilder()
.header("User-Agent", getUserAgent())
.build();
return chain.proceed(modified);
})
.build();
}
public static String getUserAgent() {
return String.format("%s/%s", BuildConfig.APP_NAME, BuildConfig.VERSION_NAME);
}
public HttpConnectionManager(XmppConnectionService service) {
super(service);
@ -124,7 +141,6 @@ public class HttpConnectionManager extends AbstractConnectionManager {
private void setupTrustManager(final OkHttpClient.Builder builder, final boolean interactive) {
final X509TrustManager trustManager;
final HostnameVerifier hostnameVerifier = mXmppConnectionService.getMemorizingTrustManager().wrapHostnameVerifier(new StrictHostnameVerifier(), interactive);
if (interactive) {
trustManager = mXmppConnectionService.getMemorizingTrustManager().getInteractive();
} else {
@ -133,7 +149,7 @@ public class HttpConnectionManager extends AbstractConnectionManager {
try {
final SSLSocketFactory sf = new TLSSocketFactory(new X509TrustManager[]{trustManager}, mXmppConnectionService.getRNG());
builder.sslSocketFactory(sf, trustManager);
builder.hostnameVerifier(hostnameVerifier);
builder.hostnameVerifier(new StrictHostnameVerifier());
} catch (final KeyManagementException | NoSuchAlgorithmException ignored) {
}
}

View File

@ -50,7 +50,7 @@ public class ChannelDiscoveryService {
}
void initializeMuclumbusService() {
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
final OkHttpClient.Builder builder = HttpConnectionManager.OK_HTTP_CLIENT.newBuilder();
if (service.useTorToConnect()) {
builder.proxy(HttpConnectionManager.getProxy());
}

View File

@ -42,16 +42,15 @@ import android.util.SparseArray;
import androidx.appcompat.app.AppCompatActivity;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.io.CharStreams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@ -63,12 +62,10 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
@ -76,14 +73,12 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.DomainHostnameVerifier;
import eu.siacs.conversations.crypto.XmppDomainVerifier;
import eu.siacs.conversations.entities.MTMDecision;
import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.persistance.FileBackend;
@ -101,12 +96,12 @@ import eu.siacs.conversations.ui.MemorizingActivity;
*/
public class MemorizingTrustManager {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
final static String DECISION_INTENT = "de.duenndns.ssl.DECISION";
public final static String DECISION_INTENT_ID = DECISION_INTENT + ".decisionId";
public final static String DECISION_INTENT_CERT = DECISION_INTENT + ".cert";
public final static String DECISION_TITLE_ID = DECISION_INTENT + ".titleId";
final static String DECISION_INTENT_CHOICE = DECISION_INTENT + ".decisionChoice";
final static String NO_TRUST_ANCHOR = "Trust anchor for certification path not found.";
private static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
private static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
@ -114,7 +109,6 @@ public class MemorizingTrustManager {
private static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z");
private static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z");
private final static Logger LOGGER = Logger.getLogger(MemorizingTrustManager.class.getName());
private final static int NOTIFICATION_ID = 100509;
static String KEYSTORE_DIR = "KeyStore";
static String KEYSTORE_FILE = "KeyStore.bks";
private static int decisionId = 0;
@ -168,20 +162,6 @@ public class MemorizingTrustManager {
this.defaultTrustManager = getTrustManager(null);
}
/**
* Changes the path for the KeyStore file.
* <p>
* The actual filename relative to the app's directory will be
* <code>app_<i>dirname</i>/<i>filename</i></code>.
*
* @param dirname directory to store the KeyStore.
* @param filename file name for the KeyStore.
*/
public static void setKeyStoreFile(String dirname, String filename) {
KEYSTORE_DIR = dirname;
KEYSTORE_FILE = filename;
}
private static boolean isIp(final String server) {
return server != null && (
PATTERN_IPV4.matcher(server).matches()
@ -217,9 +197,7 @@ public class MemorizingTrustManager {
MessageDigest md = MessageDigest.getInstance(digest);
md.update(cert.getEncoded());
return hexString(md.digest());
} catch (java.security.cert.CertificateEncodingException e) {
return e.getMessage();
} catch (java.security.NoSuchAlgorithmException e) {
} catch (CertificateEncodingException | NoSuchAlgorithmException e) {
return e.getMessage();
}
}
@ -240,7 +218,7 @@ public class MemorizingTrustManager {
}
}
void init(Context m) {
void init(final Context m) {
master = m;
masterHandler = new Handler(m.getMainLooper());
notificationManager = (NotificationManager) master.getSystemService(Context.NOTIFICATION_SERVICE);
@ -263,36 +241,6 @@ public class MemorizingTrustManager {
appKeyStore = loadAppKeyStore();
}
/**
* Binds an Activity to the MTM for displaying the query dialog.
* <p>
* This is useful if your connection is run from a service that is
* triggered by user interaction -- in such cases the activity is
* visible and the user tends to ignore the service notification.
* <p>
* You should never have a hidden activity bound to MTM! Use this
* function in onResume() and @see unbindDisplayActivity in onPause().
*
* @param act Activity to be bound
*/
public void bindDisplayActivity(AppCompatActivity act) {
foregroundAct = act;
}
/**
* Removes an Activity from the MTM display stack.
* <p>
* Always call this function when the Activity added with
* {@link #bindDisplayActivity(AppCompatActivity)} is hidden.
*
* @param act Activity to be unbound
*/
public void unbindDisplayActivity(AppCompatActivity act) {
// do not remove if it was overridden by a different activity
if (foregroundAct == act)
foregroundAct = null;
}
/**
* Get a list of all certificate aliases stored in MTM.
*
@ -307,21 +255,6 @@ public class MemorizingTrustManager {
}
}
/**
* Get a certificate for a given alias.
*
* @param alias the certificate's alias as returned by {@link #getCertificates()}.
* @return the certificate associated with the alias or <tt>null</tt> if none found.
*/
public Certificate getCertificate(String alias) {
try {
return appKeyStore.getCertificate(alias);
} catch (KeyStoreException e) {
// this should never happen, however...
throw new RuntimeException(e);
}
}
/**
* Removes the given certificate from MTMs key store.
*
@ -340,32 +273,6 @@ public class MemorizingTrustManager {
keyStoreUpdated();
}
/**
* Creates a new hostname verifier supporting user interaction.
*
* <p>This method creates a new {@link HostnameVerifier} that is bound to
* the given instance of {@link MemorizingTrustManager}, and leverages an
* existing {@link HostnameVerifier}. The returned verifier performs the
* following steps, returning as soon as one of them succeeds:
* /p>
* <ol>
* <li>Success, if the wrapped defaultVerifier accepts the certificate.</li>
* <li>Success, if the server certificate is stored in the keystore under the given hostname.</li>
* <li>Ask the user and return accordingly.</li>
* <li>Failure on exception.</li>
* </ol>
*
* @param defaultVerifier the {@link HostnameVerifier} that should perform the actual check
* @return a new hostname verifier using the MTM's key store
* @throws IllegalArgumentException if the defaultVerifier parameter is null
*/
public DomainHostnameVerifier wrapHostnameVerifier(final HostnameVerifier defaultVerifier, final boolean interactive) {
if (defaultVerifier == null)
throw new IllegalArgumentException("The default verifier may not be null");
return new MemorizingHostnameVerifier(defaultVerifier, interactive);
}
X509TrustManager getTrustManager(KeyStore ks) {
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
@ -452,16 +359,8 @@ public class MemorizingTrustManager {
}
}
private boolean isExpiredException(Throwable e) {
do {
if (e instanceof CertificateExpiredException)
return true;
e = e.getCause();
} while (e != null);
return false;
}
public void checkCertTrusted(X509Certificate[] chain, String authType, String domain, boolean isServer, boolean interactive)
private void checkCertTrusted(X509Certificate[] chain, String authType, String domain, boolean isServer, boolean interactive)
throws CertificateException {
LOGGER.log(Level.FINE, "checkCertTrusted(" + chain + ", " + authType + ", " + isServer + ")");
try {
@ -470,13 +369,8 @@ public class MemorizingTrustManager {
appTrustManager.checkServerTrusted(chain, authType);
else
appTrustManager.checkClientTrusted(chain, authType);
} catch (CertificateException ae) {
} catch (final CertificateException ae) {
LOGGER.log(Level.FINER, "checkCertTrusted: appTrustManager failed", ae);
// if the cert is stored in our appTrustManager, we ignore expiredness
if (isExpiredException(ae)) {
LOGGER.log(Level.INFO, "checkCertTrusted: accepting expired certificate from keystore");
return;
}
if (isCertKnown(chain[0])) {
LOGGER.log(Level.INFO, "checkCertTrusted: accepting cert already stored in keystore");
return;
@ -632,14 +526,24 @@ public class MemorizingTrustManager {
return myId;
}
private void certDetails(StringBuffer si, X509Certificate c) {
SimpleDateFormat validityDateFormater = new SimpleDateFormat("yyyy-MM-dd");
private void certDetails(final StringBuffer si, final X509Certificate c, final boolean showValidFor) {
si.append("\n");
si.append(c.getSubjectDN().toString());
if (showValidFor) {
try {
si.append("Valid for: ");
si.append(Joiner.on(", ").join(XmppDomainVerifier.parseValidDomains(c).all()));
} catch (final CertificateParsingException e) {
si.append("Unable to parse Certificate");
}
si.append("\n");
} else {
si.append(c.getSubjectDN());
}
si.append("\n");
si.append(validityDateFormater.format(c.getNotBefore()));
si.append(DATE_FORMAT.format(c.getNotBefore()));
si.append(" - ");
si.append(validityDateFormater.format(c.getNotAfter()));
si.append(DATE_FORMAT.format(c.getNotAfter()));
si.append("\nSHA-256: ");
si.append(certHash(c, "SHA-256"));
si.append("\nSHA-1: ");
@ -652,7 +556,7 @@ public class MemorizingTrustManager {
private String certChainMessage(final X509Certificate[] chain, CertificateException cause) {
Throwable e = cause;
LOGGER.log(Level.FINE, "certChainMessage for " + e);
StringBuffer si = new StringBuffer();
final StringBuffer si = new StringBuffer();
if (e.getCause() != null) {
e = e.getCause();
// HACK: there is no sane way to check if the error is a "trust anchor
@ -667,46 +571,13 @@ public class MemorizingTrustManager {
si.append(master.getString(R.string.mtm_connect_anyway));
si.append("\n\n");
si.append(master.getString(R.string.mtm_cert_details));
for (X509Certificate c : chain) {
certDetails(si, c);
si.append('\n');
for(int i = 0; i < chain.length; ++i) {
certDetails(si, chain[i], i == 0);
}
return si.toString();
}
private String hostNameMessage(X509Certificate cert, String hostname) {
StringBuffer si = new StringBuffer();
si.append(master.getString(R.string.mtm_hostname_mismatch, hostname));
si.append("\n\n");
try {
Collection<List<?>> sans = cert.getSubjectAlternativeNames();
if (sans == null) {
si.append(cert.getSubjectDN());
si.append("\n");
} else for (List<?> altName : sans) {
Object name = altName.get(1);
if (name instanceof String) {
si.append("[");
si.append(altName.get(0));
si.append("] ");
si.append(name);
si.append("\n");
}
}
} catch (CertificateParsingException e) {
e.printStackTrace();
si.append("<Parsing error: ");
si.append(e.getLocalizedMessage());
si.append(">\n");
}
si.append("\n");
si.append(master.getString(R.string.mtm_connect_anyway));
si.append("\n\n");
si.append(master.getString(R.string.mtm_cert_details));
certDetails(si, cert);
return si.toString();
}
/**
* Returns the top-most entry of the activity stack.
*
@ -764,17 +635,6 @@ public class MemorizingTrustManager {
}
}
boolean interactHostname(X509Certificate cert, String hostname) {
switch (interact(hostNameMessage(cert, hostname), R.string.mtm_accept_servername)) {
case MTMDecision.DECISION_ALWAYS:
storeCert(hostname, cert);
case MTMDecision.DECISION_ONCE:
return true;
default:
return false;
}
}
public X509TrustManager getNonInteractive(String domain) {
return new NonInteractiveMemorizingTrustManager(domain);
}
@ -791,57 +651,6 @@ public class MemorizingTrustManager {
return new InteractiveMemorizingTrustManager(null);
}
class MemorizingHostnameVerifier implements DomainHostnameVerifier {
private final HostnameVerifier defaultVerifier;
private final boolean interactive;
public MemorizingHostnameVerifier(HostnameVerifier wrapped, boolean interactive) {
this.defaultVerifier = wrapped;
this.interactive = interactive;
}
@Override
public boolean verify(String domain, String hostname, SSLSession session) {
LOGGER.log(Level.FINE, "hostname verifier for " + domain + ", trying default verifier first");
// if the default verifier accepts the hostname, we are done
if (defaultVerifier instanceof DomainHostnameVerifier) {
if (((DomainHostnameVerifier) defaultVerifier).verify(domain, hostname, session)) {
return true;
}
} else {
if (defaultVerifier.verify(domain, session)) {
return true;
}
}
// otherwise, we check if the hostname is an alias for this cert in our keystore
try {
X509Certificate cert = (X509Certificate) session.getPeerCertificates()[0];
//Log.d(TAG, "cert: " + cert);
if (cert.equals(appKeyStore.getCertificate(domain.toLowerCase(Locale.US)))) {
LOGGER.log(Level.FINE, "certificate for " + domain + " is in our keystore. accepting.");
return true;
} else {
LOGGER.log(Level.FINE, "server " + domain + " provided wrong certificate, asking user.");
if (interactive) {
return interactHostname(cert, domain);
} else {
return false;
}
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean verify(String domain, SSLSession sslSession) {
return verify(domain, null, sslSession);
}
}
private class NonInteractiveMemorizingTrustManager implements X509TrustManager {
private final String domain;

View File

@ -3448,15 +3448,23 @@ public class XmppConnectionService extends Service {
}
}
public void createContact(Contact contact, boolean autoGrant) {
public void createContact(final Contact contact, final boolean autoGrant) {
createContact(contact, autoGrant, null);
}
public void createContact(final Contact contact, final boolean autoGrant, final String preAuth) {
if (autoGrant) {
contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
contact.setOption(Contact.Options.ASKING);
}
pushContactToServer(contact);
pushContactToServer(contact, preAuth);
}
public void pushContactToServer(final Contact contact) {
pushContactToServer(contact, null);
}
private void pushContactToServer(final Contact contact, final String preAuth) {
contact.resetOption(Contact.Options.DIRTY_DELETE);
contact.setOption(Contact.Options.DIRTY_PUSH);
final Account account = contact.getAccount();
@ -3472,7 +3480,7 @@ public class XmppConnectionService extends Service {
sendPresencePacket(account, mPresenceGenerator.sendPresenceUpdatesTo(contact));
}
if (ask) {
sendPresencePacket(account, mPresenceGenerator.requestPresenceUpdatesFrom(contact));
sendPresencePacket(account, mPresenceGenerator.requestPresenceUpdatesFrom(contact, preAuth));
}
} else {
syncRoster(contact.getAccount());

View File

@ -5,24 +5,26 @@ import android.content.Intent;
import android.preference.Preference;
import android.util.AttributeSet;
import eu.siacs.conversations.BuildConfig;
import eu.siacs.conversations.R;
import eu.siacs.conversations.utils.PhoneHelper;
public class AboutPreference extends Preference {
public AboutPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final String appName = context.getString(R.string.app_name);
setSummary(appName +' '+ PhoneHelper.getVersionName(context));
setTitle(context.getString(R.string.title_activity_about_x, appName));
setSummaryAndTitle(context);
}
public AboutPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
final String appName = context.getString(R.string.app_name);
setSummary(appName +' '+ PhoneHelper.getVersionName(context));
setTitle(context.getString(R.string.title_activity_about_x, appName));
setSummaryAndTitle(context);
}
private void setSummaryAndTitle(final Context context) {
setSummary(String.format("%s %s", BuildConfig.APP_NAME, BuildConfig.VERSION_NAME));
setTitle(context.getString(R.string.title_activity_about_x, BuildConfig.APP_NAME));
}
@Override
protected void onClick() {
super.onClick();

View File

@ -39,6 +39,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
@ -525,7 +526,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
} else if (contact.showInRoster()) {
throw new EnterJidDialog.JidError(getString(R.string.contact_already_exists));
} else {
xmppConnectionService.createContact(contact, true);
final String preAuth = invite == null ? null : invite.getParameter(XmppUri.PARAMETER_PRE_AUTH);
xmppConnectionService.createContact(contact, true, preAuth);
if (invite != null && invite.hasFingerprints()) {
xmppConnectionService.verifyFingerprints(contact, invite.getFingerprints());
}
@ -731,7 +733,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
if (mRequestedContactsPermission.compareAndSet(false, true)) {
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) {
if (QuickConversationsService.isQuicksy() || shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
final AtomicBoolean requestPermission = new AtomicBoolean(false);
builder.setTitle(R.string.sync_with_contacts);
@ -740,20 +742,26 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
} else {
builder.setMessage(getString(R.string.sync_with_contacts_long, getString(R.string.app_name)));
}
builder.setPositiveButton(R.string.next, (dialog, which) -> {
@StringRes int confirmButtonText;
if (QuickConversationsService.isConversations()) {
confirmButtonText = R.string.next;
} else {
confirmButtonText = R.string.confirm;
}
builder.setPositiveButton(confirmButtonText, (dialog, which) -> {
if (requestPermission.compareAndSet(false, true)) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
}
});
builder.setOnDismissListener(dialog -> {
if (requestPermission.compareAndSet(false, true)) {
if (QuickConversationsService.isConversations() && requestPermission.compareAndSet(false, true)) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
}
});
builder.setCancelable(false);
builder.setCancelable(QuickConversationsService.isQuicksy());
final AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.setCanceledOnTouchOutside(QuickConversationsService.isQuicksy());
dialog.setOnShowListener(dialogInterface -> {
final TextView tv = dialog.findViewById(android.R.id.message);
if (tv != null) {

View File

@ -95,7 +95,8 @@ public class UriHandlerActivity extends AppCompatActivity {
}
@Override
public void onNewIntent(Intent intent) {
public void onNewIntent(final Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
@ -120,7 +121,7 @@ public class UriHandlerActivity extends AppCompatActivity {
startActivity(intent);
return;
}
if (xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.getParameter(XmppUri.PARAMETER_IBR))) {
if (accounts.size() == 0 && xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.getParameter(XmppUri.PARAMETER_IBR))) {
intent = SignupUtils.getTokenRegistrationIntent(this, jid.getDomain(), preAuth);
intent.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
startActivity(intent);

View File

@ -35,17 +35,4 @@ public class PhoneHelper {
cursor.close();
return uri == null ? null : Uri.parse(uri);
}
public static String getVersionName(Context context) {
final String packageName = context == null ? null : context.getPackageName();
if (packageName != null) {
try {
return context.getPackageManager().getPackageInfo(packageName, 0).versionName;
} catch (final PackageManager.NameNotFoundException | RuntimeException e) {
return "unknown";
}
} else {
return "unknown";
}
}
}

View File

@ -46,6 +46,7 @@ import java.util.regex.Matcher;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509KeyManager;
@ -401,7 +402,7 @@ public class XmppConnection implements Runnable {
return tag != null && tag.isStart("stream");
}
private TlsFactoryVerifier getTlsFactoryVerifier() throws NoSuchAlgorithmException, KeyManagementException, IOException {
private SSLSocketFactory getSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
final SSLContext sc = SSLSocketHelper.getSSLContext();
final MemorizingTrustManager trustManager = this.mXmppConnectionService.getMemorizingTrustManager();
final KeyManager[] keyManager;
@ -412,9 +413,7 @@ public class XmppConnection implements Runnable {
}
final String domain = account.getServer();
sc.init(keyManager, new X509TrustManager[]{mInteractive ? trustManager.getInteractive(domain) : trustManager.getNonInteractive(domain)}, mXmppConnectionService.getRNG());
final SSLSocketFactory factory = sc.getSocketFactory();
final DomainHostnameVerifier verifier = trustManager.wrapHostnameVerifier(new XmppDomainVerifier(), mInteractive);
return new TlsFactoryVerifier(factory, verifier);
return sc.getSocketFactory();
}
@Override
@ -789,19 +788,25 @@ public class XmppConnection implements Runnable {
}
private SSLSocket upgradeSocketToTls(final Socket socket) throws IOException {
final TlsFactoryVerifier tlsFactoryVerifier;
final SSLSocketFactory sslSocketFactory;
try {
tlsFactoryVerifier = getTlsFactoryVerifier();
sslSocketFactory = getSSLSocketFactory();
} catch (final NoSuchAlgorithmException | KeyManagementException e) {
throw new StateChangingException(Account.State.TLS_ERROR);
}
final InetAddress address = socket.getInetAddress();
final SSLSocket sslSocket = (SSLSocket) tlsFactoryVerifier.factory.createSocket(socket, address.getHostAddress(), socket.getPort(), true);
final SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, address.getHostAddress(), socket.getPort(), true);
SSLSocketHelper.setSecurity(sslSocket);
SSLSocketHelper.setHostname(sslSocket, IDN.toASCII(account.getServer()));
SSLSocketHelper.setApplicationProtocol(sslSocket, "xmpp-client");
if (!tlsFactoryVerifier.verifier.verify(account.getServer(), this.verifiedHostname, sslSocket.getSession())) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS certificate verification failed");
final XmppDomainVerifier xmppDomainVerifier = new XmppDomainVerifier();
try {
if (!xmppDomainVerifier.verify(account.getServer(), this.verifiedHostname, sslSocket.getSession())) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": TLS certificate domain verification failed");
FileBackend.close(sslSocket);
throw new StateChangingException(Account.State.TLS_ERROR_DOMAIN);
}
} catch (final SSLPeerUnverifiedException e) {
FileBackend.close(sslSocket);
throw new StateChangingException(Account.State.TLS_ERROR);
}
@ -1711,19 +1716,6 @@ public class XmppConnection implements Runnable {
UNKNOWN
}
private static class TlsFactoryVerifier {
private final SSLSocketFactory factory;
private final DomainHostnameVerifier verifier;
TlsFactoryVerifier(final SSLSocketFactory factory, final DomainHostnameVerifier verifier) throws IOException {
this.factory = factory;
this.verifier = verifier;
if (factory == null || verifier == null) {
throw new IOException("could not setup ssl");
}
}
}
private class MyKeyManager implements X509KeyManager {
@Override
public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {

View File

@ -215,7 +215,7 @@ public class SessionDescription {
mediaAttributes.put("extmap", id + " " + uri);
}
if (Config.PROCESS_EXTMAP_ALLOW_MIXED && description.hasChild("extmap-allow-mixed", Namespace.JINGLE_RTP_HEADER_EXTENSIONS)) {
if (description.hasChild("extmap-allow-mixed", Namespace.JINGLE_RTP_HEADER_EXTENSIONS)) {
mediaAttributes.put("extmap-allow-mixed", "");
}

View File

@ -136,13 +136,6 @@ public class WebRTCWrapper {
@Override
public void onAddStream(MediaStream mediaStream) {
Log.d(EXTENDED_LOGGING_TAG, "onAddStream(numAudioTracks=" + mediaStream.audioTracks.size() + ",numVideoTracks=" + mediaStream.videoTracks.size() + ")");
final List<VideoTrack> videoTracks = mediaStream.videoTracks;
if (videoTracks.size() > 0) {
remoteVideoTrack = videoTracks.get(0);
Log.d(Config.LOGTAG, "remote video track enabled?=" + remoteVideoTrack.enabled());
} else {
Log.d(Config.LOGTAG, "no remote video tracks found");
}
}
@Override
@ -164,10 +157,9 @@ public class WebRTCWrapper {
public void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {
final MediaStreamTrack track = rtpReceiver.track();
Log.d(EXTENDED_LOGGING_TAG, "onAddTrack(kind=" + (track == null ? "null" : track.kind()) + ",numMediaStreams=" + mediaStreams.length + ")");
if (track != null) {
Log.d(EXTENDED_LOGGING_TAG,"onAddTrack(class="+track.getClass().getName()+")");
if (track instanceof VideoTrack) {
remoteVideoTrack = (VideoTrack) track;
}
}
@Override

View File

@ -964,4 +964,4 @@
<string name="server_does_not_support_easy_onboarding_invites">Server nepodporuje vytváření pozvánek</string>
<string name="no_active_accounts_support_this">Žádný z aktivních účtů tuto funkci nepodporuje</string>
<string name="backup_started_message">Zálohování zahájeno. Budete upozorněni, jakmile bude záloha hotova.</string>
</resources>
</resources>

View File

@ -960,4 +960,4 @@
<string name="server_does_not_support_easy_onboarding_invites">Server understøtter ikke generering af invitationer</string>
<string name="no_active_accounts_support_this">Ingen aktive konti understøtter denne funktion</string>
<string name="backup_started_message">Sikkerhedskopieringen er startet. Du får en notifikation, når den er afsluttet.</string>
</resources>
</resources>

View File

@ -150,6 +150,7 @@
<string name="error_file_not_found">Datei nicht gefunden</string>
<string name="error_io_exception">Allgemeiner Fehler. Vielleicht hast du keinen Speicherplatz mehr?</string>
<string name="error_security_exception_during_image_copy">Die App, mit der du das Bild ausgesucht hast, hat keine Rechte eingeräumt, um das Bild zu betrachten.\n\n<small>Benutze einen anderen Dateimanager, um ein Bild auszuwählen</small>.</string>
<string name="error_security_exception">Die App, die du zum Teilen dieser Datei verwendet hast, hat nicht die erforderlichen Berechtigungen bereitgestellt.</string>
<string name="account_status_unknown">Unbekannt</string>
<string name="account_status_disabled">Vorübergehend abgeschaltet</string>
<string name="account_status_online">Online</string>
@ -164,6 +165,7 @@
<string name="account_status_regis_not_sup">Registrierung wird vom Server nicht unterstützt</string>
<string name="account_status_regis_invalid_token">Ungültiger Registrierungstoken</string>
<string name="account_status_tls_error">TLS-Aushandlung fehlgeschlagen</string>
<string name="account_status_tls_error_domain">Domain nicht überprüfbar</string>
<string name="account_status_policy_violation">Verstoß gegen die Richtlinien</string>
<string name="account_status_incompatible_server">Inkompatibler Server</string>
<string name="account_status_stream_error">Stream Fehler</string>
@ -960,4 +962,5 @@
<string name="server_does_not_support_easy_onboarding_invites">Server unterstützt keine Generierung von Einladungen</string>
<string name="no_active_accounts_support_this">Keine aktiven Konten unterstützen diese Funktion</string>
<string name="backup_started_message">Das Backup wurde gestartet. Du bekommst eine Benachrichtigung sobald es fertig ist.</string>
<string name="unable_to_enable_video">Video kann nicht aktiviert werden.</string>
</resources>

View File

@ -150,6 +150,7 @@
<string name="error_file_not_found">Arquivo non atopado</string>
<string name="error_io_exception">Erro xeral de I/O. ¿Quedaches sen espazo no disco?</string>
<string name="error_security_exception_during_image_copy">A app utilizada para escoller esta imaxe non deu permisos suficientes para ler o ficheiro.\n\n<small>Usa un xestor de ficheiros diferente para escoller a imaxe</small></string>
<string name="error_security_exception">A app que usaches para compartir este ficheiro non concedeu os permisos suficientes.</string>
<string name="account_status_unknown">Descoñecido</string>
<string name="account_status_disabled">Desactivado temporalmente</string>
<string name="account_status_online">Conectado</string>
@ -164,6 +165,7 @@
<string name="account_status_regis_not_sup">O servidor non permite o rexistro</string>
<string name="account_status_regis_invalid_token">O testemuño de rexistro non é válido</string>
<string name="account_status_tls_error">Fallo a negociación TLS</string>
<string name="account_status_tls_error_domain">Dominio non verificable</string>
<string name="account_status_policy_violation">Violación da política</string>
<string name="account_status_incompatible_server">Servidor incompatible</string>
<string name="account_status_stream_error">Erro de fluxo</string>
@ -269,7 +271,7 @@
<string name="account_already_exists">Esta conta xa existe</string>
<string name="next">Seguinte</string>
<string name="server_info_session_established">Sesión establecida</string>
<string name="skip">Saltar</string>
<string name="skip">Omitir</string>
<string name="disable_notifications">Desactivar notificacións</string>
<string name="enable">Habilitar</string>
<string name="conference_requires_password">A conversa en grupo require contrasinal</string>
@ -960,4 +962,5 @@
<string name="server_does_not_support_easy_onboarding_invites">O servidor non soporta a creación de convites</string>
<string name="no_active_accounts_support_this">Ningunha conta activa soporta esta función</string>
<string name="backup_started_message">Comezou a creación da copia de apoio. Recibirás unha notificación cando remate.</string>
<string name="unable_to_enable_video">Non se puido activar o vídeo.</string>
</resources>

View File

@ -960,4 +960,4 @@
<string name="server_does_not_support_easy_onboarding_invites">Il server non supporta la generazione di inviti</string>
<string name="no_active_accounts_support_this">Nessun account attivo supporta questa funzione</string>
<string name="backup_started_message">Il backup è iniziato. Riceverai una notifica una volta completato.</string>
</resources>
</resources>

View File

@ -7,7 +7,7 @@
<string name="action_end_conversation">会話を閉じる</string>
<string name="action_contact_details">連絡先の詳細</string>
<string name="action_muc_details">グループチャットの詳細</string>
<string name="channel_details">チャンネルの詳細</string>
<string name="channel_details">談話室の詳細</string>
<string name="action_add_account">アカウントを追加</string>
<string name="action_edit_contact">名前を編集</string>
<string name="action_add_phone_book">アドレス帳に追加</string>
@ -234,11 +234,11 @@
<string name="save_as_bookmark">ブックマークとして保存</string>
<string name="delete_bookmark">ブックマークを削除</string>
<string name="destroy_room">グループチャットを破棄する</string>
<string name="destroy_channel">チャンネルを破棄する</string>
<string name="destroy_channel">談話室を破棄する</string>
<string name="destroy_room_dialog">このグループチャットを破棄してもよろしいですか?\n\n<b>警告:</b> グループチャットはサーバーから完全に削除されます。</string>
<string name="destroy_channel_dialog">この公開談話室を破棄してもよろしいですか?\n\n<b>警告:</b> チャンネルはサーバーから完全に削除されます。</string>
<string name="destroy_channel_dialog">この公開談話室を破棄してもよろしいですか?\n\n<b>警告:</b> 談話室はサーバーから完全に削除されます。</string>
<string name="could_not_destroy_room">グループチャットを破棄できません</string>
<string name="could_not_destroy_channel">チャンネルを破棄できません</string>
<string name="could_not_destroy_channel">談話室を破棄できません</string>
<string name="action_edit_subject">グループチャットの題を編集</string>
<string name="topic">トピック</string>
<string name="joining_conference">グループチャットに参加しています…</string>
@ -286,7 +286,7 @@
<string name="pref_quiet_hours_summary">消音時間の間、通知は無音になります</string>
<string name="pref_expert_options_other">その他</string>
<string name="pref_autojoin">ブックマークと同期</string>
<string name="pref_autojoin_summary">ブックマークに従って、グループチャットに自動参加します。</string>
<string name="pref_autojoin_summary">ブックマークに従って、グループチャットに自動参加します。</string>
<string name="toast_message_omemo_fingerprint">OMEMO フィンガープリントをクリップボードにコピーしました</string>
<string name="conference_banned">このグループチャットから追い出されています</string>
<string name="conference_members_only">このグループチャットはメンバー制です</string>
@ -379,10 +379,10 @@
<string name="grant_owner_privileges">所有者権限を付与</string>
<string name="remove_owner_privileges">所有者権限を取消</string>
<string name="remove_from_room">グループチャットから削除</string>
<string name="remove_from_channel">チャンネルから削除</string>
<string name="remove_from_channel">談話室から削除</string>
<string name="could_not_change_affiliation">%s の所属を変更できません</string>
<string name="ban_from_conference">グループチャットから追い出す</string>
<string name="ban_from_channel">チャンネルから追い出す</string>
<string name="ban_from_channel">談話室から追い出す</string>
<string name="removing_from_public_conference">あなたは公開談話室から %s を削除しようとしています。その唯一の手段は、そのユーザーを永久に追い出すことです。</string>
<string name="ban_now">今すぐ追い出す</string>
<string name="could_not_change_role">%s の役割を変更できません</string>
@ -390,7 +390,7 @@
<string name="channel_options">公開談話室の環境設定</string>
<string name="members_only">非公開、メンバーのみ</string>
<string name="non_anonymous">XMPPアドレスを誰でも見れるようにする</string>
<string name="moderated">チャンネルの調停をする</string>
<string name="moderated">談話室の調停をする</string>
<string name="you_are_not_participating">あなたは参加していません</string>
<string name="modified_conference_options">グループチャットのオプションが変更されました!</string>
<string name="could_not_modify_conference_options">グループチャットのオプションを変更できませんでした</string>
@ -633,7 +633,7 @@
<plurals name="months">
<item quantity="other">%dか月</item>
</plurals>
<string name="pref_automatically_delete_messages">自動メッセージ削除</string>
<string name="pref_automatically_delete_messages">自動メッセージ削除</string>
<string name="pref_automatically_delete_messages_description">設定された期間よりも古いメッセージを、このデバイスから自動的に削除します。</string>
<string name="encrypting_message">メッセージの暗号化中</string>
<string name="not_fetching_history_retention_period">ローカル保存期間のためにメッセージを取得しません。</string>
@ -737,6 +737,11 @@
<string name="notification_group_status_information">ステータス情報</string>
<string name="error_channel_name">接続の問題</string>
<string name="error_channel_description">この通知カテゴリーは、アカウントへの接続に問題があった場合に、通知を表示するために使用されます。</string>
<string name="notification_group_messages">メッセージ</string>
<string name="notification_group_calls">通話</string>
<string name="messages_channel_name">メッセージ</string>
<string name="incoming_calls_channel_name">着信</string>
<string name="ongoing_calls_channel_name">発信</string>
<string name="silent_messages_channel_description">この通知グループは、音を鳴らしてはいけない通知を表示するために使用します。例えば、他のデバイスでアクティブになっているときなどです (猶予期間)。</string>
<string name="delivery_failed_channel_name">配信に失敗</string>
<string name="pref_message_notification_settings">メッセージ通知設定</string>
@ -802,9 +807,9 @@
<string name="install_orbot">Orbot をインストール</string>
<string name="start_orbot">Orbot を開始</string>
<string name="no_market_app_installed">マーケットアプリがインストールされていません。</string>
<string name="group_chat_will_make_your_jabber_id_public">このチャンネルでは、あなたのXMPPアドレスを公開します</string>
<string name="group_chat_will_make_your_jabber_id_public">この談話室では、あなたのXMPPアドレスを公開します</string>
<string name="ebook">電子書籍</string>
<string name="video_original">原物(非圧縮)</string>
<string name="video_original">原物 (非圧縮)</string>
<string name="open_with">…で開く</string>
<string name="set_profile_picture">Conversations プロフィール写真</string>
<string name="choose_account">アカウントを選択</string>
@ -820,15 +825,15 @@
<string name="join_public_channel">公開談話室に参加</string>
<string name="create_private_group_chat">非公開グループチャットを作成</string>
<string name="create_public_channel">公開談話室を作成</string>
<string name="create_dialog_channel_name">チャンネル</string>
<string name="create_dialog_channel_name">談話室</string>
<string name="xmpp_address">XMPP アドレス</string>
<string name="please_enter_name">チャンネルの名前をご記入ください</string>
<string name="please_enter_name">談話室の名前をご記入ください</string>
<string name="please_enter_xmpp_address">XMPP アドレスをご記入ください</string>
<string name="this_is_an_xmpp_address">これは XMPP アドレスです。名前をご記入ください。</string>
<string name="creating_channel">公開談話室を作成中…</string>
<string name="channel_already_exists">このチャンネルは既に存在します</string>
<string name="joined_an_existing_channel">存在しているチャンネルに参加しています</string>
<string name="unable_to_set_channel_configuration">チャンネルの環境設定を保存できません</string>
<string name="channel_already_exists">この談話室は既に存在します</string>
<string name="joined_an_existing_channel">存在している談話室に参加しています</string>
<string name="unable_to_set_channel_configuration">談話室の環境設定を保存できません</string>
<string name="allow_participants_to_edit_subject">誰にでもトピックの編集を許可</string>
<string name="allow_participants_to_invite_others">誰にでも他の人の招待を許可</string>
<string name="anyone_can_edit_subject">誰でもトピックを編集できます。</string>
@ -844,16 +849,16 @@
<string name="search_participants">参加者を検索</string>
<string name="file_too_large">ファイルが大きすぎます</string>
<string name="attach">添付</string>
<string name="discover_channels">チャンネルを発見</string>
<string name="search_channels">チャンネルを検索</string>
<string name="discover_channels">談話室発見</string>
<string name="search_channels">談話室を検索</string>
<string name="channel_discovery_opt_in_title">プライバシー侵害の可能性あり!</string>
<string name="channel_discover_opt_in_message"><![CDATA[チャンネル発見は、第三者のサービスである<a href="https://search.jabber.network">search.jabber.networkを利用します。<br><br>この機能を使うと、あなたののIPアドレスや検索キーワードがそのサービスに送信されます。詳しくは、<a href="https://search.jabber.network/privacy">プライバシーポリシー</a>をご覧ください。]]></string>
<string name="channel_discover_opt_in_message"><![CDATA[談話室発見は、第三者のサービスである<a href="https://search.jabber.network">search.jabber.networkを利用します。<br><br>この機能を使うと、あなたののIPアドレスや検索キーワードがそのサービスに送信されます。詳しくは、<a href="https://search.jabber.network/privacy">プライバシーポリシー</a>をご覧ください。]]></string>
<string name="i_already_have_an_account">私は既にアカウントを持っています</string>
<string name="add_existing_account">存在するアカウントを追加</string>
<string name="register_new_account">新しいアカウントを登録</string>
<string name="this_looks_like_a_domain">これはドメインアドレスのようです</string>
<string name="add_anway">とにかく追加</string>
<string name="this_looks_like_channel">これはチャンネルアドレスのようです</string>
<string name="this_looks_like_channel">これは談話室アドレスのようです</string>
<string name="share_backup_files">バックアップファイルを共有</string>
<string name="conversations_backup">Conversations のバックアップ</string>
<string name="event">出来事</string>
@ -864,11 +869,11 @@
<string name="unable_to_perform_this_action">この操作を実行できません</string>
<string name="open_join_dialog">公開談話室に参加…</string>
<string name="sharing_application_not_grant_permission">共有アプリがこのファイルへのアクセスを許可していませんでした。</string>
<string name="group_chats_and_channels"><![CDATA[グループチャットとチャンネル]]></string>
<string name="group_chats_and_channels"><![CDATA[グループチャットと談話室]]></string>
<string name="jabber_network">jabber.network</string>
<string name="local_server">ローカルサーバー</string>
<string name="pref_channel_discovery_summary">ほとんどのユーザーは、公開されている XMPP エコシステム全体からより良い提案を得るために、jabber.networkを選択するはずです。</string>
<string name="pref_channel_discovery">チャンネル発見方法</string>
<string name="pref_channel_discovery">談話室発見方法</string>
<string name="please_enable_an_account">アカウントを有効にしてください</string>
<string name="make_call">通話をする</string>
<string name="rtp_state_incoming_call">通話着信</string>
@ -917,7 +922,7 @@
<string name="record_voice_mail">音声メールを録音</string>
<string name="play_audio">音声再生</string>
<string name="pause_audio">音声一時中断</string>
<string name="add_contact_or_create_or_join_group_chat">連絡先を追加、作成またはグループチャットに参加、またはチャンネルを発見する</string>
<string name="add_contact_or_create_or_join_group_chat">連絡先を追加、作成またはグループチャットに参加、または談話室を発見する</string>
<plurals name="view_users">
<item quantity="other">%1$d人の参加者を表示</item>
</plurals>
@ -932,4 +937,4 @@
<string name="server_does_not_support_easy_onboarding_invites">サーバーは招待をサポートしていません</string>
<string name="no_active_accounts_support_this">この機能をサポートするアクティブなアカウントがありません</string>
<string name="backup_started_message">バックアップを開始しました。 バックアップが完了すると通知が届きます。</string>
</resources>
</resources>

View File

@ -2,131 +2,285 @@
<resources>
<string name="action_settings">ക്രമീകരണങ്ങൾ</string>
<string name="action_add">പുതിയ സംഭാഷണം</string>
<string name="action_accounts">അക്കൗണ്ടുകൾ നിയന്ത്രിക്കൂ</string>
<string name="action_account">അക്കൗണ്ട് നിയന്ത്രിക്കൂ</string>
<string name="action_end_conversation">സംഭാഷണം അടയ്ക്കൂ</string>
<string name="action_contact_details">കോൺ‌ടാക്റ്റ് വിശദാംശങ്ങൾ</string>
<string name="action_muc_details">ഗ്രൂപ്പ് ചാറ്റ് വിശദാംശങ്ങൾ</string>
<string name="channel_details">ചാനൽ വിവരങ്ങൾ</string>
<string name="action_add_account">അക്കൗണ്ട് ചേർക്കൂ</string>
<string name="action_edit_contact">പെര് തിരുത്തുക</string>
<string name="action_block_contact">കോൺ‌ടാക്റ്റ് തടയുക</string>
<string name="action_unblock_contact">കോൺ‌ടാക്റ്റ് തടഞ്ഞത് മാറ്റുക</string>
<string name="action_block_domain">മേഖല തടയുക</string>
<string name="action_block_participant">പങ്കാളിയെ തടയുക</string>
<string name="title_activity_settings">ക്രമീകരണങ്ങൾ</string>
<string name="title_activity_start_conversation">സംഭാഷണം ആരംഭിക്കൂ</string>
<string name="title_activity_choose_contact">കോൺ‌ടാക്റ്റ് തിരഞ്ഞെടുക്കുക</string>
<string name="title_activity_choose_contacts">കോൺ‌ടാക്റ്റുകൾ തിരഞ്ഞെടുക്കുക</string>
<string name="title_activity_share_via_account">അക്കൗണ്ട് വഴി പങ്കിടുക</string>
<string name="title_activity_block_list">തടഞ്ഞവയുടെ പട്ടിക</string>
<string name="just_now">ഇപ്പോൾ</string>
<string name="minute_ago">1 മിനിറ്റ് മുമ്പ്</string>
<string name="minutes_ago">%d മിനിറ്റ് മുമ്പ്</string>
<plurals name="x_unread_conversations">
<item quantity="one">%d വായിക്കാത്ത സംഭാഷണം</item>
<item quantity="other">%d വായിക്കാത്ത സംഭാഷണങ്ങൾ</item>
</plurals>
<string name="sending">അയയ്ക്കുന്നു...</string>
<string name="pgp_message">OpenPGP സുരക്ഷിതമാക്കിയ സന്ദേശം</string>
<string name="nick_in_use">വിളിപ്പേര് ഇതിനകം ഉപയോഗത്തിലാണ്</string>
<string name="invalid_muc_nick">അസാധുവായ വിളിപ്പേര്</string>
<string name="admin">അഡ്മിൻ</string>
<string name="owner">ഉടമ</string>
<string name="moderator">മോഡറേറ്റർ</string>
<string name="participant">പങ്കെടുക്കുന്നയാൾ</string>
<string name="visitor">സന്ദർശകൻ</string>
<string name="block_domain_text">%s-ൽ നിന്ന് എല്ലാ കോൺ‌ടാക്റ്റുകളും തടയണോ?</string>
<string name="contact_blocked">കോൺ‌ടാക്റ്റ് തടഞ്ഞു</string>
<string name="blocked">തടഞ്ഞു</string>
<string name="change_password_on_server">സെർവറിൽ രഹസ്യവാക്ക് മാറ്റുക</string>
<string name="share_with">ഇതുമായി പങ്കിടുക…</string>
<string name="start_conversation">സംഭാഷണം ആരംഭിക്കുക</string>
<string name="invite_contact">കോൺ‌ടാക്റ്റിനെ ക്ഷണിക്കുക</string>
<string name="invite">ക്ഷണിക്കൂ</string>
<string name="contacts">കോൺ‌ടാക്റ്റുകൾ</string>
<string name="contact">കോൺ‌ടാക്റ്റ്</string>
<string name="cancel">റദ്ദാക്കൂ</string>
<string name="set">സജ്ജമാക്കൂ</string>
<string name="add">ചേർക്കൂ</string>
<string name="edit">തിരുത്തുക</string>
<string name="delete">ഇല്ലാതാക്കൂ</string>
<string name="block">തടയുക</string>
<string name="unblock">തടഞ്ഞത് മാറ്റുക</string>
<string name="save">സംരക്ഷിക്കൂ</string>
<string name="ok">ശരി</string>
<string name="crash_report_title">%1$s തകർന്നു</string>
<string name="send_now">ഇപ്പോൾ അയയ്‌ക്കൂ</string>
<string name="send_never">ഒരിക്കലും ചോദിക്കരുത്</string>
<string name="attach_file">ഫയൽ ഉൾപ്പെടുത്തുക</string>
<string name="add_contact">കോൺടാക്റ്റ് ചേർക്കൂ</string>
<string name="preparing_images">ചിത്രങ്ങൾ അയയ്ക്കാൻ തയ്യാറാകുന്നു</string>
<string name="sharing_files_please_wait">ഫയലുകൾ പങ്കിടുന്നു. കാത്തിരിക്കൂ…</string>
<string name="action_clear_history">ചരിത്രം മായ്ക്കൂ</string>
<string name="clear_conversation_history">സംഭാഷണ ചരിത്രം മായ്ക്കൂ</string>
<string name="delete_file_dialog">ഫയൽ ഇല്ലാതാക്കൂ</string>
<string name="choose_presence">ഉപകരണം തിരഞ്ഞെടുക്കൂ</string>
<string name="send_unencrypted_message">സുരക്ഷിതമല്ലാത്ത സന്ദേശം അയയ്കൂ</string>
<string name="send_message">സന്ദേശം അയയ്ക്കൂ</string>
<string name="send_message_to_x">%s-ന് (ക്ക്) സന്ദേശം അയയ്ക്കൂ</string>
<string name="send_omemo_message">OMEMO സുരക്ഷിതമാക്കിയ സന്ദേശം അയയ്ക്കൂ</string>
<string name="send_omemo_x509_message">v\\OMEMO സുരക്ഷിതമാക്കിയ സന്ദേശം അയയ്ക്കൂ</string>
<string name="send_pgp_message">OpenPGP സുരക്ഷിതമാക്കിയ സന്ദേശം അയയ്ക്കൂ</string>
<string name="your_nick_has_been_changed">പുതിയ വിളിപ്പേര് ഉപയോഗത്തിലുള്ളതാണ്</string>
<string name="openkeychain_required">OpenKeychain</string>
<string name="restart">പുനരാരംഭിക്കൂ</string>
<string name="install">സ്ഥാപിക്കൂ</string>
<string name="openkeychain_not_installed">OpenKeychain ഇൻസ്റ്റാൾ ചെയ്യുക</string>
<string name="waiting">കാത്തിരിക്കുന്നു...</string>
<string name="no_pgp_key">OpenPGP കീ ഒന്നും കണ്ടെത്തിയില്ല</string>
<string name="pref_general">പൊതുവായവ</string>
<string name="pref_accept_files">ഫയലുകൾ സ്വീകരിക്കൂ</string>
<string name="pref_attachments">അറ്റാച്ചുമെന്റുകൾ</string>
<string name="pref_notification_settings">അറിയിപ്പ്</string>
<string name="pref_led">LED അറിയിപ്പ്</string>
<string name="pref_ringtone">റിംഗ്‌ടോൺ</string>
<string name="pref_notification_sound">അറിയിപ്പ് ശബ്‌ദം</string>
<string name="pref_call_ringtone_summary">ഇൻകമിംഗ് കോളുകൾക്കുള്ള റിംഗ്‌ടോൺ</string>
<string name="pref_advanced_options">വിപുലമായ</string>
<string name="pref_never_send_crash">ഒരിക്കലും ക്രാഷ് റിപ്പോർട്ടുകൾ അയയ്‌ക്കരുത്</string>
<string name="pref_confirm_messages">സന്ദേശങ്ങൾ ഉറപ്പാക്കൂ</string>
<string name="pref_ui_options">UI</string>
<string name="accept">സ്വീകരിക്കുക</string>
<string name="error">ഒരു പിശക് സംഭവിച്ചു</string>
<string name="your_account">നിങ്ങളുടെ അക്കൗണ്ട്</string>
<string name="send_presence_updates">സാന്നിധ്യ അപ്‌ഡേറ്റുകൾ അയയ്‌ക്കുക</string>
<string name="attach_choose_picture">ചിത്രം തിരഞ്ഞെടുക്കൂ</string>
<string name="attach_take_picture">ഫോട്ടോ എടുക്കൂ</string>
<string name="error_not_an_image_file">നിങ്ങൾ തിരഞ്ഞെടുത്ത ഫയൽ ഒരു ചിത്രം അല്ല</string>
<string name="error_file_not_found">ഫയൽ കണ്ടില്ല</string>
<string name="account_status_unknown">അജ്ഞാതം</string>
<string name="account_status_online">ഓൺലൈൻ</string>
<string name="account_status_offline">ഓഫ്‌ലൈൻ</string>
<string name="account_status_not_found">സെർവർ കണ്ടെത്തിയില്ല</string>
<string name="account_status_regis_conflict">ഉപയോക്തൃനാമം ഇതിനകം നിലവിലുണ്ട്</string>
<string name="account_status_regis_success">രജിസ്ട്രേഷൻ പൂർത്തിയായി</string>
<string name="encryption_choice_unencrypted">സുരക്ഷിതമല്ലാത്ത</string>
<string name="encryption_choice_otr">OTR</string>
<string name="encryption_choice_pgp">OpenPGP</string>
<string name="encryption_choice_omemo">OMEMO</string>
<string name="mgmt_account_delete">അക്കൗണ്ട് ഇല്ലാതാക്കൂ</string>
<string name="mgmt_account_publish_avatar">അവതാർ പ്രസിദ്ധീകരിക്കൂ</string>
<string name="mgmt_account_publish_pgp">OpenPGP പബ്ലിക് കീ പ്രസിദ്ധീകരിക്കുക</string>
<string name="unpublish_pgp">OpenPGP പബ്ലിക് കീ നീക്കം ചെയ്യുക</string>
<string name="mgmt_account_are_you_sure">നിങ്ങള്ക്ക് ഉറപ്പാണോ?</string>
<string name="attach_record_voice">ശബ്‌ദം റെക്കോർഡുചെയ്യൂ</string>
<string name="account_settings_jabber_id">XMPP വിലാസം</string>
<string name="block_jabber_id">XMPP വിലാസം തടയുക</string>
<string name="account_settings_example_jabber_id">username@example.com</string>
<string name="password">രഹസ്യവാക്ക്</string>
<string name="invalid_jid">ഈ XMPP വിലാസ‍ം അസാധുവാണ്</string>
<string name="error_out_of_memory">മെമ്മറി തീർന്നു. ചിത്രം വളരെ വലുതാണ്</string>
<string name="server_info_show_more">സെർവർ വിവരം</string>
<string name="server_info_mam">XEP-0313: MAM</string>
<string name="server_info_available">ലഭ്യമാണ്</string>
<string name="server_info_unavailable">ലഭ്യമല്ല</string>
<string name="last_seen_now">അവസാനം കണ്ടത് ഇപ്പോൾ</string>
<string name="last_seen_min">അവസാനമായി കണ്ടത് ഒരു മിനിറ്റ് മുമ്പ്</string>
<string name="last_seen_min">അവസാനം കണ്ടത് ഒരു മിനിറ്റ് മുമ്പ്</string>
<string name="last_seen_mins">അവസാനം കണ്ടത് %d മിനിറ്റ് മുമ്പ്</string>
<string name="last_seen_hour">അവസാനം കണ്ടത് ഒരു മണിക്കൂർ മുമ്പ്</string>
<string name="last_seen_hours">അവസാനം കണ്ടത് %d മണിക്കൂർ മുമ്പ്</string>
<string name="last_seen_day">അവസാനം കണ്ടത് ഒരു ദിവസം മുമ്പ്</string>
<string name="last_seen_days">അവസാനം കണ്ടത് %d ദിവസം മുമ്പ്</string>
<string name="omemo_fingerprint">OMEMO വിരലടയാളം</string>
<string name="omemo_fingerprint_x509">v\\OMEMO വിരലടയാളം</string>
<string name="other_devices">മറ്റ് ഉപകരണങ്ങൾ</string>
<string name="fetching_keys">കീകൾ ലഭ്യമാക്കുന്നു...</string>
<string name="done">ചെയ്തു</string>
<string name="decrypt">ഡീക്രിപ്റ്റ് ചെയ്യുക</string>
<string name="bookmarks">അടയാളകുറിപ്പുകൾ</string>
<string name="search">തിരയുക</string>
<string name="enter_contact">കോൺ‌ടാക്റ്റ് നൽകുക</string>
<string name="delete_contact">കോൺ‌ടാക്റ്റ് ഇല്ലാതാക്കൂ</string>
<string name="view_contact_details">കോൺ‌ടാക്റ്റ് വിവരങ്ങൾ കാണിക്കൂ</string>
<string name="block_contact">കോൺ‌ടാക്റ്റ് തടയുക</string>
<string name="unblock_contact">കോൺ‌ടാക്റ്റ് തടഞ്ഞത് മാറ്റുക</string>
<string name="create">സൃഷ്ടിക്കൂ</string>
<string name="select">തിരഞ്ഞെടുക്കൂ</string>
<string name="contact_already_exists">കോൺ‌ടാക്റ്റ് ഇതിനകം നിലവിലുണ്ട്</string>
<string name="join">ചേരുക</string>
<string name="destroy_room">ഗ്രൂപ്പ് ചാറ്റ് നശിപ്പിക്കൂ</string>
<string name="destroy_channel">ചാനൽ നശിപ്പിക്കൂ</string>
<string name="topic">വിഷയം</string>
<string name="joining_conference">ഗ്രൂപ്പ് ചാറ്റിൽ ചേരുന്നു...</string>
<string name="add_back">തിരികെ ചേർക്കൂ</string>
<string name="contact_has_read_up_to_this_point">%s ഇത് വരെ വായിച്ചിട്ടുണ്ട്</string>
<string name="contacts_have_read_up_to_this_point">%s ഇത് വരെ വായിച്ചിട്ടുണ്ട്</string>
<string name="everyone_has_read_up_to_this_point">എല്ലാവരും ഇത് വരെ വായിച്ചിട്ടുണ്ട്</string>
<string name="publish">പ്രസിദ്ധീകരിക്കൂ</string>
<string name="publishing">പ്രസിദ്ധീകരിക്കുന്നു...</string>
<string name="account_already_exists">ഈ അക്കൗണ്ട് ഇതിനകം നിലവിലുണ്ട്</string>
<string name="next">അടുത്തത്</string>
<string name="server_info_session_established">സെഷൻ സ്ഥാപിച്ചു</string>
<string name="skip">ഒഴിവാക്കൂ</string>
<string name="conference_requires_password">ഗ്രൂപ്പ് ചാറ്റിന് രഹസ്യവാക്ക് ആവശ്യമാണ്</string>
<string name="enter_password">രഹസ്യവാക്ക് നൽകുക</string>
<string name="request_now">ഇപ്പോൾ അഭ്യർത്ഥിക്കുക</string>
<string name="ignore">ഒഴിവാക്കൂ</string>
<string name="pref_security_settings">സുരക്ഷ</string>
<string name="pref_expert_options">വിദഗ്ദ്ധ ക്രമീകരണങ്ങൾ</string>
<string name="title_activity_about_x">%s-നെ കുറിച്ച്</string>
<string name="title_pref_quiet_hours_start_time">ആരംഭ സമയം</string>
<string name="pref_expert_options_other">മറ്റുള്ളവ</string>
<string name="conference_kicked">നിങ്ങളെ ഗ്രൂപ്പ് ചാറ്റിൽ നിന്ന് പുറത്താക്കി</string>
<string name="using_account">%s അക്കൗണ്ട് ഉപയോഗിക്കുന്നു</string>
<string name="check_x_filesize">%s-ന്റെ വലുപ്പം പരിശോധിക്കൂ</string>
<string name="message_options">സന്ദേശ ഓപ്ഷനുകൾ</string>
<string name="copy_original_url">യഥാർത്ഥ URL പകർത്തുക</string>
<string name="send_again">വീണ്ടും അയയ്ക്കൂ</string>
<string name="file_url">ഫയൽ URL</string>
<string name="url_copied_to_clipboard">ക്ലിപ്പ്ബോർഡിലേക്ക് URL പകർത്തി</string>
<string name="jabber_id_copied_to_clipboard">ക്ലിപ്പ്ബോർഡിലേക്ക് XMPP വിലസം പകർത്തി</string>
<string name="web_address">വെബ് വിലാസം</string>
<string name="confirm">ഉറപ്പാക്കൂ</string>
<string name="try_again">വീണ്ടും ശ്രമിക്കുക</string>
<string name="pref_create_backup">ബാക്കപ്പ് സൃഷ്ടിക്കൂ</string>
<string name="notification_create_backup_title">ബാക്കപ്പ് ഫയലുകൾ സൃഷ്ടിക്കുന്നു</string>
<string name="choose_file">ഫയൽ തിരഞ്ഞെടുക്കൂ</string>
<string name="delete_x_file">%s ഇല്ലാതാക്കൂ</string>
<string name="file">ഫയൽ</string>
<string name="open_x_file">%s തുറക്കൂ</string>
<string name="preparing_file">ഫയൽ പങ്കിടാൻ തയ്യാറാകുന്നു</string>
<string name="file_deleted">ഫയൽ ഇല്ലാതാക്കി</string>
<string name="enable_notifications">അറിയിപ്പുകൾ പ്രാപ്തമാക്കൂ</string>
<string name="account_image_description">അക്കൗണ്ട് അവതാർ</string>
<string name="clear_other_devices">ഉപകരണങ്ങൾ മായ്ക്കൂ</string>
<string name="error_trustkeys_title">എന്തോ കുഴപ്പം സംഭവിച്ചു</string>
<string name="fetching_history_from_server">സെർവറിൽ നിന്ന് ചരിത്രം ലഭ്യമാക്കുന്നു</string>
<string name="updating">പുതുക്കുന്നു...</string>
<string name="password_changed">രഹസ്യവാക്ക് മാറ്റി</string>
<string name="change_password">രഹസ്യവാക്ക് മാറ്റുക</string>
<string name="current_password">നിലവിലെ രഹസ്യവാക്ക്</string>
<string name="new_password">പുതിയ രഹസ്യവാക്ക്</string>
<string name="no_role">ഓഫ്‌ലൈൻ</string>
<string name="member">അംഗം</string>
<string name="advanced_mode">വിപുലമായ മോഡ്</string>
<string name="remove_from_room">ഗ്രൂപ്പ് ചാറ്റിൽ നിന്ന് മാറ്റുക</string>
<string name="remove_from_channel">ചാനലിൽ നിന്ന് നീക്കം ചെയ്യുക</string>
<string name="ban_from_conference">ഗ്രൂപ്പ് ചാറ്റിൽ നിന്ന് നിരോധിക്കൂ</string>
<string name="ban_from_channel">ചാനലിൽ നിന്ന് നിരോധിക്കൂ</string>
<string name="ban_now">ഇപ്പോൾ നിരോധിക്കൂ</string>
<string name="members_only">സ്വകാര്യ, അംഗങ്ങൾ മാത്രം</string>
<string name="reply">മറുപടി</string>
<string name="mark_as_read">വായിച്ചതായി കാണിക്കൂ</string>
<string name="pref_enter_is_send">എന്റെർ കീ അയയ്ക്കും</string>
<string name="audio">ശബ്ദം</string>
<string name="video">വീഡിയോ</string>
<string name="image">ചിത്രം</string>
<string name="sending_x_file">%s അയയ്ക്കുന്നു</string>
<string name="contact_is_typing">%s ടൈപ്പുചെയ്യുന്നു…</string>
<string name="dialog_manage_certs_negativebutton">റദ്ദാക്കൂ</string>
<string name="recently_used">സമീപകാലത്ത് ഉപയോഗിച്ചത്</string>
<string name="search_contacts">കോൺ‌ടാക്റ്റുകൾ തിരയുക</string>
<string name="send_private_message">സ്വകാര്യ സന്ദേശം അയയ്‌ക്കൂ</string>
<string name="username">ഉപയോക്തൃനാമം</string>
<string name="username_hint">ഉപയോക്തൃനാമം</string>
<string name="download_failed_server_not_found">ഡൗൺലോഡ് പരാജയപ്പെട്ടു: സെർവർ കണ്ടെത്തിയില്ല</string>
<string name="download_failed_file_not_found">ഡൗൺലോഡ് പരാജയപ്പെട്ടു: ഫയൽ കണ്ടെത്തിയില്ല</string>
<string name="server_info_broken">തകർന്നു</string>
<string name="pref_presence_settings">ലഭ്യത</string>
<string name="hostname_example">xmpp.example.com</string>
<string name="captcha_required">CAPTCHA നിർബന്ധമാണ്</string>
<plurals name="x_messages">
<item quantity="one">%d സന്ദേശം</item>
<item quantity="other">%d സന്ദേശങ്ങൾ</item>
</plurals>
<string name="load_more_messages">കൂടുതൽ സന്ദേശങ്ങൾ ലഭ്യമാക്കൂ</string>
<string name="notify_on_all_messages">എല്ലാ സന്ദേശങ്ങളും അറിയിക്കൂ</string>
<string name="always">എപ്പോഴും</string>
<string name="large_images_only">വലിയ ചിത്രങ്ങൾ മാത്രം</string>
<string name="correct_message">സന്ദേശം തിരുത്തുക</string>
<string name="agree_and_continue">സമ്മതിച്ച് തുടരുക</string>
<string name="create_account"> അക്കൗണ്ട് സൃഷ്ടിക്കൂ</string>
<string name="use_own_provider">എന്റെ സ്വന്തം ദാതാവിനെ ഉപയോഗിക്കുക</string>
<string name="pick_your_username">നിങ്ങളുടെ ഉപയോക്തൃനാമം തിരഞ്ഞെടുക്കൂ</string>
<string name="presence_online">ഓൺലൈൻ</string>
<string name="presence_xa">ലഭ്യമല്ല</string>
<string name="presence_dnd">തിരക്കിലാണ്</string>
<string name="invite_again">വീണ്ടും ക്ഷണിക്കൂ</string>
<string name="me">ഞാൻ</string>
<string name="allow">അനുവദിക്കൂ</string>
<string name="block_entire_domain">മുഴുവൻ മേഖലയും തടയുക</string>
<string name="online_right_now">ഇപ്പോൾ സജീവം</string>
<string name="open_website">വെബ്സൈറ്റ് തുറക്കൂ</string>
<string name="today">ഇന്ന്</string>
<string name="yesterday">ഇന്നലെ</string>
<string name="message">സന്ദേശം</string>
<string name="once">ഒരിക്കൽ</string>
<string name="share">പങ്കിടുക</string>
<string name="search_messages">സന്ദേശങ്ങൾ തിരയുക</string>
<string name="gif">GIF</string>
<string name="group_chat_name">പേര്</string>
<string name="notification_group_messages">സന്ദേശങ്ങൾ</string>
<string name="notification_group_calls">കോളുകൾ</string>
<string name="messages_channel_name">സന്ദേശങ്ങൾ</string>
<string name="silent_messages_channel_name">നിശബ്‌ദ സന്ദേശങ്ങൾ</string>
<string name="group_chat_members">പങ്കെടുക്കുന്നവർ</string>
<string name="choose_a_country">ഒരു രാജ്യം തിരഞ്ഞെടുക്കൂ</string>
<string name="phone_number">ഫോൺ നമ്പർ</string>
<string name="verify_your_phone_number">നിങ്ങളുടെ ഫോൺ നമ്പർ ഉറപ്പാക്കൂ</string>
<string name="please_enter_your_phone_number">നിങ്ങളുടെ ഫോൺ നമ്പർ നൽകുക.</string>
<string name="verify_x">%s ഉറപ്പാക്കൂ</string>
<string name="resend_sms">SMS വീണ്ടും അയയ്ക്കൂ</string>
<string name="resend_sms_in">SMS വീണ്ടും അയയ്ക്കൂ (%s)</string>
<string name="yes">അതെ</string>
<string name="verifying">ഉറപ്പാക്കുന്നു...</string>
<string name="requesting_sms">SMS അഭ്യർത്ഥിക്കുന്നു…</string>
<string name="your_name">നിങ്ങളുടെ പേര്</string>
<string name="enter_your_name">നിങ്ങളുടെ പേര് നൽകുക</string>
<string name="choose_account">അക്കൗണ്ട് തിരഞ്ഞെടുക്കൂ</string>
<string name="enter_jabber_id">XMPP വിലാസം നൽകുക</string>
<string name="xmpp_address">XMPP വിലാസം</string>

View File

@ -987,4 +987,4 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż
<string name="server_does_not_support_easy_onboarding_invites">Serwer nie wspiera tworzenia zaproszeń</string>
<string name="no_active_accounts_support_this">Nie ma aktywnych kont wspierających tę funkcję</string>
<string name="backup_started_message">Tworzenie kopii zapasowej się rozpoczęło. Dostaniesz powiadomienie kiedy się zakończy. </string>
</resources>
</resources>

View File

@ -150,6 +150,7 @@
<string name="error_file_not_found">Arquivo não encontrado</string>
<string name="error_io_exception">Ocorreu um erro genérico de E/S. Você tem espaço de armazenamento suficiente no seu aparelho?</string>
<string name="error_security_exception_during_image_copy">O aplicativo que você usou para selecionar esta imagem não nos forneceu permissões suficientes para ler o arquivo.\n\n<small>Utilize um gerenciador de arquivos diferente para selecionar a imagem.</small></string>
<string name="error_security_exception">O app que você usou para compartilhar esse arquivo não forneceu permissões suficientes.</string>
<string name="account_status_unknown">Desconhecido</string>
<string name="account_status_disabled">Temporariamente desabilitado</string>
<string name="account_status_online">Conectado</string>
@ -164,6 +165,7 @@
<string name="account_status_regis_not_sup">O registro não é suportado pelo servidor</string>
<string name="account_status_regis_invalid_token">Token de registro inválido</string>
<string name="account_status_tls_error">Não foi possível efetuar a negociação TLS</string>
<string name="account_status_tls_error_domain">Domínio não verificável</string>
<string name="account_status_policy_violation">Violação de política</string>
<string name="account_status_incompatible_server">Servidor incompatível</string>
<string name="account_status_stream_error">Erro de fluxo</string>
@ -960,4 +962,5 @@
<string name="server_does_not_support_easy_onboarding_invites">O servidor não suporta a criação de convites</string>
<string name="no_active_accounts_support_this">Nenhuma conta ativa suporta esse recurso</string>
<string name="backup_started_message">O backup foi iniciado. Você receberá uma notificação assim que ele for concluído.</string>
<string name="unable_to_enable_video">Não foi possível habilitar o vídeo.</string>
</resources>

View File

@ -973,4 +973,4 @@
<string name="server_does_not_support_easy_onboarding_invites">Serverul nu suportă generarea de invitații</string>
<string name="no_active_accounts_support_this">Nici un cont activ nu suporta această caracteristică</string>
<string name="backup_started_message">Se creează copia de siguranță. Veți primi o notificare când acesta este completă.</string>
</resources>
</resources>

View File

@ -985,4 +985,5 @@
<string name="unable_to_parse_invite">Невозможно разобрать приглашение</string>
<string name="server_does_not_support_easy_onboarding_invites">Сервер не поддерживает создание приглашений</string>
<string name="no_active_accounts_support_this">Ни один активный аккаунт не поддерживает эту функцию</string>
<string name="backup_started_message">Резервное копирование было начато. Вы получите уведомление, как только оно будет завершено. </string>
</resources>

View File

@ -74,6 +74,8 @@
<string name="unblock">Одблокирај</string>
<string name="save">Сачувај</string>
<string name="ok">У реду</string>
<string name="crash_report_title">%1$s је принудно заустављен</string>
<string name="crash_report_message">Слањем извештаја рада путем вашег ИксМПП налога помажете даљем развоју %1$s.</string>
<string name="send_now">Пошаљи одмах</string>
<string name="send_never">Не питај више</string>
<string name="problem_connecting_to_account">Не могу да се повежем са налогом</string>
@ -99,6 +101,7 @@
<string name="send_omemo_message">Пошаљи ОМЕМО шифровану поруку</string>
<string name="send_omemo_x509_message">Пошаљи v\\ОМЕМО шифровану поруку</string>
<string name="send_pgp_message">Пошаљи ОпенПГП шифровану поруку</string>
<string name="your_nick_has_been_changed">Нови надимак је у употреби</string>
<string name="send_unencrypted">Пошаљи нешифровано</string>
<string name="decryption_failed">Шифровање није успело. Можда немате одговарајући лични кључ.</string>
<string name="openkeychain_required">Отворени кључарник</string>
@ -119,12 +122,17 @@
<string name="pref_led">ЛЕД светло</string>
<string name="pref_led_summary">Трептање ЛЕД светла кад стигне нова порука</string>
<string name="pref_ringtone">Звук</string>
<string name="pref_notification_sound">Звук обавештења</string>
<string name="pref_notification_sound_summary">Звук обавештења нових порука</string>
<string name="pref_call_ringtone_summary">Мелодија долазног позива</string>
<string name="pref_notification_grace_period">Период одгоде</string>
<string name="pref_advanced_options">Напредно</string>
<string name="pref_never_send_crash">Никад не шаљи извештаје о паду</string>
<string name="pref_confirm_messages">Потврди поруке</string>
<string name="pref_confirm_messages_summary">Обзнаните контактима када примите и прочитате њихове поруке</string>
<string name="pref_ui_options">Сучеље</string>
<string name="openpgp_error">Отворени кључарник је направио грешку.</string>
<string name="bad_key_for_encryption">Лош кључ за шифровање.</string>
<string name="accept">Прихвати</string>
<string name="error">Десила се грешка</string>
<string name="recording_error">Грешка</string>
@ -136,6 +144,7 @@
<string name="attach_take_picture">Фотографиши</string>
<string name="preemptively_grant">Унапред дозволи захтев за претплатом</string>
<string name="error_not_an_image_file">Изабрани фајл није слика</string>
<string name="error_compressing_image">Не могу преобратити датотеку фотографије</string>
<string name="error_file_not_found">Фајл није нађен</string>
<string name="error_io_exception">Општа У/И грешка. Можда вам је нестало простора у складишту?</string>
<string name="account_status_unknown">Непознато</string>
@ -149,10 +158,14 @@
<string name="account_status_regis_fail">Регистрација није успела</string>
<string name="account_status_regis_conflict">Корисничко име је већ у употреби</string>
<string name="account_status_regis_success">Регистрација завршена</string>
<string name="account_status_regis_not_sup">Овај сервер не подржава регистрацију</string>
<string name="account_status_regis_invalid_token">Неисправан регистрациони токен</string>
<string name="account_status_tls_error">ТЛС преговарање није успело</string>
<string name="account_status_tls_error_domain">Непроверљив домен</string>
<string name="account_status_policy_violation">Нарушавање полисе</string>
<string name="account_status_incompatible_server">Некомпатибилан сервер</string>
<string name="account_status_stream_error">Грешка тока</string>
<string name="account_status_stream_opening_error">Грешка при отварању тока</string>
<string name="encryption_choice_unencrypted">Нешифровано</string>
<string name="encryption_choice_otr">ОТР</string>
<string name="encryption_choice_pgp">ОпенПГП</string>
@ -163,11 +176,16 @@
<string name="mgmt_account_publish_pgp">Објави ОпенПГП јавни кључ</string>
<string name="unpublish_pgp">Уклони ОпенПГП кључ</string>
<string name="unpublish_pgp_message">Желите ли заиста да уклоните ваш ОпенПГП кључ из ваше објаве присутности?\nВаши контакти више неће моћи да вам шаљу ОпенПГП шифроване поруке.</string>
<string name="openpgp_has_been_published">ОпенПГП кључ је објављен.</string>
<string name="mgmt_account_enable">Укључи налог</string>
<string name="mgmt_account_are_you_sure">Да ли сте сигурни?</string>
<string name="attach_record_voice">Сними глас</string>
<string name="account_settings_jabber_id">ИксМПП адреса</string>
<string name="block_jabber_id">Блокирај ИксМПП адресу</string>
<string name="account_settings_example_jabber_id">korisnickoime@primer.com</string>
<string name="password">Лозинка</string>
<string name="invalid_jid">Ово је неисправна ИксМПП адреса</string>
<string name="error_out_of_memory">Недовољно меморије. Фотографија је превелика</string>
<string name="add_phone_book_text">Желите ли да додате %s у ваш именик?</string>
<string name="server_info_show_more">Подаци о серверу</string>
<string name="server_info_mam">XEP-0313: МАМ</string>
@ -176,6 +194,7 @@
<string name="server_info_blocking">XEP-0191: наредба блокирања</string>
<string name="server_info_roster_version">XEP-0237: верзионисање ростера</string>
<string name="server_info_stream_management">XEP-0198: менаџмент тока</string>
<string name="server_info_external_service_discovery">XEP-0215: Проналажење спољњих сервиса</string>
<string name="server_info_pep">XEP-0163: PEP (аватари/ОМЕМО)</string>
<string name="server_info_http_upload">XEP-0363: ХТТП отпремање фајлова</string>
<string name="server_info_push">XEP-0357: „push“</string>
@ -183,17 +202,25 @@
<string name="server_info_unavailable">недоступан</string>
<string name="missing_public_keys">Недостају објаве јавног кључа</string>
<string name="last_seen_now">виђен/а мало пре</string>
<string name="last_seen_min">виђен/а пре минут</string>
<string name="last_seen_mins">виђен/а пре %d минута</string>
<string name="last_seen_hour">виђен/а пре сат времена</string>
<string name="last_seen_hours">виђен/а пре %d сати</string>
<string name="last_seen_day">виђен/а јуче</string>
<string name="last_seen_days">виђен/а пре %d дана</string>
<string name="install_openkeychain">Шифрована порука. Инсталирајте Отворени кључарник да је дешифрујете.</string>
<string name="openpgp_messages_found">Пронаћене су нове ОпенПГП шифроване поруке</string>
<string name="openpgp_key_id">ИД ОпенПГП кључа</string>
<string name="omemo_fingerprint">ОМЕМО отисак</string>
<string name="omemo_fingerprint_x509">v\\ОМЕМО отисак</string>
<string name="omemo_fingerprint_selected_message">ОМЕМО отисак (порекло поруке)</string>
<string name="omemo_fingerprint_x509_selected_message">v\\ОМЕМО отисак (порекло поруке)</string>
<string name="other_devices">Остали уређаји</string>
<string name="trust_omemo_fingerprints">Поуздај се у ОМЕМО отиске</string>
<string name="fetching_keys">Добављам кључеве…</string>
<string name="done">Готово</string>
<string name="decrypt">Дешифруј</string>
<string name="bookmarks">Обележивачи</string>
<string name="search">Тражи</string>
<string name="enter_contact">Унеси контакт</string>
<string name="delete_contact">Обриши контакт</string>
@ -204,8 +231,14 @@
<string name="select">Изабери</string>
<string name="contact_already_exists">Контакт већ постоји</string>
<string name="join">Придружи се</string>
<string name="channel_full_jid_example">channel@conference.example.com/nick</string>
<string name="channel_bare_jid_example">channel@conference.example.com</string>
<string name="save_as_bookmark">Сачувај као обележивач</string>
<string name="delete_bookmark">Обриши обележивач</string>
<string name="destroy_room">Уклони групно ћаскање</string>
<string name="destroy_channel">Уклони канал</string>
<string name="could_not_destroy_room">Не могу уклонити групно ћаскање</string>
<string name="could_not_destroy_channel">Не могу уклонити канал</string>
<string name="action_edit_subject">Уреди предмет групног ћаскања</string>
<string name="topic">Тема</string>
<string name="joining_conference">Улазим у групно ћаскање…</string>
@ -214,18 +247,23 @@
<string name="add_back">Додај га</string>
<string name="contact_has_read_up_to_this_point">%s је прочитао довде</string>
<string name="contacts_have_read_up_to_this_point">%s је прочитао/ла довде</string>
<string name="contacts_and_n_more_have_read_up_to_this_point">%1$s + %2$d других су прочитали довде</string>
<string name="everyone_has_read_up_to_this_point">Сви су прочитали довде</string>
<string name="publish">Објави</string>
<string name="touch_to_choose_picture">Тапните аватар да изаберете слику из галерије</string>
<string name="publishing">Објављујем…</string>
<string name="error_publish_avatar_server_reject">Сервер је одбио вашу објаву</string>
<string name="error_publish_avatar_converting">Не могу преобратити вашу фотографију</string>
<string name="error_saving_avatar">Не могох да сачувам аватар на диск</string>
<string name="or_long_press_for_default">(или притисните дуго да вратите подразумевани)</string>
<string name="error_publish_avatar_no_server_support">Ваш сервер не подржава објаву аватара</string>
<string name="private_message">шапну</string>
<string name="private_message_to">за %s</string>
<string name="send_private_message_to">Пошаљи личну поруку за %s</string>
<string name="connect">Повежи</string>
<string name="account_already_exists">Овај налог већ постоји</string>
<string name="next">Следеће</string>
<string name="server_info_session_established">Сесија успостављена</string>
<string name="skip">Прескочи</string>
<string name="disable_notifications">Искључи обавештења</string>
<string name="enable">Укључи</string>
@ -238,18 +276,24 @@
<string name="pref_allow_message_correction_summary">Дозвољава вашим контактима да ретроактивно уређују њихове поруке</string>
<string name="pref_expert_options">Поставке за стручњаке</string>
<string name="pref_expert_options_summary">Будите пажљиви са овим</string>
<string name="title_activity_about_x">О %s</string>
<string name="title_pref_quiet_hours">Тихи сати</string>
<string name="title_pref_quiet_hours_start_time">Време почетка</string>
<string name="title_pref_quiet_hours_end_time">Време завршетка</string>
<string name="title_pref_enable_quiet_hours">Укључи тихе сате</string>
<string name="pref_quiet_hours_summary">Обавештења ће бити ућуткана за време тихих сати</string>
<string name="pref_expert_options_other">Остало</string>
<string name="conference_banned">Забрањени сте на овом групном ћаскању</string>
<string name="pref_autojoin">Синхронизуј са обележивачима</string>
<string name="pref_autojoin_summary">Аутоматски се придружите групним ћаскањима по поставци обележивача</string>
<string name="toast_message_omemo_fingerprint">ОМЕМО отисак копиран на клипборд</string>
<string name="conference_banned">Забрањен вам је приступ овом групном ћаскању</string>
<string name="conference_members_only">Ово групно ћаскање је само за чланове</string>
<string name="conference_resource_constraint">Ограничење ресурса</string>
<string name="conference_kicked">Шутнути сте из овог групног ћаскања</string>
<string name="conference_shutdown">Групно ћаскање је угашено</string>
<string name="conference_unknown_error">Више нисте у овом групном ћаскању</string>
<string name="using_account">преко налога %s</string>
<string name="hosted_on">код домаћина %s</string>
<string name="checking_x">Проверавам %s на ХТТП домаћину</string>
<string name="not_connected_try_again">Нисте повезани. Покушајте поново касније</string>
<string name="check_x_filesize">Провери величину %s</string>
@ -261,6 +305,8 @@
<string name="send_again">Пошаљи поново</string>
<string name="file_url">УРЛ фајла</string>
<string name="url_copied_to_clipboard">УРЛ је копиран на клипборд</string>
<string name="jabber_id_copied_to_clipboard">ИксМПП адреса копирана на клипборд</string>
<string name="error_message_copied_to_clipboard">Порука грешке копирана на клипборд</string>
<string name="web_address">веб адреса</string>
<string name="scan_qr_code">Очитај 2Д бар-кôд</string>
<string name="show_qr_code">Прикажи 2Д бар-кôд</string>
@ -268,7 +314,16 @@
<string name="account_details">Детаљи налога</string>
<string name="confirm">Потврди</string>
<string name="try_again">Покушај поново</string>
<string name="pref_keep_foreground_service">Сервис у првом плану</string>
<string name="pref_keep_foreground_service_summary">Спречава оперативни систем да прекине вашу везу</string>
<string name="pref_create_backup">Направите резерву</string>
<string name="pref_create_backup_summary">Резерва ће бити складиштена у %s</string>
<string name="notification_create_backup_title">Правим резерву</string>
<string name="notification_backup_created_title">Ваша резерва је направљена</string>
<string name="notification_backup_created_subtitle">Резерве су складиштене у %s</string>
<string name="restoring_backup">Учитавам резерву</string>
<string name="notification_restored_backup_title">Ваша резерва је учитана</string>
<string name="notification_restored_backup_subtitle">Не заборавите да омогућите налог</string>
<string name="choose_file">Изабери фајл</string>
<string name="receiving_x_file">Примам %1$s (%2$d%% завршено)</string>
<string name="download_x_file">Преузми %s</string>
@ -276,12 +331,20 @@
<string name="file">фајл</string>
<string name="open_x_file">Отвори %s</string>
<string name="sending_file">шаљем (%1$d%% завршено)</string>
<string name="preparing_file">Припремам датотеку за пренос</string>
<string name="x_file_offered_for_download">%s понуђен за преузимање</string>
<string name="cancel_transmission">Прекини пренос</string>
<string name="file_transmission_failed">не могу поделити датотеку</string>
<string name="file_transmission_cancelled">пренос датотеке је прекинут</string>
<string name="file_deleted">Датотека је обрисана</string>
<string name="no_application_found_to_open_file">Нема апликације за отварање датотеке</string>
<string name="no_application_found_to_open_link">Нема апликације за отварање везе</string>
<string name="no_application_found_to_view_contact">Нема апликације за приказ контакта</string>
<string name="pref_show_dynamic_tags">Динамичке ознаке</string>
<string name="pref_show_dynamic_tags_summary">Приказ ознака испод контаката</string>
<string name="enable_notifications">Укључи обавештења</string>
<string name="no_conference_server_found">Сервер групног ћаскања није нађен</string>
<string name="conference_creation_failed">Не могу направити групно ћаскање</string>
<string name="account_image_description">Аватар налога</string>
<string name="copy_omemo_clipboard_description">Копирај ОМЕМО отисак на клипборд</string>
<string name="regenerate_omemo_key">Поново генериши ОМЕМО кључ</string>
@ -295,6 +358,7 @@
<string name="change_password">Промени лозинку</string>
<string name="current_password">Текућа лозинка</string>
<string name="new_password">Нова лозинка</string>
<string name="password_should_not_be_empty">Лозинка не може бити празна</string>
<string name="enable_all_accounts">Укључи све налоге</string>
<string name="disable_all_accounts">Искључи све налоге</string>
<string name="perform_action_with">Изврши радњу са</string>
@ -303,14 +367,25 @@
<string name="outcast">Изгнаник</string>
<string name="member">Члан</string>
<string name="advanced_mode">Напредни режим</string>
<string name="grant_membership">Одобри админ. привилегије</string>
<string name="remove_membership">Укини админ. привилегије</string>
<string name="grant_admin_privileges">Одобри админ. привилегије</string>
<string name="remove_admin_privileges">Одобри админ. привилегије</string>
<string name="grant_owner_privileges">Одобри власничке привилегије</string>
<string name="remove_owner_privileges">Укини власничке привилегије</string>
<string name="remove_from_room">Уклони из групног ћаскања</string>
<string name="remove_from_channel">Уклони из канала</string>
<string name="could_not_change_affiliation">Не могох да изменим припадност за %s</string>
<string name="ban_from_conference">Забрани за групно ћаскање</string>
<string name="ban_from_conference">Забрани приступ групном ћаскању</string>
<string name="ban_from_channel">Забрани приступ каналу</string>
<string name="removing_from_public_conference">Покушавате да уклоните %s из јавног канала. Ово се за стално постиже једино забраном приступа кориснику.</string>
<string name="ban_now">Забрани одмах</string>
<string name="could_not_change_role">Не могох да изменим улогу за %s</string>
<string name="conference_options">Поставке приватног групног ћаскања</string>
<string name="channel_options">Поставке јавног канала</string>
<string name="members_only">Лична, само чланови</string>
<string name="non_anonymous">Начините ИксМПП адресу видљиву свима</string>
<string name="moderated">Начините канал модерисаним</string>
<string name="you_are_not_participating">Не учествујете</string>
<string name="modified_conference_options">Опције групног ћаскања измењене!</string>
<string name="could_not_modify_conference_options">Не могу да изменим опције групног ћаскања</string>
@ -341,8 +416,11 @@
<string name="pref_chat_states_summary">Обзнаните контактима када им куцате поруке</string>
<string name="send_location">Пошаљи локацију</string>
<string name="show_location">Прикажи локацију</string>
<string name="no_application_found_to_display_location">Нема апликације за приказ локације</string>
<string name="location">Локација</string>
<string name="title_undo_swipe_out_conversation">Преписка затворена</string>
<string name="title_undo_swipe_out_group_chat">Напустили сте групно ћаскање</string>
<string name="title_undo_swipe_out_channel">Напустили сте јавни канал</string>
<string name="pref_dont_trust_system_cas_title">Не поуздај се у системска сертификациона тела</string>
<string name="pref_dont_trust_system_cas_summary">Сви сертификати морају ручно да се одобре</string>
<string name="pref_remove_trusted_certificates_title">Уклони сертификате</string>
@ -356,12 +434,15 @@
<item quantity="few">%d сертификата обрисана</item>
<item quantity="other">%d сертификата обрисано</item>
</plurals>
<string name="pref_quick_action_summary">Замени дугме за слање брзом радњом</string>
<string name="pref_quick_action">Брза радња</string>
<string name="none">Ниједна</string>
<string name="recently_used">Недавно коришћена</string>
<string name="choose_quick_action">Изаберите брзу радњу</string>
<string name="search_contacts">Тражи контакте</string>
<string name="search_bookmarks">Претрага обележивача</string>
<string name="send_private_message">Пошаљи личну поруку</string>
<string name="user_has_left_conference">%1$s је напустио/ла групно ћаскање</string>
<string name="username">Корисничко име</string>
<string name="username_hint">Корисничко име</string>
<string name="invalid_username">Ово није исправно корисничко име</string>
@ -371,16 +452,28 @@
<string name="download_failed_could_not_write_file">Преузимање није успело: не могох да упишем фајл</string>
<string name="account_status_tor_unavailable">Тор мрежа недоступна</string>
<string name="account_status_bind_failure">Неуспех свезивања</string>
<string name="account_status_host_unknown">Сервер није одговоран за овај домен</string>
<string name="server_info_broken">Оштећен</string>
<string name="pref_presence_settings">Доступност</string>
<string name="pref_away_when_screen_off">Увек када је уређај закљчан</string>
<string name="pref_away_when_screen_off_summary">Прикажи ме одсутним када је уређај закљчан</string>
<string name="pref_dnd_on_silent_mode">Заузет у нечујном режиму</string>
<string name="pref_dnd_on_silent_mode_summary">Прикажи ме заузетум у нечујном режиму</string>
<string name="pref_treat_vibrate_as_silent">Вибрација је нечујни режим</string>
<string name="pref_treat_vibrate_as_dnd_summary">Прикажи ме заузетум у режиму вибрације</string>
<string name="pref_show_connection_options">Проширене поставке повезивања</string>
<string name="pref_show_connection_options_summary">Приказ домаћина и порта у поставкама налога</string>
<string name="hostname_example">xmpp.primer.com</string>
<string name="action_add_account_with_certificate">Пријавите се сертификатом</string>
<string name="unable_to_parse_certificate">Не могу прочитати сертификат</string>
<string name="mam_prefs">Поставке архивисања</string>
<string name="server_side_mam_prefs">Серверске поставке архивисања</string>
<string name="fetching_mam_prefs">Добављам поставке архивисања, сачекајте…</string>
<string name="unable_to_fetch_mam_prefs">Не могу да добавим поставке архивисања</string>
<string name="captcha_required">КЕПЧА је обавезна</string>
<string name="captcha_hint">Унесите текст са слике изнад</string>
<string name="certificate_chain_is_not_trusted">Неповерљив ланац сертификата</string>
<string name="jid_does_not_match_certificate">ИксМПП адреса се не слаже са сертификатом</string>
<string name="action_renew_certificate">Обнови сертификат</string>
<string name="error_fetching_omemo_key">Грешка добављања ОМЕМО кључа!</string>
<string name="verified_omemo_key_with_certificate">Оверен ОМЕМО кључ помоћу сертификата!</string>
@ -390,6 +483,7 @@
<string name="pref_use_tor_summary">Тунеловање свих веза кроз Тор мрежу. Захтева Орбот</string>
<string name="account_settings_hostname">Име домаћина</string>
<string name="account_settings_port">Порт</string>
<string name="hostname_or_onion">Серверска или .onion адреса</string>
<string name="not_a_valid_port">Ово није исправан број порта</string>
<string name="not_valid_hostname">Ово није исправно име домаћина</string>
<string name="connected_accounts">%1$d од %2$d налога повезано</string>
@ -399,11 +493,20 @@
<item quantity="other">%d порука</item>
</plurals>
<string name="load_more_messages">Учитај још порука</string>
<string name="shared_file_with_x">Датотека подељена са %s</string>
<string name="shared_image_with_x">Слика подељена са %s</string>
<string name="shared_images_with_x">Слике подељене са %s</string>
<string name="shared_text_with_x">Текст подељен са %s</string>
<string name="no_storage_permission">Дозволите да %1$s приступи спољној меморији</string>
<string name="no_camera_permission">Дозволите да %1$s приступи камери</string>
<string name="sync_with_contacts">Синхронизуј са контактима</string>
<string name="notify_on_all_messages">Обавештења за све поруке</string>
<string name="notify_only_when_highlighted">Обавести само када ме помињу</string>
<string name="notify_never">Обавештења искључена</string>
<string name="notify_paused">Обавештења паузирана</string>
<string name="pref_picture_compression">Компресија слике</string>
<string name="always">увек</string>
<string name="large_images_only">Само велике слике</string>
<string name="battery_optimizations_enabled">Оптимизација батерије је укључена</string>
<string name="disable">Искључи</string>
<string name="selection_too_large">Назначена површина је превелика</string>
@ -412,10 +515,14 @@
<string name="correct_message">Исправи поруку</string>
<string name="send_corrected_message">Пошаљи исправљену поруку</string>
<string name="this_account_is_disabled">Искључили сте овај налог</string>
<string name="no_application_to_share_uri">Нема апликације за дељење ресурса</string>
<string name="share_uri_with">Подели везу помоћу…</string>
<string name="agree_and_continue">Сложи се и настави</string>
<string name="your_full_jid_will_be">Ваша цела ИксМПП адреса ће бити: %s</string>
<string name="create_account">Направи налог</string>
<string name="use_own_provider">Користићу сопствени провајдер</string>
<string name="pick_your_username">Одредите ваше корисничко име</string>
<string name="pref_manually_change_presence">Ручно мењај доступност</string>
<string name="status_message">Порука стања</string>
<string name="presence_chat">Слободан за ћаскање</string>
<string name="presence_online">На вези</string>
@ -433,11 +540,17 @@
<string name="gp_short">Кратак</string>
<string name="gp_medium">Средњи</string>
<string name="gp_long">Дуг</string>
<string name="pref_broadcast_last_activity">Објави употребу</string>
<string name="pref_broadcast_last_activity_summary">Обзнаните контакте кад користите Конверзацију</string>
<string name="pref_privacy">Приватност</string>
<string name="pref_theme_options">Тема</string>
<string name="pref_theme_options_summary">Избор палете боја</string>
<string name="pref_theme_automatic">Аутопатски</string>
<string name="pref_theme_light">Светла</string>
<string name="pref_theme_dark">Тамна</string>
<string name="pref_use_green_background">Зелена позадина</string>
<string name="pref_use_green_background_summary">Зелена позадина за примљене поруке</string>
<string name="unable_to_connect_to_keychain">Не могу да се повежем са Отвореним кључарником</string>
<string name="this_device_is_no_longer_in_use">Овај уређај више није у употреби</string>
<string name="type_pc">Рачунар</string>
<string name="type_phone">Мобилни телефон</string>
@ -445,6 +558,7 @@
<string name="type_web">Веб прегледач</string>
<string name="type_console">Конзола</string>
<string name="payment_required">Захтевано је плаћање</string>
<string name="missing_internet_permission">Дозволите приступ интернету</string>
<string name="me">Ја</string>
<string name="contact_asks_for_presence_subscription">Контакт пита за претплату на ажурирање присутности</string>
<string name="allow">Дозволи</string>

View File

@ -1,9 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_settings">Cài đặt</string>
<string name="action_add">Hội thoại mới</string>
<string name="action_add">Cuộc hội thoại mới</string>
<string name="action_accounts">Quản lý tài khoản</string>
<string name="action_account">Quản lý tài khoản</string>
<string name="action_end_conversation">Đóng cuộc hội thoại</string>
<string name="action_contact_details">Thông tin liên hệ</string>
<string name="action_muc_details">Chi tiết cuộc trò chuyện nhóm</string>
<string name="channel_details">Chi tiết kênh</string>
<string name="action_add_account">Thêm tài khoản</string>
<string name="action_edit_contact">Chỉnh sửa tên</string>
<string name="action_add_phone_book">Thêm vào danh bạ</string>
@ -12,31 +16,47 @@
<string name="action_unblock_contact">Bỏ chặn liên hệ</string>
<string name="action_block_domain">Chặn miền</string>
<string name="action_unblock_domain">Bỏ chặn miền</string>
<string name="action_block_participant">Chặn thành viên</string>
<string name="action_unblock_participant">Bỏ chặn thành viên</string>
<string name="title_activity_manage_accounts">Quản lý tài khoản</string>
<string name="title_activity_settings">Cài đặt</string>
<string name="title_activity_sharewith">Chia sẻ qua Conversation</string>
<string name="title_activity_start_conversation">Khởi chạy Conversation</string>
<string name="title_activity_choose_contact">Chọn liên hệ</string>
<string name="title_activity_choose_contacts">Chọn liên hệ</string>
<string name="title_activity_share_via_account">Chia sẻ qua tài khoản</string>
<string name="title_activity_block_list">Danh sách chặn</string>
<string name="just_now">mới đây</string>
<string name="minute_ago">1 phút trước</string>
<string name="minutes_ago">%d phút trước</string>
<plurals name="x_unread_conversations">
<item quantity="other">%d cuộc hội thoại chưa đọc</item>
</plurals>
<string name="sending">đang gửi...</string>
<string name="message_decrypting">Đang giải mã tin nhắn. Xin chờ...</string>
<string name="pgp_message">Tin nhắn mã hoá bằng OpenPGP</string>
<string name="nick_in_use">Biệt danh đã được sử dụng</string>
<string name="invalid_muc_nick">Biệt danh không hợp lệ</string>
<string name="admin">Quản trị viên</string>
<string name="owner">Chủ nhân</string>
<string name="moderator">Điều phối viên</string>
<string name="participant">Thành viên</string>
<string name="visitor">Khách</string>
<string name="remove_contact_text">Bạn có muốn xoá %s khỏi danh sách liên hệ của bạn không? Các cuộc hội thoại với liên hệ này sẽ không bị xoá.</string>
<string name="block_contact_text">Bạn có muốn chặn %s gửi tin nhắn cho bạn?</string>
<string name="unblock_contact_text">Bạn có muốn bỏ chặn %s và cho phép họ gửi tin nhắn cho bạn?</string>
<string name="block_domain_text">Chặn tất cả liên hệ từ %s?</string>
<string name="unblock_domain_text">Bỏ chặn tất cả liên hệ từ %s?</string>
<string name="contact_blocked">Đã chặn liên hệ</string>
<string name="blocked">Đã chặn</string>
<string name="remove_bookmark_text">Bạn có muốn xoá dấu trang %s không? Các cuộc hội thoại với dấu trang này sẽ không bị xoá.</string>
<string name="register_account">Đăng ký tài khoản mới trên máy chủ</string>
<string name="change_password_on_server">Đổi mật k trên máy chủ</string>
<string name="share_with">Chia sẻ với...</string>
<string name="start_conversation">Bắt đầu cuộc hội thoại</string>
<string name="invite_contact">Mời liên hệ</string>
<string name="invite">Mời</string>
<string name="contacts">Danh bạ</string>
<string name="contact">Liên hệ</string>
<string name="cancel">Huỷ</string>
@ -48,30 +68,47 @@
<string name="unblock">Bỏ chặn</string>
<string name="save">Lưu</string>
<string name="ok">OK</string>
<string name="crash_report_title">%1$s đã đột ngột dừng</string>
<string name="crash_report_message">Việc sử dụng tài khoản XMPP của bạn để gửi báo cáo hoạt động sẽ giúp sự phát triển liên tục của %1$s.</string>
<string name="send_now">Gửi ngay</string>
<string name="send_never">Đừng hỏi lại nữa</string>
<string name="problem_connecting_to_account">Không thể kết nối đến tài khoản</string>
<string name="problem_connecting_to_accounts">Không thể kết nối đến nhiều tài khoản</string>
<string name="touch_to_fix">Nhấn để quản lý các tài khoản của bạn</string>
<string name="attach_file">Đính kèm tập tin</string>
<string name="not_in_roster">Thêm liên hệ bị thiếu này vào danh sách liên hệ?</string>
<string name="add_contact">Thêm liên hệ</string>
<string name="send_failed">thất bại khi chuyển</string>
<string name="preparing_image">Đang chuẩn bị sẵn sàng để gửi hình ảnh</string>
<string name="preparing_images">Đang chuẩn bị sẵn sàng để gửi các hình ảnh</string>
<string name="sharing_files_please_wait">Đang chia sẻ các tập tin. Xin chờ...</string>
<string name="action_clear_history">Xoá lịch sử</string>
<string name="clear_conversation_history">Xoá lịch sử hội thoại</string>
<string name="clear_histor_msg">Bạn có muốn xoá tất cả tin nhắn trong cuộc hội thoại này không?\n\n<b>Cảnh báo:</b> Việc này sẽ không ảnh hưởng đến các tin nhắn được lưu trữ trên các thiết bị hoặc máy chủ khác.</string>
<string name="delete_file_dialog">Xoá tệp</string>
<string name="delete_file_dialog_msg">Bạn có chắc bạn muốn xoá tệp này không?\n\n<b>Cảnh báo:</b> Việc này sẽ không xoá các bản sao được lưu trữ trên các thiết bị hoặc máy chủ khác của tệp này.</string>
<string name="also_end_conversation">Đóng cuộc hội thoại này sau đó</string>
<string name="choose_presence">Chọn thiết bị</string>
<string name="send_unencrypted_message">Gửi tin nhắn không mã hoá</string>
<string name="send_message">Gửi tin nhắn</string>
<string name="send_message_to_x">Gửi tin nhắn đến %s</string>
<string name="send_omemo_message">Gửi tin nhắn mã hoá OMEMO</string>
<string name="send_omemo_x509_message">Gửi tin nhắn mã hoá v\\OMEMO</string>
<string name="send_pgp_message">Gửi tin nhắn mã hoá OpenPGP</string>
<string name="your_nick_has_been_changed">Biệt danh mới đang được sử dụng</string>
<string name="send_unencrypted">Gửi dạng không mã hoá</string>
<string name="decryption_failed">Giải mã thất bại. Có lẽ bạn không có đúng khoá cá nhân.</string>
<string name="openkeychain_required">OpenKeychain</string>
<string name="openkeychain_required_long"><![CDATA[%1$s sử dụng <b>OpenKeychain</b> để mã hoá và giải mã các tin nhắn và quản lý các mã khoá công khi của bạn.<br><br>Nó được cấp phép dưới GPLv3 và có sẵn trên F-Droid và Google Play.<br><br><small>(Vui lòng khởi động lại %1$s sau đó.)</small>]]></string>
<string name="restart">Khởi chạy lại</string>
<string name="install">Cài đặt</string>
<string name="openkeychain_not_installed">Xin cài đặt OpenKeychain</string>
<string name="offering">đang đề xuất...</string>
<string name="waiting">đang chờ...</string>
<string name="no_pgp_key">Không tìm thấy khoá OpenPGP</string>
<string name="contact_has_no_pgp_key">Không thể mã hoá tin nhắn của bạn vì liên hệ của bạn không thông báo mã khoá công khai của họ.\n\n<small>Vui lòng yêu cầu liên hệ của bạn thiết lập OpenPGP.</small></string>
<string name="no_pgp_keys">Không tìm thấy các khoá OpenPGP</string>
<string name="contacts_have_no_pgp_keys">Không thể mã hoá tin nhắn của bạn vì các liên hệ của bạn không thông báo mã khoá công khai của họ.\n\n<small>Vui lòng yêu cầu họ thiết lập OpenPGP.</small></string>
<string name="pref_general">Tổng quan</string>
<string name="pref_accept_files">Chấp thuận các tập tin</string>
<string name="pref_accept_files_summary">Tự động chấp thuận các tập tin nhỏ hơn...</string>
@ -82,14 +119,22 @@
<string name="pref_led">Thông báo đèn LED</string>
<string name="pref_led_summary">Chớp đèn thông báo khi có tin nhắn mới</string>
<string name="pref_ringtone">Âm báo</string>
<string name="pref_notification_sound">Âm thanh thông báo</string>
<string name="pref_notification_sound_summary">Âm thanh thông báo cho các tin nhắn mới</string>
<string name="pref_call_ringtone_summary">Nhạc chuông cho các cuộc gọi đến</string>
<string name="pref_notification_grace_period">Thời gian gia hạn thông báo</string>
<string name="pref_notification_grace_period_summary">Khoảng thời gian mà các thông báo được giữ im lặng sau khi phát hiện hoạt động trên một trong những thiết bị khác.</string>
<string name="pref_advanced_options">Nâng cao</string>
<string name="pref_never_send_crash">Không bao giờ gửi báo cáo dừng chạy</string>
<string name="pref_never_send_crash_summary">Bằng việc gửi báo cáo hoạt động, bạn đang hỗ trợ sự phát triển</string>
<string name="pref_confirm_messages">Xác nhận tin nhắn</string>
<string name="pref_confirm_messages_summary">Báo cho liên hệ của bạn biết khi bạn đã nhận và đọc tin nhắn</string>
<string name="pref_ui_options">UI</string>
<string name="openpgp_error">OpenKeychain đã có lỗi.</string>
<string name="bad_key_for_encryption">Mã khoá mã hoá bị lỗi.</string>
<string name="accept">Chấp thuận</string>
<string name="error">Đã có lỗi xảy ra</string>
<string name="recording_error">Lỗi</string>
<string name="your_account">Tài khoản của bạn</string>
<string name="send_presence_updates">Gửi cập nhật hiện diện</string>
<string name="receive_presence_updates">Nhận cập nhật hiện diện</string>
@ -98,8 +143,11 @@
<string name="attach_take_picture">Chụp hình</string>
<string name="preemptively_grant">Ưu tiên trao quyền yêu cầu đăng ký</string>
<string name="error_not_an_image_file">Tập tin bạn chọn không phải là hình ảnh</string>
<string name="error_compressing_image">Không thể chuyển đổi tệp hình ảnh</string>
<string name="error_file_not_found">Không tìm thấy tập tin</string>
<string name="error_io_exception">Lỗi I/O tổng quát. Có lẽ đã hết dung lượng lưu trữ?</string>
<string name="error_security_exception_during_image_copy">Ứng dụng mà bạn dùng để chọn hình ảnh này không cung cấp đủ quyền để đọc tệp.\n\n<small>Hãy sử dụng trình quản lý tệp khác để chọn hình ảnh</small></string>
<string name="error_security_exception">Ứng dụng bạn dùng để chia sẻ tệp này không cung cấp đủ quyền.</string>
<string name="account_status_unknown">Không rõ</string>
<string name="account_status_disabled">Tạm thời tắt</string>
<string name="account_status_online">Trực tuyến</string>
@ -111,9 +159,14 @@
<string name="account_status_regis_fail">Đăng ký thất bại</string>
<string name="account_status_regis_conflict">Tên người dùng đã được sử dụng</string>
<string name="account_status_regis_success">Đăng ký hoàn tất</string>
<string name="account_status_regis_not_sup">Việc đăng ký không được máy chủ hỗ trợ</string>
<string name="account_status_regis_invalid_token">Mã đăng ký không hợp lệ</string>
<string name="account_status_tls_error">Thương lượng TLS thất bại</string>
<string name="account_status_tls_error_domain">Miền không thể xác minh được</string>
<string name="account_status_policy_violation">Vi phạm chính sách</string>
<string name="account_status_incompatible_server">Máy chủ không tương thích</string>
<string name="account_status_stream_error">Lỗi truyền phát</string>
<string name="account_status_stream_opening_error">Lỗi khi mở luồng truyền</string>
<string name="encryption_choice_unencrypted">Không mã hoá</string>
<string name="encryption_choice_otr">OTR</string>
<string name="encryption_choice_pgp">OpenPGP</string>
@ -122,11 +175,19 @@
<string name="mgmt_account_disable">Tạm thời tắt</string>
<string name="mgmt_account_publish_avatar">Đăng ảnh đại diện</string>
<string name="mgmt_account_publish_pgp">Đăng khoá công cộng OpenPGP</string>
<string name="unpublish_pgp">Xoá mã khoá OpenPGP công khai</string>
<string name="unpublish_pgp_message">Bạn có chắc bạn muốn xoá mã khoá OpenPGP công khai của bạn khỏi sự thông báo có mặt của bạn không?\nCác liên hệ của bạn sẽ không thể gửi các tin nhắn được mã hoá bằng OpenPGP cho bạn nữa.</string>
<string name="openpgp_has_been_published">Đã xuất bản mã khoá OpenPGP công khai.</string>
<string name="mgmt_account_enable">Bật tài khoản</string>
<string name="mgmt_account_are_you_sure">Bạn chắc chứ?</string>
<string name="mgmt_account_delete_confirm_text">Việc xoá tài khoản sẽ xoá toàn bộ lịch sử cuộc hội thoại của bạn</string>
<string name="attach_record_voice">Ghi âm</string>
<string name="account_settings_jabber_id">Địa chỉ XMPP</string>
<string name="block_jabber_id">Chặn địa chỉ XMPP</string>
<string name="account_settings_example_jabber_id">username@example.com</string>
<string name="password">Mật khẩu</string>
<string name="invalid_jid">Đây không phải là địa chỉ XMPP hợp lệ</string>
<string name="error_out_of_memory">Hết bộ nhớ. Hình ảnh quá lớn</string>
<string name="add_phone_book_text">Bạn có muốn thêm %s vào danh bạ?</string>
<string name="server_info_show_more">Thông tin máy chủ</string>
<string name="server_info_mam">XEP-0313: MAM</string>
@ -135,6 +196,7 @@
<string name="server_info_blocking">XEP-0191: Blocking Command</string>
<string name="server_info_roster_version">XEP-0237: Phiên bản hoá danh sách bạn bè</string>
<string name="server_info_stream_management">XEP-0198: Stream Management</string>
<string name="server_info_external_service_discovery">XEP-0215: Khám phá dịch vụ ngoài</string>
<string name="server_info_pep">XEP-0163: PEP (Avatars / OMEMO)</string>
<string name="server_info_http_upload">XEP-0363: HTTP File Upload</string>
<string name="server_info_push">XEP-0357: Push</string>
@ -142,19 +204,28 @@
<string name="server_info_unavailable">không sẵn sàng</string>
<string name="missing_public_keys">Thông báo khoá công cộng bị thất lạc</string>
<string name="last_seen_now">thấy lần cuối vừa đây</string>
<string name="last_seen_min">đã xem một phút trước</string>
<string name="last_seen_mins">thấy lần cuối %d phút trước</string>
<string name="last_seen_hour">đã xem một tiếng trước</string>
<string name="last_seen_hours">thấy lần cuối %d tiếng trước</string>
<string name="last_seen_day">đã xem một ngày trước</string>
<string name="last_seen_days">thấy lần cuối %d ngày trước</string>
<string name="install_openkeychain">Tin nhắn được mã hoá. Vui lòng cài đặt OpenKeychain để giải mã nó.</string>
<string name="openpgp_messages_found">Đã tìm thấy các tin nhắn được mã hoá bằng OpenPGP mới</string>
<string name="openpgp_key_id">ID khoá OpenPGP</string>
<string name="omemo_fingerprint">Dấu vân tay OMEMO</string>
<string name="omemo_fingerprint_x509">Dấu vân tay v\\OMEMO</string>
<string name="omemo_fingerprint_selected_message">Mã vân tay OMEMO (nguồn gốc tin nhắn)</string>
<string name="omemo_fingerprint_x509_selected_message">v\\Mã vân tay OMEMO (nguồn gốc tin nhắn)</string>
<string name="other_devices">Các thiết bị khác</string>
<string name="trust_omemo_fingerprints">Tin tưởng các dấu vân tay OMEMO</string>
<string name="fetching_keys">Đang nhận khoá...</string>
<string name="done">Xong</string>
<string name="decrypt">Giải mã</string>
<string name="bookmarks">Dấu trang</string>
<string name="search">Tìm kiếm</string>
<string name="enter_contact">Nhập liên hệ</string>
<string name="delete_contact">Xoá liên hệ</string>
<string name="view_contact_details">Xem chi tiết liên hệ</string>
<string name="block_contact">Chặn liên hệ</string>
<string name="unblock_contact">Bỏ chặn liên hệ</string>
@ -162,63 +233,132 @@
<string name="select">Chọn</string>
<string name="contact_already_exists">Đã có liên hệ này rồi</string>
<string name="join">Tham gia</string>
<string name="channel_full_jid_example">channel@conference.example.com/nick</string>
<string name="channel_bare_jid_example">channel@conference.example.com</string>
<string name="save_as_bookmark">Lưu thành đánh dấu</string>
<string name="delete_bookmark">Xoá đánh dấu</string>
<string name="destroy_room">Phá huỷ cuộc trò chuyện nhóm</string>
<string name="destroy_channel">Phá huỷ kênh</string>
<string name="destroy_room_dialog">Bạn có chắc bạn muốn phá huỷ cuộc trò chuyện nhóm này không?\n\n<b>Cảnh báo:</b> Cuộc trò chuyện nhóm này sẽ bị xoá hoàn toàn trên máy chủ.</string>
<string name="destroy_channel_dialog">Bạn có chắc bạn muốn phá huỷ kênh công khai này không?\n\n<b>Cảnh báo:</b> Kênh này sẽ bị xoá hoàn toàn trên máy chủ.</string>
<string name="could_not_destroy_room">Không thể phá huỷ cuộc trò chuyện nhóm</string>
<string name="could_not_destroy_channel">Không thể phá huỷ kênh</string>
<string name="action_edit_subject">Chỉnh sửa chủ đề cuộc trò chuyện nhóm</string>
<string name="topic">Chủ đề</string>
<string name="joining_conference">Đang tham gia cuộc trò chuyện nhóm...</string>
<string name="leave">Rời khỏi</string>
<string name="contact_added_you">Liên hệ đã thêm bạn vào danh bạ</string>
<string name="add_back">Thêm họ vào</string>
<string name="contact_has_read_up_to_this_point">%s đã đọc đến điểm này</string>
<string name="contacts_have_read_up_to_this_point">%s đã đọc cho đến lúc này</string>
<string name="contacts_and_n_more_have_read_up_to_this_point">%1$s +%2$d người khác đã đọc cho đến lúc này</string>
<string name="everyone_has_read_up_to_this_point">Mọi người đã đọc cho đến lúc này</string>
<string name="publish">Đăng</string>
<string name="touch_to_choose_picture">Nhấn ảnh đại diện để chọn ảnh từ thư viện</string>
<string name="publishing">Đang đăng...</string>
<string name="error_publish_avatar_server_reject">Máy chủ đã từ chối đăng tải của bạn</string>
<string name="error_publish_avatar_converting">Không thể chuyển đổi hình ảnh</string>
<string name="error_saving_avatar">Không thể lưu ảnh đại diện vào ổ đĩa</string>
<string name="or_long_press_for_default">(Hoặc nhấn giữ để chuyển về mặc định)</string>
<string name="error_publish_avatar_no_server_support">Máy chủ của bạn không hỗ trợ việc công khai ảnh đại diện</string>
<string name="private_message">đã thì thầm</string>
<string name="private_message_to">đến %s</string>
<string name="send_private_message_to">Gửi tin nhắn riêng tư đến %s</string>
<string name="connect">Kết nối</string>
<string name="account_already_exists">Đã có tài khoản này rồi</string>
<string name="next">Tiếp theo</string>
<string name="server_info_session_established">Đã thiết lập phiên làm việc</string>
<string name="skip">Bỏ qua</string>
<string name="disable_notifications">Tắt thông báo</string>
<string name="enable">Bật</string>
<string name="conference_requires_password">Cuộc trò chuyện nhóm yêu cầu mật khẩu</string>
<string name="enter_password">Nhập mật khẩu</string>
<string name="request_presence_updates">Vui lòng yêu cầu cập nhật sự có mặt từ liên hệ của bạn trước tiên.\n\n<small>Việc này sẽ được sử dụng để xác định ứng dụng trò chuyện mà liên hệ của bạn đang dùng</small>.</string>
<string name="request_now">Yêu cầu ngay</string>
<string name="ignore">Bỏ qua</string>
<string name="without_mutual_presence_updates"><b>Cảnh báo:</b> Việc gửi cái này mà không có cập nhật sự có mặt chung có thể sẽ gây ra các vấn đề không mong đợi.\n\n<small>Hãy đi đến \"Chi tiếi liên hệ\" để xác minh đăng ký sự có mặt của bạn.</small></string>
<string name="pref_security_settings">Bảo mật</string>
<string name="pref_allow_message_correction">Cho phép việc sửa tin nhắn</string>
<string name="pref_allow_message_correction_summary">Cho phép các liên hệ của bạn chỉnh sửa cảc tin nhắn của họ</string>
<string name="pref_expert_options">Cài đặt chuyên gia</string>
<string name="pref_expert_options_summary">Xin hãy cẩn trọng với chúng</string>
<string name="title_activity_about_x">Giới thiệu về %s</string>
<string name="title_pref_quiet_hours">Giờ yên lặng</string>
<string name="title_pref_quiet_hours_start_time">Thời gian bắt đầu</string>
<string name="title_pref_quiet_hours_end_time">Thời gian kết thúc</string>
<string name="title_pref_enable_quiet_hours">Bật giờ yên lặng</string>
<string name="pref_quiet_hours_summary">Thông báo sẽ được tắt trong giờ yên lặng</string>
<string name="pref_expert_options_other">Khác</string>
<string name="pref_autojoin">Đồng bộ hoá bằng dấu trang</string>
<string name="pref_autojoin_summary">Tự động tham gia các cuộc trò chuyện nhóm nếu dấu trang bảo thế</string>
<string name="toast_message_omemo_fingerprint">Đã sao chép mã vân tay OMEMO vào bộ nhớ tạm</string>
<string name="conference_banned">Bạn bị cấm khỏi cuộc trò chuyện nhóm này</string>
<string name="conference_members_only">Cuộc trò chuyện nhóm này chỉ dành cho thành viên</string>
<string name="conference_resource_constraint">Tài nguyên bị hạn chế</string>
<string name="conference_kicked">Bạn đã bị đá ra khỏi cuộc trò chuyện nhóm này</string>
<string name="conference_shutdown">Cuộc trò chuyện nhóm bị ngừng hoạt động</string>
<string name="conference_unknown_error">Bạn không còn ở trong cuộc trò chuyện nhóm này nữa</string>
<string name="using_account">đang dùng tài khoản %s</string>
<string name="hosted_on">được lưu trữ trên %s</string>
<string name="checking_x">Đang kiểm tra %s trên máy chủ HTTTP</string>
<string name="not_connected_try_again">Bạn chưa kết nối mạng. Xin thử lại sau</string>
<string name="check_x_filesize">Kiểm tra kích cỡ %s</string>
<string name="check_x_filesize_on_host">Kiểm tra %1$s kích cỡ trên %2$s</string>
<string name="message_options">Tuỳ chọn tin nhắn</string>
<string name="quote">Trích dẫn</string>
<string name="paste_as_quote">Dán làm trích dẫn</string>
<string name="copy_original_url">Sao chép URL gốc</string>
<string name="send_again">Gửi lại</string>
<string name="file_url">URL tập tin</string>
<string name="url_copied_to_clipboard">Đã sao chép URL vào bộ nhớ tạm</string>
<string name="jabber_id_copied_to_clipboard">Đã sao chép địa chỉ XMPP vào bộ nhớ tạm</string>
<string name="error_message_copied_to_clipboard">Đã sao chép thông báo lỗi vào bộ nhớ tạm</string>
<string name="web_address">địa chỉ web</string>
<string name="scan_qr_code">Quét mã vạch 2D</string>
<string name="show_qr_code">Hiện mã vạch 2D</string>
<string name="show_block_list">Quét danh sách chặn</string>
<string name="account_details">Chi tiết tài khoản</string>
<string name="confirm">Xác nhận</string>
<string name="try_again">Thử lại</string>
<string name="pref_keep_foreground_service">Dịch vụ ở trước</string>
<string name="pref_keep_foreground_service_summary">Ngăn hệ điều hành ngắt kết nối của bạn</string>
<string name="pref_create_backup">Tạo bản sao lưu</string>
<string name="pref_create_backup_summary">Các tệp sao lưu sẽ được lưu trữ trong %s</string>
<string name="notification_create_backup_title">Đang tạo các tệp sao lưu</string>
<string name="notification_backup_created_title">Đã tạo bản sao lưu</string>
<string name="notification_backup_created_subtitle">Đã lưu trữ các tệp sao lưu trong %s</string>
<string name="restoring_backup">Đang khôi phục bản sao lưu</string>
<string name="notification_restored_backup_title">Đã khôi phục bản sao lưu</string>
<string name="notification_restored_backup_subtitle">Đừng quên bật tài khoản.</string>
<string name="choose_file">Chọn tập tin</string>
<string name="receiving_x_file">Đang nhận %1$s (đã hoàn tất %2$d%%)</string>
<string name="download_x_file">Tải về %s</string>
<string name="delete_x_file">Xoá %s</string>
<string name="file">tập tin</string>
<string name="open_x_file">Mở %s</string>
<string name="sending_file">đang gửi (đã hoàn tất %1$d%%)</string>
<string name="preparing_file">Đang chuẩn bị sẵn sàng để chia sẻ tệp</string>
<string name="x_file_offered_for_download">Đã đề xuất tải về %s</string>
<string name="cancel_transmission">Huỷ chuyển tập tin</string>
<string name="file_transmission_failed">không thể chia sẻ tệp</string>
<string name="file_transmission_cancelled">đã huỷ truyền tệp</string>
<string name="file_deleted">Đã xoá tệp</string>
<string name="no_application_found_to_open_file">Không tìm thấy ứng dụng nào để mở tệp</string>
<string name="no_application_found_to_open_link">Không tìm thấy ứng dụng nào để mở liên kết</string>
<string name="no_application_found_to_view_contact">Không tìm thấy ứng dụng nào để xem liên hệ</string>
<string name="pref_show_dynamic_tags">Thẻ năng động</string>
<string name="pref_show_dynamic_tags_summary">Hiện nhãn chỉ đọc bên dưới các liên hệ</string>
<string name="enable_notifications">Bật thông báo</string>
<string name="no_conference_server_found">Không tìm thấy máy chủ trò chuyện nhóm nào</string>
<string name="conference_creation_failed">Không thể tạo cuộc trò chuyện nhóm</string>
<string name="account_image_description">Ảnh đại diện tài khoản</string>
<string name="copy_omemo_clipboard_description">Sao chép dấu vân tay OMEMO vào clipboard</string>
<string name="regenerate_omemo_key">Tạo lại khoá OMEMO</string>
<string name="clear_other_devices">Xoá các thiết bị</string>
<string name="clear_other_devices_desc">Bạn có chắc bạn muốn xoá tất cả thiết bị khác khỏi thông báo OMEMO không? Lần sau khi các thiết bị của bạn kết nối, chúng sẽ tự thông báo lại, nhưng có thể sẽ không nhận các tin nhắn được gửi trong lúc đó.</string>
<string name="error_no_keys_to_trust_server_error">Không có mã khoá dùng được nào có sẵn cho liên hệ này.\nKhông thể lấy mã khoá mới từ máy chủ. Có lẽ có gì đó sai với máy chủ của liên hệ?</string>
<string name="error_no_keys_to_trust_presence">Không có mã khoá dùng được nào có sẵn cho liên hệ này.\nHãy chắc chắn là cả hai có đăng ký sự có mặt.</string>
<string name="error_trustkeys_title">Có gì đó sai đã xảy ra</string>
<string name="fetching_history_from_server">Đang nhận lịch sử từ máy chủ</string>
<string name="no_more_history_on_server">Không còn lịch sử nào trên máy chủ</string>
<string name="updating">Đang cập nhật...</string>
@ -227,6 +367,7 @@
<string name="change_password">Đổi mật khẩu</string>
<string name="current_password">Mật khẩu hiện tại</string>
<string name="new_password">Mật khẩu mới</string>
<string name="password_should_not_be_empty">Mật khẩu không thể trống</string>
<string name="enable_all_accounts">Bật toàn bộ tài khoản</string>
<string name="disable_all_accounts">Tắt toàn bộ tài khoản</string>
<string name="perform_action_with">Thực hiện thao tác với</string>
@ -235,16 +376,36 @@
<string name="outcast">Kẻ bị ruồng bỏ</string>
<string name="member">Thành viên</string>
<string name="advanced_mode">Chế độ nâng cao</string>
<string name="grant_membership">Cấp đặc quyền thành viên</string>
<string name="remove_membership">Thu hồi đặc quyền thành viên</string>
<string name="grant_admin_privileges">Trao quyền quản trị</string>
<string name="remove_admin_privileges">Huỷ quyền quản trị</string>
<string name="grant_owner_privileges">Cấp đặc quyền chủ sở hữu</string>
<string name="remove_owner_privileges">Thu hồi đặc quyền chủ sở hữu</string>
<string name="remove_from_room">Xoá khỏi cuộc trò chuyện nhóm</string>
<string name="remove_from_channel">Xoá khỏi kênh</string>
<string name="could_not_change_affiliation">Không thể đổi mối quan hệ của %s</string>
<string name="ban_from_conference">Cấm khỏi cuộc trò chuyện nhóm</string>
<string name="ban_from_channel">Cấm khỏi kênh</string>
<string name="removing_from_public_conference">Bạn đang cố xoá %s khỏi một kênh công khai. Cách duy nhất để làm thế là cấm người dùng đó mãi mãi.</string>
<string name="ban_now">Cấm ngay</string>
<string name="could_not_change_role">Không thể đổi phận sự của %s</string>
<string name="conference_options">Thiết lâp cuộc trò chuyện nhóm riêng tư</string>
<string name="channel_options">Thiết lập kênh công khai</string>
<string name="members_only">Riêng, chỉ dành cho thành viên</string>
<string name="non_anonymous">Làm cho các địa chỉ XMPP có thể được bất kỳ ai nhìn thấy</string>
<string name="moderated">Làm cho kênh được kiểm duyệt</string>
<string name="you_are_not_participating">Hiện bạn chưa tham gia</string>
<string name="modified_conference_options">Đã sửa đổi tuỳ chọn cuộc trò chuyện nhóm!</string>
<string name="could_not_modify_conference_options">Không thể sửa đổi tuỳ chọn cuộc trò chuyện nhóm</string>
<string name="never">Chưa từng</string>
<string name="until_further_notice">Cho đến thông báo tiếp theo</string>
<string name="snooze">Báo lại</string>
<string name="reply">Trả lời</string>
<string name="mark_as_read">Đánh dấu là đã đọc</string>
<string name="pref_input_options">Đầu vào</string>
<string name="pref_enter_is_send">Bấm Enter để gửi</string>
<string name="pref_enter_is_send_summary">Sử dụng phím Enter để gửi tin nhắn. Bạn luôn có thể sử dụng Ctrl+Enter để gửi tin nhắn, kể cả khi tuỳ chọn này bị tắt.</string>
<string name="pref_display_enter_key">Hiện nút Enter</string>
<string name="pref_display_enter_key_summary">Đổi nút biểu tượng cảm xúc thành nút Enter</string>
<string name="audio">âm thanh</string>
@ -259,11 +420,17 @@
<string name="hide_offline">Ẩn ngoại tuyến</string>
<string name="contact_is_typing">%s đang gõ...</string>
<string name="contact_has_stopped_typing">%s đã ngừng gõ</string>
<string name="contacts_are_typing">%s đang gõ...</string>
<string name="contacts_have_stopped_typing">%s đã ngừng gõ</string>
<string name="pref_chat_states">Thông báo đang gõ</string>
<string name="pref_chat_states_summary">Để cho các liên hệ của bạn biết khi bạn đang viết tin nhắn cho họ</string>
<string name="send_location">Gửi vị trí</string>
<string name="show_location">Hiện vị trí</string>
<string name="no_application_found_to_display_location">Không tìm thấy ứng dụng nào để hiển thị vị trí</string>
<string name="location">Vị trí</string>
<string name="title_undo_swipe_out_conversation">Đã đóng cuộc hội thoại</string>
<string name="title_undo_swipe_out_group_chat">Đã rời khỏi cuộc trò chuyện nhóm riêng tư</string>
<string name="title_undo_swipe_out_channel">Đã rời khỏi kênh công khai</string>
<string name="pref_dont_trust_system_cas_title">Đừng tin các CA hệ thống</string>
<string name="pref_dont_trust_system_cas_summary">Tất cả chứng nhận phải được phê duyệt thủ công</string>
<string name="pref_remove_trusted_certificates_title">Xoá các chứng nhận</string>
@ -275,41 +442,97 @@
<plurals name="toast_delete_certificates">
<item quantity="other">Đã xoá %d chứng nhận</item>
</plurals>
<string name="pref_quick_action_summary">Thay thế nút \"Gửi\" bằng hành động nhanh</string>
<string name="pref_quick_action">Thao tác nhanh</string>
<string name="none">Không có</string>
<string name="recently_used">Dùng gần đây nhất</string>
<string name="choose_quick_action">Chọn thao tác nhanh</string>
<string name="search_contacts">Tìm kiếm liên hệ</string>
<string name="search_bookmarks">Tìm kiếm dấu trang</string>
<string name="send_private_message">Gửi tin nhắn cá nhân</string>
<string name="user_has_left_conference">%1$s đã rời khỏi cuộc trò chuyện nhóm</string>
<string name="username">Tên người dùng</string>
<string name="username_hint">Tên người dùng</string>
<string name="invalid_username">Đây không phải là tên người dùng hợp lệ</string>
<string name="download_failed_server_not_found">Tải xuống thất bại: Không thấy máy chủ</string>
<string name="download_failed_file_not_found">Tải xuống thất bại: Không thấy tập tin</string>
<string name="download_failed_could_not_connect">Tải xuống thất bại: Không thể kết nối đến máy chủ</string>
<string name="download_failed_could_not_write_file">Tải xuống thất bại: Không thể ghi tệp</string>
<string name="account_status_tor_unavailable">Mạng Tor chưa sẵn sàng</string>
<string name="account_status_bind_failure">Gắn kết thất bại</string>
<string name="account_status_host_unknown">Máy chủ không chịu trách nhiệm cho miền này</string>
<string name="server_info_broken">Bị hỏng</string>
<string name="pref_presence_settings">Tính khả dụng</string>
<string name="pref_away_when_screen_off">Vắng mặt khi thiết bị bị khoá</string>
<string name="pref_away_when_screen_off_summary">Hiện là Vắng mặt khi thiết bị bị khoá</string>
<string name="pref_dnd_on_silent_mode">Bận ở chế độ im lặng</string>
<string name="pref_dnd_on_silent_mode_summary">Hiện là Bận khi thiết bị ở chế độ im lặng</string>
<string name="pref_treat_vibrate_as_silent">Coi chế độ rung như chế độ im lặng</string>
<string name="pref_treat_vibrate_as_dnd_summary">Hiện là Bận khi thiết bị ở chế độ rung</string>
<string name="pref_show_connection_options">Cài đặt kết nối mở rộng</string>
<string name="pref_show_connection_options_summary">Hiện tên máy chủ và cài đặt cổng khi thiết lập tài khoản</string>
<string name="hostname_example">xmpp.example.com</string>
<string name="action_add_account_with_certificate">Đăng nhập bằng chứng chỉ</string>
<string name="unable_to_parse_certificate">Không thể xử lý chứng chỉ</string>
<string name="mam_prefs">Cài đặt lưu trữ</string>
<string name="server_side_mam_prefs">Cài đặt lưu trữ ở phía máy chủ</string>
<string name="fetching_mam_prefs">Đang lấy cài đặt lưu trữ. Vui lòng đợi...</string>
<string name="unable_to_fetch_mam_prefs">Không thể lấy cài đặt lưu trữ</string>
<string name="captcha_required">Yêu cầu CAPTCHA</string>
<string name="captcha_hint">Nhập văn bản trong hình ảnh ở trên</string>
<string name="certificate_chain_is_not_trusted">Chuỗi chứng chỉ không được tin tưởng</string>
<string name="jid_does_not_match_certificate">Địa chỉ XMPP không khớp với chứng chỉ</string>
<string name="action_renew_certificate">Gia hạn chứng nhận</string>
<string name="error_fetching_omemo_key">Lỗi nhập khoá OMEMO!</string>
<string name="verified_omemo_key_with_certificate">Khoá OMEMO đã xác minh với chứng nhận!</string>
<string name="device_does_not_support_certificates">Thiết bị không hỗ trợ chọn lựa các chứng chỉ của máy trạm!</string>
<string name="pref_connection_options">Kết nối</string>
<string name="pref_use_tor">Kết nối đến Tor</string>
<string name="pref_use_tor_summary">Chuyển toàn bộ kết nối thông qua mạng Tor. Cần có Orbot</string>
<string name="account_settings_hostname">Tên máy chủ</string>
<string name="account_settings_port">Cổng</string>
<string name="hostname_or_onion">Địa chỉ máy chủ hoặc .onion</string>
<string name="not_a_valid_port">Đây không phải là số cổng hợp lệ</string>
<string name="not_valid_hostname">Đây không phải là tên máy chủ hợp lệ</string>
<string name="connected_accounts">%1$d trên %2$d tài khoản đã kết nối</string>
<plurals name="x_messages">
<item quantity="other">%dv tin nhắn</item>
</plurals>
<string name="load_more_messages">Tải thêm tin nhắn</string>
<string name="shared_file_with_x">Đã chia sẻ tệp với %s</string>
<string name="shared_image_with_x">Đã chia sẻ hình ảnh với %s</string>
<string name="shared_images_with_x">Đã chia sẻ các hình ảnh với %s</string>
<string name="shared_text_with_x">Đã chia sẻ văn bản với %s</string>
<string name="no_storage_permission">Cấp quyền truy cập bộ nhớ cho %1$s</string>
<string name="no_camera_permission">Cấp quyền truy cập camera cho %1$s</string>
<string name="sync_with_contacts">Đồng bộ với danh bạ</string>
<string name="sync_with_contacts_long">%1$s muốn quyền truy cập sổ địa chỉ của bạn để nối nó với danh sách liên hệ XMPP của bạn.\nViệc này sẽ hiển thị họ tên và ảnh đại diện của các liên hệ của bạn.\n\n%1$s sẽ chỉ đọc sổ địa chỉ của bạn và nối nó một cách cục bộ mà không tải gì cả lên máy chủ của bạn.</string>
<string name="sync_with_contacts_quicksy"><![CDATA[Quicksy cần quyền truy cập vào số điện thoại của các liên hệ của bạn để đưa ra đề xuất về các liên hệ có thể có đã ở trên Quicksy.<br><br>Chúng tôi sẽ không lưu trữ bản sao của các số điện thoại đó.\n\nĐể biết thêm thông tin hãy đọc <a href="https://quicksy.im/#privacy">chính sách riêng tư</a> của chúng tôi.<br><br>Bây giờ bạn sẽ được hỏi cấp quyền truy cập danh bạ.]]></string>
<string name="notify_on_all_messages">Thông báo tất cả tin nhắn</string>
<string name="notify_only_when_highlighted">Chỉ thông báo khi được nhắc đến</string>
<string name="notify_never">Đã tắt thông báo</string>
<string name="notify_paused">Đã dừng thông báo</string>
<string name="pref_picture_compression">Nén hình ảnh</string>
<string name="pref_picture_compression_summary">Gợi ý: Sử dụng \'Chọn tệp\' thay vì \'Chọn ảnh\' để gửi từng hình ảnh không nén riêng biệt mà không tính đến cài đặt này.</string>
<string name="always">Luôn luôn</string>
<string name="large_images_only">Chỉ các hình ảnh lớn</string>
<string name="battery_optimizations_enabled">Đã bật tối ưu pin</string>
<string name="battery_optimizations_enabled_explained">Thiết bị của bạn đang sử dụng tối ưu hoá pin sâu cho %1$s, điều này có thể dẫn đến thông báo bị trì hoãn hay thậm chí là mất tin nhắn.\nChúng tôi khuyên bạn tắt tối ưu hoá pin.</string>
<string name="battery_optimizations_enabled_dialog">Thiết bị của bạn đang sử dụng tối ưu hoá pin sâu cho %1$s, điều này có thể dẫn đến thông báo bị trì hoãn hay thậm chí là mất tin nhắn.\nBây giờ bạn sẽ được hỏi để tắt tối ưu hoá pin.</string>
<string name="disable">Tắt</string>
<string name="selection_too_large">Khu vực chọn quá lớn</string>
<string name="no_accounts">(Không có tài khoản đã kích hoạt)</string>
<string name="this_field_is_required">Trường này là bắt buộc</string>
<string name="correct_message">Sửa tin nhắn</string>
<string name="send_corrected_message">Gửi tin nhắn đã sửa</string>
<string name="no_keys_just_confirm">Bạn đã xác minh mã kiểm tra của người này một cách bảo mật để xác nhận sự tin tưởng. Bằng cách chọn \"Xong\" bạn chỉ đang xác nhận rằng %s ở trong cuộc trò chuyện nhóm này.</string>
<string name="this_account_is_disabled">Bạn đã tắt tài khoản này</string>
<string name="security_error_invalid_file_access">Lỗi bảo mật: Truy cập tệp không hợp lệ!</string>
<string name="no_application_to_share_uri">Không tìm thấy ứng dụng nào để chia sẻ URI</string>
<string name="share_uri_with">Chia sẻ URI với...</string>
<string name="agree_and_continue">Đồng ý và tiếp tục</string>
<string name="your_full_jid_will_be">Địa chỉ XMPP đầy đủ của bạn sẽ là: %s</string>
<string name="create_account">Tạo tài khoản</string>
<string name="presence_online">Trực tuyến</string>
<string name="gp_disable">Tắt</string>
<string name="message_copied_to_clipboard">Đã chép tin nhắn vào clipboard</string>

View File

@ -147,6 +147,7 @@
<string name="error_file_not_found">未找到文件</string>
<string name="error_io_exception">常规I/O错误。可能是存储空间不足</string>
<string name="error_security_exception_during_image_copy">您用来选择图片的程序没有给予读取权限。\n\n &lt;/small&gt;尝试其他文件管理器选择图片&lt;/small&gt;</string>
<string name="error_security_exception">你用来共享此文件的应用程序没有提供足够的权限。</string>
<string name="account_status_unknown">未知</string>
<string name="account_status_disabled">暂时不可用</string>
<string name="account_status_online">在线</string>
@ -161,6 +162,7 @@
<string name="account_status_regis_not_sup">服务器不支持注册</string>
<string name="account_status_regis_invalid_token">无效的注册令牌</string>
<string name="account_status_tls_error">TLS协商失败</string>
<string name="account_status_tls_error_domain">域名不可验证</string>
<string name="account_status_policy_violation">违反政策</string>
<string name="account_status_incompatible_server">服务器不兼容</string>
<string name="account_status_stream_error">流错误</string>
@ -947,4 +949,5 @@
<string name="server_does_not_support_easy_onboarding_invites">服务器不支持生成邀请</string>
<string name="no_active_accounts_support_this">没有活跃帐户支持此功能</string>
<string name="backup_started_message">已启动备份。一旦完成,你会收到通知。</string>
<string name="unable_to_enable_video">无法启用视频</string>
</resources>

View File

@ -163,6 +163,7 @@
<string name="account_status_regis_not_sup">Registration not supported by server</string>
<string name="account_status_regis_invalid_token">Invalid registration token</string>
<string name="account_status_tls_error">TLS negotiation failed</string>
<string name="account_status_tls_error_domain">Domain not verifiable</string>
<string name="account_status_policy_violation">Policy violation</string>
<string name="account_status_incompatible_server">Incompatible server</string>
<string name="account_status_stream_error">Stream error</string>

View File

@ -48,6 +48,7 @@ import eu.siacs.conversations.crypto.sasl.Plain;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Entry;
import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.utils.AccountUtils;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
@ -260,7 +261,7 @@ public class QuickConversationsService extends AbstractQuickConversationsService
}
private void setHeader(HttpURLConnection connection) {
connection.setRequestProperty("User-Agent", service.getIqGenerator().getUserAgent());
connection.setRequestProperty("User-Agent", HttpConnectionManager.getUserAgent());
connection.setRequestProperty("Installation-Id", getInstallationId());
connection.setRequestProperty("Accept-Language", Locale.getDefault().getLanguage());
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pref_notification_grace_period_summary">Khoảng thời gian Quicksy giữ yên lặng sau khi xem hoạt động trên một thiết bị khác</string>
<string name="pref_never_send_crash_summary">Bằng việc gửi báo cáo hoạt động, bạn đang hỗ trợ sự phát triển liên tục của Quicksy</string>
<string name="pref_broadcast_last_activity_summary">Để cho tất cả liên hệ của bạn biết khi bạn sử dụng Quicksy</string>
<string name="huawei_protected_apps_summary">Để tiếp tục nhận các thông báo, kể cả khi màn hình đã tắt, bạn cần thêm Quicksy vào danh sách các ứng dụng được bảo vệ.</string>
<string name="set_profile_picture">Ảnh hồ sơ Quicksy</string>
<string name="not_available_in_your_country">Quicksy không có sẵn ở quốc gia của bạn.</string>
<string name="unable_to_verify_server_identity">Không thể xác minh danh tính máy chủ.</string>
<string name="unknown_security_error">Lỗi bảo mật không xác định.</string>
<string name="timeout_while_connecting_to_server">Hết thời gian chờ khi kết nối đến máy chủ.</string>
</resources>