Merge tag '2.7.1' into develop
This commit is contained in:
commit
35b9745fc9
|
@ -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+
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
• Fix avatar selection on some Android 10 devices
|
||||
• Fix file transfer for larger files
|
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="pick_a_server">Escolla o seu provedor XMPP</string>
|
||||
<string name="pick_a_server">Escolle o teu provedor XMPP</string>
|
||||
<string name="use_chat.sum7.eu">Utilizar chat.sum7.eu</string>
|
||||
<string name="create_new_account">Crear nova conta</string>
|
||||
<string name="do_you_have_an_account">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.</string>
|
||||
<string name="server_select_text">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.</string>
|
||||
<string name="do_you_have_an_account">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.</string>
|
||||
<string name="server_select_text">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.</string>
|
||||
<string name="magic_create_text_on_x">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.</string>
|
||||
<string name="magic_create_text_fixed">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.</string>
|
||||
<string name="your_server_invitation">O convite do teu servidor</string>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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...");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String> 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(() -> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -251,7 +251,7 @@ public class Resolver {
|
|||
ResolverResult<D> 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);
|
||||
}
|
||||
|
|
|
@ -292,6 +292,7 @@
|
|||
<string name="conference_shutdown">A csoportos csevegés le lett állítva</string>
|
||||
<string name="conference_unknown_error">Többé már nincs ebben a csoportos csevegésben</string>
|
||||
<string name="using_account">használt fiók: %s</string>
|
||||
<string name="hosted_on">kiszolgálva itt: %s</string>
|
||||
<string name="checking_x"> %s ellenőrzése a HTTP gépen</string>
|
||||
<string name="not_connected_try_again">Nincs kapcsolódva. Próbálja meg később újra</string>
|
||||
<string name="check_x_filesize"> %s méretének ellenőrzése</string>
|
||||
|
@ -556,6 +557,7 @@
|
|||
<string name="pref_privacy">Adatvédelem</string>
|
||||
<string name="pref_theme_options">Téma</string>
|
||||
<string name="pref_theme_options_summary">Színpaletta kiválasztása</string>
|
||||
<string name="pref_theme_automatic">Automatikus</string>
|
||||
<string name="pref_theme_light">Világos téma</string>
|
||||
<string name="pref_theme_dark">Sötét téma</string>
|
||||
<string name="unable_to_connect_to_keychain">Nem sikerült kapcsolódni a OpenKeychain alkalmazáshoz</string>
|
||||
|
|
|
@ -292,6 +292,7 @@
|
|||
<string name="conference_shutdown">La chat di gruppo è stata chiusa</string>
|
||||
<string name="conference_unknown_error">Non sei più in questa chat di gruppo</string>
|
||||
<string name="using_account">usando l’account %s</string>
|
||||
<string name="hosted_on">ospitato su %s</string>
|
||||
<string name="checking_x">Controllo %s su host HTTP</string>
|
||||
<string name="not_connected_try_again">Non sei connesso. Riprova più tardi</string>
|
||||
<string name="check_x_filesize">Controlla dimensione %s</string>
|
||||
|
|
|
@ -292,6 +292,7 @@
|
|||
<string name="conference_shutdown">Konferencja została zamknięta</string>
|
||||
<string name="conference_unknown_error">Nie uczestniczysz już w tej konferencji</string>
|
||||
<string name="using_account">używając konta %s</string>
|
||||
<string name="hosted_on">udostępnione na %s</string>
|
||||
<string name="checking_x">Sprawdzanie %s na hoście HTTP</string>
|
||||
<string name="not_connected_try_again">Brak połączenia. Spróbuj ponownie później</string>
|
||||
<string name="check_x_filesize">Sprawdź rozmiar %s</string>
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
<string name="account_status_regis_conflict">Användarnamn används redan</string>
|
||||
<string name="account_status_regis_success">Registrering klar</string>
|
||||
<string name="account_status_regis_not_sup">Servern stödjer inte registrering</string>
|
||||
<string name="account_status_tls_error">TLS-förhandling misslyckades</string>
|
||||
<string name="account_status_policy_violation">Kränkning av policy</string>
|
||||
<string name="account_status_incompatible_server">Inkompatibel server</string>
|
||||
<string name="account_status_stream_error">Strömningsfel</string>
|
||||
|
@ -322,6 +323,7 @@
|
|||
<string name="regenerate_omemo_key">Regenerera OMEMO-nyckel</string>
|
||||
<string name="clear_other_devices">Rensa enheter</string>
|
||||
<string name="clear_other_devices_desc">Ä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.</string>
|
||||
<string name="error_trustkeys_title">Något gick fel</string>
|
||||
<string name="fetching_history_from_server">Hämtar historik från server</string>
|
||||
<string name="no_more_history_on_server">Ingen mer historik på server</string>
|
||||
<string name="updating">Uppdaterar…</string>
|
||||
|
@ -350,6 +352,7 @@
|
|||
<string name="you_are_not_participating">Du deltar ej</string>
|
||||
<string name="never">Aldrig</string>
|
||||
<string name="until_further_notice">Tills vidare</string>
|
||||
<string name="mark_as_read">Läsmarkera</string>
|
||||
<string name="pref_input_options">Input</string>
|
||||
<string name="pref_enter_is_send">Skicka med enter</string>
|
||||
<string name="pref_enter_is_send_summary">Använd enter-knappen för att skicka meddelande</string>
|
||||
|
@ -493,6 +496,7 @@
|
|||
<string name="pref_privacy">Privatliv</string>
|
||||
<string name="pref_theme_options">Tema</string>
|
||||
<string name="pref_theme_options_summary">Välj färgschema</string>
|
||||
<string name="pref_theme_automatic">Automatisk</string>
|
||||
<string name="pref_theme_light">Ljust tema</string>
|
||||
<string name="pref_theme_dark">Mörkt tema</string>
|
||||
<string name="unable_to_connect_to_keychain">Kan inte ansluta till OpenKeychain</string>
|
||||
|
@ -543,6 +547,8 @@
|
|||
<string name="i_followed_this_link_from_a_trusted_source">Jag följde denna länk från en trovärdig källa</string>
|
||||
<string name="verifying_omemo_keys_trusted_source">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.</string>
|
||||
<string name="verify_omemo_keys">Verifiera OMEMO-nycklar</string>
|
||||
<string name="show_inactive_devices">Visa inaktiva</string>
|
||||
<string name="hide_inactive_devices">Dölj inaktiva</string>
|
||||
<string name="distrust_omemo_key">Lita ej på enhet</string>
|
||||
<string name="distrust_omemo_key_text">Ä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.</string>
|
||||
<plurals name="seconds">
|
||||
|
@ -586,27 +592,74 @@
|
|||
<string name="session_failure">Sessionsfel</string>
|
||||
<string name="today">Idag</string>
|
||||
<string name="yesterday">Igår</string>
|
||||
<string name="pref_validate_hostname">Bekräfta värdnamn med DNSSEC</string>
|
||||
<string name="certificate_does_not_contain_jid">Certifikatet innehåller ej en XMPP-adress</string>
|
||||
<string name="attach_record_video">Spela in video</string>
|
||||
<string name="message">Meddelande</string>
|
||||
<string name="mtm_accept_cert">Godkänn okänt certifikat?</string>
|
||||
<string name="mtm_trust_anchor">Servercertifikatet är inte signerat av en känd certifikatutfärdare.</string>
|
||||
<string name="mtm_connect_anyway">Vill du ansluta ändå?</string>
|
||||
<string name="mtm_cert_details">Certifikatdetaljer:</string>
|
||||
<string name="draft">Utkast:</string>
|
||||
<string name="create_shortcut">Skapa genväg</string>
|
||||
<string name="small">Liten</string>
|
||||
<string name="medium">Mellan</string>
|
||||
<string name="large">Stor</string>
|
||||
<string name="action_copy_location">Kopiera plats</string>
|
||||
<string name="action_share_location">Dela plats</string>
|
||||
<string name="title_activity_share_location">Dela plats</string>
|
||||
<string name="title_activity_show_location">Visa plats</string>
|
||||
<string name="share">Dela</string>
|
||||
<string name="please_wait">Var god dröj...</string>
|
||||
<string name="no_microphone_permission">Conversations behöver tillgång till mikrofonen</string>
|
||||
<string name="gif">GIF</string>
|
||||
<string name="copy_jabber_id">Kopiera XMPP-adress</string>
|
||||
<string name="nickname">Smeknamn</string>
|
||||
<string name="group_chat_name">Namn</string>
|
||||
<string name="providing_a_name_is_optional">Att ange ett namn är valfritt</string>
|
||||
<string name="create_dialog_group_chat_name">Gruppchattens namn</string>
|
||||
<string name="unable_to_save_recording">Kan inte spara inspelning</string>
|
||||
<string name="group_chat_members">Deltagare</string>
|
||||
<string name="video_360p">Mellan (360p)</string>
|
||||
<string name="video_720p">Hög (720p)</string>
|
||||
<string name="choose_a_country">Välj ett land</string>
|
||||
<string name="phone_number">telefonnummer</string>
|
||||
<string name="verify_your_phone_number">Bekräfta ditt telefonnummer</string>
|
||||
<string name="yes">Ja</string>
|
||||
<string name="no">Nej</string>
|
||||
<string name="verifying">Bekräftar...</string>
|
||||
<string name="unknown_api_error_network">Okänt nätverksfel.</string>
|
||||
<string name="too_many_attempts">För många försök</string>
|
||||
<string name="the_app_is_out_of_date">Du använder en föråldrad version av denna app.</string>
|
||||
<string name="your_name">Ditt namn</string>
|
||||
<string name="enter_your_name">Skriv in ditt namn</string>
|
||||
<string name="reject_request">Avslå begäran</string>
|
||||
<string name="install_orbot">Installera Orbot</string>
|
||||
<string name="start_orbot">Starta Orbot</string>
|
||||
<string name="ebook">e-bok</string>
|
||||
<string name="open_with">Öppna med...</string>
|
||||
<string name="choose_account">Välj konto</string>
|
||||
<string name="create_group_chat">Skapa gruppchatt</string>
|
||||
<string name="create_private_group_chat">Skapa sluten gruppchatt</string>
|
||||
<string name="create_dialog_channel_name">Kanalnamn</string>
|
||||
<string name="xmpp_address">XMPP-adress</string>
|
||||
<string name="please_enter_name">Vänligen ange ett namn på kanalen</string>
|
||||
<string name="please_enter_xmpp_address">Ange en XMPP-adress</string>
|
||||
<string name="this_is_an_xmpp_address">Detta är en XMPP-adress. Ange ett namn.</string>
|
||||
<string name="channel_already_exists">Denna kanal finns redan</string>
|
||||
<string name="joined_an_existing_channel">Du har gått med i en befintlig kanal</string>
|
||||
<string name="jabber_ids_are_visible_to_admins">XMPP-adresser är synliga för administratörer.</string>
|
||||
<string name="jabber_ids_are_visible_to_anyone">XMPP-adresser är synliga för alla.</string>
|
||||
<string name="no_users_hint_group_chat">Denna slutna gruppchatt har inga deltagare.</string>
|
||||
<string name="manage_permission">Hantera rättigheter</string>
|
||||
<string name="file_too_large">För stor fil</string>
|
||||
<string name="attach">Bifoga</string>
|
||||
<string name="discover_channels">Upptäck kanaler</string>
|
||||
<string name="i_already_have_an_account">Jag har redan ett konto</string>
|
||||
<string name="add_existing_account">Lägg till befintligt konto</string>
|
||||
<string name="register_new_account">Skapa nytt konto</string>
|
||||
<string name="this_looks_like_a_domain">Detta verkar vara ett domännamn</string>
|
||||
<string name="add_anway">Lägg till ändå</string>
|
||||
<string name="this_looks_like_channel">Detta ser ut som en kanaladress</string>
|
||||
<string name="category_about">Om</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="crash_report_title">Quicksy fallou</string>
|
||||
<string name="crash_report_message">Ao enviar lotes de rexistro está a axudar no desenvolvemento de Quicksy\n<b>Aviso:</b> vai utilizar a súa conta XMPP para enviar o rexistro ao equipo de desenvolvemento.</string>
|
||||
<string name="openkeychain_required_long">Quicksy utiliza unha app de terceiros chamada <b>OpenKeychain</b> 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<small>(Por favor, reinicie Quicksy ao rematar).</small></string>
|
||||
<string name="contact_has_no_pgp_key">Quicksy non pode cifrar as súas mensaxes porque os seu contacto non publicou as sua chave pública.\n\n<small>Por favor, solicite ao contacto configure OpenPGP.</small></string>
|
||||
<string name="contacts_have_no_pgp_keys">Quicksy non pode cifrar as súas mensaxes porque os seus contactos non están a publicar a súa chave pública.\n\n<small>Por favor, pídalle aos seus contactos que configuren OpenPGP.</small></string>
|
||||
<string name="crash_report_message">Ao enviar lotes de rexistro estás a axudar no desenvolvemento de Quicksy\n<b>Aviso:</b> vas utilizar a tua conta XMPP para enviar o rexistro ao equipo de desenvolvemento.</string>
|
||||
<string name="openkeychain_required_long">Quicksy utiliza unha app de terceiros chamada <b>OpenKeychain</b> 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<small>(Por favor, reinicia Quicksy ao rematar).</small></string>
|
||||
<string name="contact_has_no_pgp_key">Quicksy non pode cifrar as tuas mensaxes porque o teu contacto non publicou as sua chave pública.\n\n<small>Por favor, solicita ao contacto que configure OpenPGP.</small></string>
|
||||
<string name="contacts_have_no_pgp_keys">Quicksy non pode cifrar as tuas mensaxes porque os teus contactos non están a publicar a súa chave pública.\n\n<small>Por favor, pídelle aos teus contactos que configuren OpenPGP.</small></string>
|
||||
<string name="pref_notification_grace_period_summary">O período de tempo que Quicksy permanece acalado tras ver actividade en outro dispositivo</string>
|
||||
<string name="pref_never_send_crash_summary">Enviando trazas de rexistro está axudando ao desenvolvemento de Quicksy</string>
|
||||
<string name="pref_never_send_crash_summary">Enviando trazas de rexistro estás axudando ao desenvolvemento de Quicksy</string>
|
||||
<string name="no_storage_permission">Quicksy precisa acceso ao almacenamento externo</string>
|
||||
<string name="no_camera_permission">Quicksy precisa acceso a cámara</string>
|
||||
<string name="battery_optimizations_enabled_explained">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.</string>
|
||||
<string name="battery_optimizations_enabled_dialog">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.</string>
|
||||
<string name="pref_broadcast_last_activity_summary">Permitir a todos os seus contactos saber cando está a utilizar Quicksy</string>
|
||||
<string name="data_saver_enabled_explained">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.</string>
|
||||
<string name="device_does_not_support_data_saver">O seu dispositivo non soporta a desactivación do aforro de datos para Quicksy.</string>
|
||||
<string name="huawei_protected_apps_summary">Para seguir recibindo notificacións, mesmo coa pantalla apagada, precisa engadir a Quicksy na lista de apps protexidas.</string>
|
||||
<string name="error_trustkey_general">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.</string>
|
||||
<string name="battery_optimizations_enabled_explained">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.</string>
|
||||
<string name="battery_optimizations_enabled_dialog">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.</string>
|
||||
<string name="pref_broadcast_last_activity_summary">Permitir a todos os teus contactos saber cando estás a utilizar Quicksy</string>
|
||||
<string name="data_saver_enabled_explained">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.</string>
|
||||
<string name="device_does_not_support_data_saver">O teu dispositivo non soporta a desactivación do aforro de datos para Quicksy.</string>
|
||||
<string name="huawei_protected_apps_summary">Para seguir recibindo notificacións, mesmo coa pantalla apagada, precisas engadir a Quicksy na lista de apps protexidas.</string>
|
||||
<string name="error_trustkey_general">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.</string>
|
||||
<string name="no_microphone_permission">Quicksy precisa acceder ao micrófono</string>
|
||||
<string name="foreground_service_channel_description">Esta categoría de notificacións utilízase para mostrar unha notificación permanente que indica que Quicksy está funcionando.</string>
|
||||
<string name="set_profile_picture">Imaxe de perfil Quicksy</string>
|
||||
<string name="not_available_in_your_country">Quicksy non está dispoñible no seu país.</string>
|
||||
<string name="unable_to_verify_server_identity">Non se puido validar a identidade do servidor.</string>
|
||||
<string name="not_available_in_your_country">Quicksy non está dispoñible no teu país.</string>
|
||||
<string name="unable_to_verify_server_identity">Non se puido verificar a identidade do servidor.</string>
|
||||
<string name="unknown_security_error">Fallo de seguridade descoñecido.</string>
|
||||
<string name="timeout_while_connecting_to_server">Caducou a conexión mentras conectaba co servidor.</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue