diff --git a/CHANGELOG.md b/CHANGELOG.md
index 14dbf7755..091e36daf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+### Version 2.7.1
+
+* Fix avatar selection on some Android 10 devices
+* Fix file transfer for larger files
+
### Version 2.7.0
* Provide PDF preview on Android 5+
diff --git a/README.md b/README.md
index 5db157c98..b2808a279 100644
--- a/README.md
+++ b/README.md
@@ -175,7 +175,7 @@ FCM (Google Push) allows an app to wake up from *Doze* which is (as the name sug
#### Conversations doesn’t work for me. Where can I get help?
-You can join our conference room on `support@conference.chat.sum7.eu`.
+You can join our conference room on [`support@conference.chat.sum7.eu`](https://conversations.im/j/support@conference.chat.sum7.eu).
A lot of people in there are able to answer basic questions about the usage of
Conversations or can provide you with tips on running your own XMPP server. If
you found a bug or your app crashes please read the Developer / Report Bugs
@@ -265,7 +265,7 @@ and introduce yourself to `iNPUTmice` so he can approve your join request.
#### How do I backup / move Conversations to a new device?
On the one hand Conversations supports Message Archive Management to keep a server side history of your messages so when migrating to a new device that device can display your entire history. However that does not work if you enable OMEMO due to its forward secrecy. (Read [The State of Mobile XMPP in 2016](https://gultsch.de/xmpp_2016.html) especially the section on encryption.)
-As of version 2.4.0 an integrated Backup & Restore function will help with this, go to Settings → Expert settings → Create backup. A notification will pop-up during the creation process that will announce you when it's ready. After the files, one for each account, are created, you can move the **Conversations** folder *(if you want your old media files too)* or only the **Conversations/Backup** folder *(for OMEMO keys and history only)* to your new device (or to a storage place) where a freshly installed Conversations can restore each account. Don't forget to enable the accounts after a succesful restore.
+As of version 2.4.0 an integrated Backup & Restore function will help with this, go to Settings and you’ll find a setting called Create backup. A notification will pop-up during the creation process that will announce you when it's ready. After the files, one for each account, are created, you can move the **Conversations** folder *(if you want your old media files too)* or only the **Conversations/Backup** folder *(for OMEMO keys and history only)* to your new device (or to a storage place) where a freshly installed Conversations can restore each account. Don't forget to enable the accounts after a succesful restore.
This backup method will include your OMEMO keys. Due to forward secrecy you will not be able to recover messages sent and received between creating the backup and restoring it. If you have a server side archive (MAM) those messages will be retrieved but displayed as *unable to decrypt*. For technical reasons you might also lose the first message you either sent or receive after the restore; for each conversation you have. This message will then also show up as *unable to decrypt*, but this will automatically recover itself as long as both participants are on Conversations 2.3.11+. Note that this doesn’t happen if you just transfer to a new phone and no messages have been exchanged between backup and restore.
diff --git a/build.gradle b/build.gradle
index e9906e95f..8367d7a1b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -54,7 +54,7 @@ dependencies {
compatImplementation "com.android.support:support-emoji-appcompat:$supportLibVersion"
conversationsFreeCompatImplementation "com.android.support:support-emoji-bundled:$supportLibVersion"
quicksyFreeCompatImplementation "com.android.support:support-emoji-bundled:$supportLibVersion"
- implementation 'org.bouncycastle:bcmail-jdk15on:1.58'
+ implementation 'org.bouncycastle:bcmail-jdk15on:1.64'
//zxing stopped supporting Java 7 so we have to stick with 3.3.3
//https://github.com/zxing/zxing/issues/1170
implementation 'com.google.zxing:core:3.3.3'
@@ -90,8 +90,8 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 25
- versionCode 364
- versionName "2.7.0"
+ versionCode 367
+ versionName "2.7.1"
archivesBaseName += "-$versionName"
applicationId "eu.sum7.conversations"
resValue "string", "applicationId", applicationId
diff --git a/metadata/en-US/changelogs/367.txt b/metadata/en-US/changelogs/367.txt
new file mode 100644
index 000000000..a882ff386
--- /dev/null
+++ b/metadata/en-US/changelogs/367.txt
@@ -0,0 +1,2 @@
+• Fix avatar selection on some Android 10 devices
+• Fix file transfer for larger files
diff --git a/src/conversations/res/values-gl/strings.xml b/src/conversations/res/values-gl/strings.xml
index 25a40a42a..5401a977d 100644
--- a/src/conversations/res/values-gl/strings.xml
+++ b/src/conversations/res/values-gl/strings.xml
@@ -1,10 +1,10 @@
- Escolla o seu provedor XMPP
+ Escolle o teu provedor XMPP
Utilizar chat.sum7.eu
Crear nova conta
- Xa posúe unha conta XMPP? Este pode ser o caso se xa está a utilizar outro cliente XMPP ou utilizou Conversations previamente. Se non é así pode crear unha nova conta agora mesmo.\nTruco: Algúns provedores de correo tamén proporcionan contas XMPP.
- XMPP é unha rede de mensaxería independente do provedor. Pode utilizar este cliente con calquer provedor XMPP da súa elección.\nMais para a súa conveniencia fixemos que fose doado crear unha conta en chat.sum7.eu; un provedor especialmente axeitado para utilizar con Conversations.
+ Xa posúes unha conta XMPP? Este pode ser o caso se xa estás a utilizar outro cliente XMPP ou utilizaches Conversations previamente. Se non é así podes crear unha nova conta agora mesmo.\nTruco: Algúns provedores de correo tamén proporcionan contas XMPP.
+ XMPP é unha rede de mensaxería independente do provedor. Podes utilizar este cliente con calquera provedor XMPP da túa elección.\nMais para a tua conveniencia fixemos que fose doado crear unha conta en chat.sum7.eu; un provedor especialmente axeitado para utilizar con Conversations.
Convidáronte a %1$s. Guiarémoste no proceso para crear unha conta.\nAo escoller %1$s como provedor poderás comunicarte con usuarias de outros provedores cando lles deas o teu enderezo XMPP completo.
Convidáronte a %1$s. Escollemos un nome de usuaria por ti. Guiarémoste no proceso de crear unha conta.\nPoderás comunicarte con usuarias de outros provedores cando lles digas o teu enderezo XMPP completo.
O convite do teu servidor
diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java
index d58bd2e21..750029931 100644
--- a/src/main/java/eu/siacs/conversations/Config.java
+++ b/src/main/java/eu/siacs/conversations/Config.java
@@ -100,7 +100,6 @@ public final class Config {
public static final boolean REMOVE_BROKEN_DEVICES = false;
public static final boolean OMEMO_PADDING = false;
public static final boolean PUT_AUTH_TAG_INTO_KEY = true;
- public static final boolean TWELVE_BYTE_IV = true;
public static final boolean USE_BOOKMARKS2 = false;
diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
index 018a86b5d..e67755586 100644
--- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
+++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java
@@ -651,7 +651,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
final boolean wipe,
final boolean firstAttempt) {
final Bundle publishOptions = account.getXmppConnection().getFeatures().pepPublishOptions() ? PublishOptions.openAccess() : null;
- IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles(
+ final IqPacket publish = mXmppConnectionService.getIqGenerator().publishBundles(
signedPreKeyRecord, axolotlStore.getIdentityKeyPair().getPublicKey(),
preKeyRecords, getOwnDeviceId(), publishOptions);
Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ": Bundle " + getOwnDeviceId() + " in PEP not current. Publishing...");
diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java
index 13082deac..bec0ff9e2 100644
--- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java
+++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java
@@ -115,14 +115,13 @@ public class XmppAxolotlMessage {
generator.init(128);
return generator.generateKey().getEncoded();
} catch (NoSuchAlgorithmException e) {
- Log.e(Config.LOGTAG, e.getMessage());
- return null;
+ throw new IllegalStateException(e);
}
}
private static byte[] generateIv() {
final SecureRandom random = new SecureRandom();
- byte[] iv = new byte[Config.TWELVE_BYTE_IV ? 12 : 16];
+ final byte[] iv = new byte[12];
random.nextBytes(iv);
return iv;
}
diff --git a/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java b/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java
index c88af6f95..c0b3512a3 100644
--- a/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java
+++ b/src/main/java/eu/siacs/conversations/entities/DownloadableFile.java
@@ -1,7 +1,10 @@
package eu.siacs.conversations.entities;
+import android.util.Log;
+
import java.io.File;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.utils.MimeUtils;
public class DownloadableFile extends File {
@@ -66,6 +69,7 @@ public class DownloadableFile extends File {
this.iv = new byte[]{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf };
System.arraycopy(keyIvCombo, 0, aeskey, 0, 32);
}
+ Log.d(Config.LOGTAG,"using "+this.iv.length+"-byte IV for file transmission");
}
public void setKey(byte[] key) {
diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java
index 360103aa0..e44d2a2c0 100644
--- a/src/main/java/eu/siacs/conversations/entities/Message.java
+++ b/src/main/java/eu/siacs/conversations/entities/Message.java
@@ -613,6 +613,8 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
this.getBody().length() + message.getBody().length() <= Config.MAX_DISPLAY_MESSAGE_CHARS &&
!message.isGeoUri() &&
!this.isGeoUri() &&
+ !message.isOOb() &&
+ !this.isOOb() &&
!message.treatAsDownloadable() &&
!this.treatAsDownloadable() &&
!message.getBody().startsWith(ME_COMMAND) &&
diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java
index 08fae1bc5..430c7532b 100644
--- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java
+++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java
@@ -105,11 +105,12 @@ public class HttpUploadConnection implements Transferable {
} else {
this.mime = this.file.getMimeType();
}
+ final long originalFileSize = file.getSize();
this.delayed = delay;
if (Config.ENCRYPT_ON_HTTP_UPLOADED
|| message.getEncryption() == Message.ENCRYPTION_AXOLOTL
|| message.getEncryption() == Message.ENCRYPTION_OTR) {
- this.key = new byte[Config.TWELVE_BYTE_IV ? 44 : 48];
+ this.key = new byte[44];
mXmppConnectionService.getRNG().nextBytes(this.key);
this.file.setKeyAndIv(this.key);
}
@@ -128,7 +129,7 @@ public class HttpUploadConnection implements Transferable {
md5 = null;
}
- this.file.setExpectedSize(file.getSize() + (file.getKey() != null ? 16 : 0));
+ this.file.setExpectedSize(originalFileSize + (file.getKey() != null ? 16 : 0));
message.resetFileParams();
this.mSlotRequester.request(method, account, file, mime, md5, new SlotRequester.OnSlotRequested() {
@Override
diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java
index 81f3f80bc..98721aaf4 100644
--- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java
+++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java
@@ -5,6 +5,14 @@ import android.os.PowerManager;
import android.os.SystemClock;
import android.util.Log;
+import org.bouncycastle.crypto.engines.AESEngine;
+import org.bouncycastle.crypto.io.CipherInputStream;
+import org.bouncycastle.crypto.io.CipherOutputStream;
+import org.bouncycastle.crypto.modes.AEADBlockCipher;
+import org.bouncycastle.crypto.modes.GCMBlockCipher;
+import org.bouncycastle.crypto.params.AEADParameters;
+import org.bouncycastle.crypto.params.KeyParameter;
+
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
@@ -15,24 +23,15 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.concurrent.atomic.AtomicLong;
-import javax.crypto.Cipher;
-import javax.crypto.CipherInputStream;
-import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.utils.Compatibility;
-import eu.siacs.conversations.utils.CryptoHelper;
public class AbstractConnectionManager {
- private static final String KEYTYPE = "AES";
- private static final String CIPHERMODE = "AES/GCM/NoPadding";
- private static final String PROVIDER = "BC";
private static final int UI_REFRESH_THRESHOLD = 250;
private static final AtomicLong LAST_UI_UPDATE_CALL = new AtomicLong(0);
protected XmppConnectionService mXmppConnectionService;
@@ -43,10 +42,8 @@ public class AbstractConnectionManager {
public static InputStream upgrade(DownloadableFile file, InputStream is) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, NoSuchProviderException {
if (file.getKey() != null && file.getIv() != null) {
- final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
- SecretKeySpec keySpec = new SecretKeySpec(file.getKey(), KEYTYPE);
- IvParameterSpec ivSpec = new IvParameterSpec(file.getIv());
- cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
+ AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
+ cipher.init(true, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv()));
return new CipherInputStream(is, cipher);
} else {
return is;
@@ -61,17 +58,15 @@ public class AbstractConnectionManager {
return os;
}
} catch (FileNotFoundException e) {
- Log.d(Config.LOGTAG,"unable to create output stream", e);
+ Log.d(Config.LOGTAG, "unable to create output stream", e);
return null;
}
try {
- final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
- SecretKeySpec keySpec = new SecretKeySpec(file.getKey(), KEYTYPE);
- IvParameterSpec ivSpec = new IvParameterSpec(file.getIv());
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
+ AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
+ cipher.init(false, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv()));
return new CipherOutputStream(os, cipher);
} catch (Exception e) {
- Log.d(Config.LOGTAG,"unable to create cipher output stream", e);
+ Log.d(Config.LOGTAG, "unable to create cipher output stream", e);
return null;
}
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index 4280e6f00..63d6a1911 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1838,7 +1838,7 @@ public class XmppConnectionService extends Service {
private void markFileDeleted(final String path) {
synchronized (FILENAMES_TO_IGNORE_DELETION) {
if (FILENAMES_TO_IGNORE_DELETION.remove(path)) {
- Log.d(Config.LOGTAG,"ignored deletion of "+path);
+ Log.d(Config.LOGTAG, "ignored deletion of " + path);
return;
}
}
@@ -1854,7 +1854,7 @@ public class XmppConnectionService extends Service {
for (Conversation conversation : getConversations()) {
deleted |= conversation.markAsDeleted(uuids);
}
- for(final String uuid : uuids) {
+ for (final String uuid : uuids) {
evictPreview(uuid);
}
if (deleted) {
@@ -3172,16 +3172,20 @@ public class XmppConnectionService extends Service {
conversation.setAttribute("accept_non_anonymous", true);
updateConversation(conversation);
}
- IqPacket request = new IqPacket(IqPacket.TYPE.GET);
+ if (options.containsKey("muc#roomconfig_moderatedroom")) {
+ final boolean moderated = "1".equals(options.getString("muc#roomconfig_moderatedroom"));
+ options.putString("members_by_default", moderated ? "0" : "1");
+ }
+ final IqPacket request = new IqPacket(IqPacket.TYPE.GET);
request.setTo(conversation.getJid().asBareJid());
request.query("http://jabber.org/protocol/muc#owner");
sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
if (packet.getType() == IqPacket.TYPE.RESULT) {
- Data data = Data.parse(packet.query().findChild("x", Namespace.DATA));
+ final Data data = Data.parse(packet.query().findChild("x", Namespace.DATA));
data.submit(options);
- IqPacket set = new IqPacket(IqPacket.TYPE.SET);
+ final IqPacket set = new IqPacket(IqPacket.TYPE.SET);
set.setTo(conversation.getJid().asBareJid());
set.query("http://jabber.org/protocol/muc#owner").addChild(data);
sendIqPacket(account, set, new OnIqPacketReceived() {
@@ -4580,7 +4584,7 @@ public class XmppConnectionService extends Service {
public void evictPreview(String uuid) {
if (mBitmapCache.remove(uuid) != null) {
- Log.d(Config.LOGTAG,"deleted cached preview");
+ Log.d(Config.LOGTAG, "deleted cached preview");
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java
index 4c7b77276..898f607c4 100644
--- a/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java
@@ -49,6 +49,8 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.ui.interfaces.OnAvatarPublication;
import eu.siacs.conversations.ui.util.PendingItem;
+import static eu.siacs.conversations.ui.PublishProfilePictureActivity.REQUEST_CHOOSE_PICTURE;
+
public class PublishGroupChatProfilePictureActivity extends XmppActivity implements OnAvatarPublication {
private final PendingItem pendingConversationUuid = new PendingItem<>();
private ActivityPublishProfilePictureBinding binding;
@@ -93,7 +95,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme
configureActionBar(getSupportActionBar());
this.binding.cancelButton.setOnClickListener((v) -> this.finish());
this.binding.secondaryHint.setVisibility(View.GONE);
- this.binding.accountImage.setOnClickListener((v) -> this.chooseAvatar());
+ this.binding.accountImage.setOnClickListener((v) -> PublishProfilePictureActivity.chooseAvatar(this));
Intent intent = getIntent();
String uuid = intent == null ? null : intent.getStringExtra("uuid");
if (uuid != null) {
@@ -113,7 +115,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
- CropImage.ActivityResult result = CropImage.getActivityResult(data);
+ final CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
this.uri = result.getUri();
if (xmppConnectionServiceBound) {
@@ -125,17 +127,13 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme
Toast.makeText(this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
}
+ } else if (requestCode == REQUEST_CHOOSE_PICTURE) {
+ if (resultCode == RESULT_OK) {
+ PublishProfilePictureActivity.cropUri(this, data.getData());
+ }
}
}
- private void chooseAvatar() {
- CropImage.activity()
- .setOutputCompressFormat(Bitmap.CompressFormat.PNG)
- .setAspectRatio(1, 1)
- .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE)
- .start(this);
- }
-
@Override
public void onAvatarPublicationSucceeded() {
runOnUiThread(() -> {
diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java
index 8f91ffdc1..db05cc8bf 100644
--- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java
@@ -1,8 +1,10 @@
package eu.siacs.conversations.ui;
+import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.util.Log;
@@ -26,6 +28,8 @@ import eu.siacs.conversations.utils.PhoneHelper;
public class PublishProfilePictureActivity extends XmppActivity implements XmppConnectionService.OnAccountUpdate, OnAvatarPublication {
+ public static final int REQUEST_CHOOSE_PICTURE = 0x1337;
+
private ImageView avatar;
private TextView hintOrWarning;
private TextView secondaryHint;
@@ -106,7 +110,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
}
finish();
});
- this.avatar.setOnClickListener(v -> chooseAvatar());
+ this.avatar.setOnClickListener(v -> chooseAvatar(this));
this.defaultUri = PhoneHelper.getProfilePictureUri(getApplicationContext());
if (savedInstanceState != null) {
this.avatarUri = savedInstanceState.getParcelable("uri");
@@ -139,15 +143,28 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
Toast.makeText(this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
}
+ } else if (requestCode == REQUEST_CHOOSE_PICTURE) {
+ if (resultCode == RESULT_OK) {
+ cropUri(this, data.getData());
+ }
}
}
- private void chooseAvatar() {
- CropImage.activity()
- .setOutputCompressFormat(Bitmap.CompressFormat.PNG)
- .setAspectRatio(1, 1)
- .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE)
- .start(this);
+ public static void chooseAvatar(final Activity activity) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("image/*");
+ activity.startActivityForResult(
+ Intent.createChooser(intent, activity.getString(R.string.attach_choose_picture)),
+ REQUEST_CHOOSE_PICTURE
+ );
+ } else {
+ CropImage.activity()
+ .setOutputCompressFormat(Bitmap.CompressFormat.PNG)
+ .setAspectRatio(1, 1)
+ .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE)
+ .start(activity);
+ }
}
@Override
@@ -181,10 +198,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
final Uri uri = intent != null ? intent.getData() : null;
if (uri != null && handledExternalUri.compareAndSet(false,true)) {
- CropImage.activity(uri).setOutputCompressFormat(Bitmap.CompressFormat.PNG)
- .setAspectRatio(1, 1)
- .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE)
- .start(this);
+ cropUri(this, uri);
return;
}
@@ -194,6 +208,13 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
configureActionBar(getSupportActionBar(), !this.mInitialAccountSetup && !handledExternalUri.get());
}
+ public static void cropUri(final Activity activity, final Uri uri) {
+ CropImage.activity(uri).setOutputCompressFormat(Bitmap.CompressFormat.PNG)
+ .setAspectRatio(1, 1)
+ .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE)
+ .start(activity);
+ }
+
protected void loadImageIntoPreview(Uri uri) {
Bitmap bm = null;
diff --git a/src/main/java/eu/siacs/conversations/utils/Resolver.java b/src/main/java/eu/siacs/conversations/utils/Resolver.java
index fe117fb55..e781e66d6 100644
--- a/src/main/java/eu/siacs/conversations/utils/Resolver.java
+++ b/src/main/java/eu/siacs/conversations/utils/Resolver.java
@@ -251,7 +251,7 @@ public class Resolver {
ResolverResult results = resolveWithFallback(hostname, type, authenticated);
for (D record : results.getAnswersOrEmptySet()) {
Result resolverResult = Result.fromRecord(srv, directTls);
- resolverResult.authenticated = results.isAuthenticData() && authenticated;
+ resolverResult.authenticated = results.isAuthenticData() && authenticated; //TODO technically it doesn’t matter if the IP was authenticated
resolverResult.ip = record.getInetAddress();
list.add(resolverResult);
}
@@ -442,7 +442,11 @@ public class Resolver {
public String toString() {
return "Result{" +
"ip='" + (ip == null ? null : ip.getHostAddress()) + '\'' +
+<<<<<<< HEAD
", hostname='" + (hostname == null ? null : hostname.toString()) + '\'' +
+=======
+ ", hostame='" + (hostname == null ? null : hostname.toString()) + '\'' +
+>>>>>>> 2.7.1
", port=" + port +
", directTls=" + directTls +
", authenticated=" + authenticated +
diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml
index edbe10a9b..b7d629de3 100644
--- a/src/main/res/values-hu/strings.xml
+++ b/src/main/res/values-hu/strings.xml
@@ -292,6 +292,7 @@
A csoportos csevegés le lett állítva
Többé már nincs ebben a csoportos csevegésben
használt fiók: %s
+ kiszolgálva itt: %s
%s ellenőrzése a HTTP gépen
Nincs kapcsolódva. Próbálja meg később újra
%s méretének ellenőrzése
@@ -556,6 +557,7 @@
Adatvédelem
Téma
Színpaletta kiválasztása
+ Automatikus
Világos téma
Sötét téma
Nem sikerült kapcsolódni a OpenKeychain alkalmazáshoz
diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml
index 5b0b549c3..5c276ef16 100644
--- a/src/main/res/values-it/strings.xml
+++ b/src/main/res/values-it/strings.xml
@@ -292,6 +292,7 @@
La chat di gruppo è stata chiusa
Non sei più in questa chat di gruppo
usando l’account %s
+ ospitato su %s
Controllo %s su host HTTP
Non sei connesso. Riprova più tardi
Controlla dimensione %s
diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml
index 8c1e45e05..746e8022e 100644
--- a/src/main/res/values-pl/strings.xml
+++ b/src/main/res/values-pl/strings.xml
@@ -292,6 +292,7 @@
Konferencja została zamknięta
Nie uczestniczysz już w tej konferencji
używając konta %s
+ udostępnione na %s
Sprawdzanie %s na hoście HTTP
Brak połączenia. Spróbuj ponownie później
Sprawdź rozmiar %s
diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml
index bb842740f..f43629a83 100644
--- a/src/main/res/values-sv/strings.xml
+++ b/src/main/res/values-sv/strings.xml
@@ -151,6 +151,7 @@
Användarnamn används redan
Registrering klar
Servern stödjer inte registrering
+ TLS-förhandling misslyckades
Kränkning av policy
Inkompatibel server
Strömningsfel
@@ -322,6 +323,7 @@
Regenerera OMEMO-nyckel
Rensa enheter
Är du säker på att du vill rensa alla andra enheter från OMEMO-annonsering? Nästa gång dina enheter ansluter kommer de att återannonsera sig, men de kanske inte tar emot enheter under tiden.
+ Något gick fel
Hämtar historik från server
Ingen mer historik på server
Uppdaterar…
@@ -350,6 +352,7 @@
Du deltar ej
Aldrig
Tills vidare
+ Läsmarkera
Input
Skicka med enter
Använd enter-knappen för att skicka meddelande
@@ -493,6 +496,7 @@
Privatliv
Tema
Välj färgschema
+ Automatisk
Ljust tema
Mörkt tema
Kan inte ansluta till OpenKeychain
@@ -543,6 +547,8 @@
Jag följde denna länk från en trovärdig källa
Du håller på att verifiera OMEMO-nyckeln för %1$s efter att du följt en länk. Detta är endast säkert om du följde länken från en trovärdig källa där endast %2$s kan ha publiserat denna länk.
Verifiera OMEMO-nycklar
+ Visa inaktiva
+ Dölj inaktiva
Lita ej på enhet
Är du säker på att du vill ta bort verifieringen av denna enhet?\nDenna enhet och meddelanden som kommer från enheten kommer att markeras som ej pålitliga.
@@ -586,27 +592,74 @@
Sessionsfel
Idag
Igår
+ Bekräfta värdnamn med DNSSEC
Certifikatet innehåller ej en XMPP-adress
Spela in video
Meddelande
Godkänn okänt certifikat?
+ Servercertifikatet är inte signerat av en känd certifikatutfärdare.
+ Vill du ansluta ändå?
+ Certifikatdetaljer:
Utkast:
+ Skapa genväg
+ Liten
+ Mellan
+ Stor
+ Kopiera plats
+ Dela plats
Dela plats
Visa plats
Dela
+ Var god dröj...
+ Conversations behöver tillgång till mikrofonen
+ GIF
Kopiera XMPP-adress
+ Smeknamn
+ Namn
+ Att ange ett namn är valfritt
Gruppchattens namn
+ Kan inte spara inspelning
Deltagare
+ Mellan (360p)
+ Hög (720p)
Välj ett land
telefonnummer
Bekräfta ditt telefonnummer
+ Ja
+ Nej
+ Bekräftar...
+ Okänt nätverksfel.
+ För många försök
+ Du använder en föråldrad version av denna app.
+ Ditt namn
+ Skriv in ditt namn
+ Avslå begäran
+ Installera Orbot
+ Starta Orbot
+ e-bok
+ Öppna med...
+ Välj konto
Skapa gruppchatt
Skapa sluten gruppchatt
Kanalnamn
+ XMPP-adress
Vänligen ange ett namn på kanalen
+ Ange en XMPP-adress
+ Detta är en XMPP-adress. Ange ett namn.
Denna kanal finns redan
Du har gått med i en befintlig kanal
+ XMPP-adresser är synliga för administratörer.
+ XMPP-adresser är synliga för alla.
Denna slutna gruppchatt har inga deltagare.
+ Hantera rättigheter
+ För stor fil
+ Bifoga
Upptäck kanaler
+ Jag har redan ett konto
+ Lägg till befintligt konto
+ Skapa nytt konto
+ Detta verkar vara ett domännamn
+ Lägg till ändå
Detta ser ut som en kanaladress
+ Om
diff --git a/src/quicksy/res/values-gl/strings.xml b/src/quicksy/res/values-gl/strings.xml
index b1675f6e0..9641086fe 100644
--- a/src/quicksy/res/values-gl/strings.xml
+++ b/src/quicksy/res/values-gl/strings.xml
@@ -1,26 +1,26 @@
Quicksy fallou
- Ao enviar lotes de rexistro está a axudar no desenvolvemento de Quicksy\nAviso: vai utilizar a súa conta XMPP para enviar o rexistro ao equipo de desenvolvemento.
- Quicksy utiliza unha app de terceiros chamada OpenKeychain para cifrar e descifrar as mensaxes e xestionar a súas chaves públicas.\n\nOpenKeychain en licenza GPLv3 e está dispoñible en F-Droid e Google Play.\n\n(Por favor, reinicie Quicksy ao rematar).
- Quicksy non pode cifrar as súas mensaxes porque os seu contacto non publicou as sua chave pública.\n\nPor favor, solicite ao contacto configure OpenPGP.
- Quicksy non pode cifrar as súas mensaxes porque os seus contactos non están a publicar a súa chave pública.\n\nPor favor, pídalle aos seus contactos que configuren OpenPGP.
+ Ao enviar lotes de rexistro estás a axudar no desenvolvemento de Quicksy\nAviso: vas utilizar a tua conta XMPP para enviar o rexistro ao equipo de desenvolvemento.
+ Quicksy utiliza unha app de terceiros chamada OpenKeychain para cifrar e descifrar as mensaxes e xestionar a tuas chaves públicas.\n\nOpenKeychain ten licenza GPLv3 e está dispoñible en F-Droid e Google Play.\n\n(Por favor, reinicia Quicksy ao rematar).
+ Quicksy non pode cifrar as tuas mensaxes porque o teu contacto non publicou as sua chave pública.\n\nPor favor, solicita ao contacto que configure OpenPGP.
+ Quicksy non pode cifrar as tuas mensaxes porque os teus contactos non están a publicar a súa chave pública.\n\nPor favor, pídelle aos teus contactos que configuren OpenPGP.
O período de tempo que Quicksy permanece acalado tras ver actividade en outro dispositivo
- Enviando trazas de rexistro está axudando ao desenvolvemento de Quicksy
+ Enviando trazas de rexistro estás axudando ao desenvolvemento de Quicksy
Quicksy precisa acceso ao almacenamento externo
Quicksy precisa acceso a cámara
- O seu dispositivo está a realizar optimizacións de batería intensivas con Quicksy que poderían levar a que as notificacións tarden en chegar ou que as mensaxes se perdan.\nRecomendamos desactivalas.
- O seu dispositivo está a realizar optimizacións de batería moi fortes con Quicksy que poderían levar a que se retrasen as notificacións ou que se perdan mensaxes.\n\nPediráselle que as desactive.
- Permitir a todos os seus contactos saber cando está a utilizar Quicksy
- O seu sistema operativo está restrinxindo o acceso a internet en segundo plano para Quicksy. Para recibir notificacións ou novas mensaxes debería permitir a Quicksy acceso non limitado cando se activa o aforro de datos.\nQuicksy esforzarase en aforrar datos cando sexa posible.
- O seu dispositivo non soporta a desactivación do aforro de datos para Quicksy.
- Para seguir recibindo notificacións, mesmo coa pantalla apagada, precisa engadir a Quicksy na lista de apps protexidas.
- Quicksy non pode enviar mensaxes cifradas a %1$s. Esto podería deberse a que o seu contacto utiliza un servidor antigo ou un cliente sen soporte OMEMO.
+ O teu dispositivo está a realizar optimizacións de batería intensivas con Quicksy que poderían levar a que as notificacións tarden en chegar ou que as mensaxes se perdan.\nRecomendamos desactivalas.
+ O teu dispositivo está a realizar optimizacións de batería moi fortes con Quicksy que poderían levar a que se retrasen as notificacións ou que se perdan mensaxes.\n\nVaiche solicitar que as desactives.
+ Permitir a todos os teus contactos saber cando estás a utilizar Quicksy
+ O teu sistema operativo está restrinxindo o acceso a internet en segundo plano para Quicksy. Para recibir notificacións ou novas mensaxes deberías permitir a Quicksy acceso non limitado cando se activa o aforro de datos.\nQuicksy esforzarase en aforrar datos cando sexa posible.
+ O teu dispositivo non soporta a desactivación do aforro de datos para Quicksy.
+ Para seguir recibindo notificacións, mesmo coa pantalla apagada, precisas engadir a Quicksy na lista de apps protexidas.
+ Quicksy non pode enviar mensaxes cifradas a %1$s. Esto podería deberse a que o teu contacto utiliza un servidor antigo ou un cliente sen soporte OMEMO.
Quicksy precisa acceder ao micrófono
Esta categoría de notificacións utilízase para mostrar unha notificación permanente que indica que Quicksy está funcionando.
Imaxe de perfil Quicksy
- Quicksy non está dispoñible no seu país.
- Non se puido validar a identidade do servidor.
+ Quicksy non está dispoñible no teu país.
+ Non se puido verificar a identidade do servidor.
Fallo de seguridade descoñecido.
Caducou a conexión mentras conectaba co servidor.