aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/pixart')
-rw-r--r--src/main/java/de/pixart/messenger/persistance/FileBackend.java3
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java6
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java90
-rw-r--r--src/main/java/de/pixart/messenger/ui/EditMessage.java36
-rw-r--r--src/main/java/de/pixart/messenger/utils/MimeUtils.java21
6 files changed, 131 insertions, 29 deletions
diff --git a/src/main/java/de/pixart/messenger/persistance/FileBackend.java b/src/main/java/de/pixart/messenger/persistance/FileBackend.java
index 893834ad7..88e53efd4 100644
--- a/src/main/java/de/pixart/messenger/persistance/FileBackend.java
+++ b/src/main/java/de/pixart/messenger/persistance/FileBackend.java
@@ -55,6 +55,7 @@ import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.ExifHelper;
import de.pixart.messenger.utils.FileUtils;
import de.pixart.messenger.utils.FileWriterException;
+import de.pixart.messenger.utils.MimeUtils;
import de.pixart.messenger.xmpp.pep.Avatar;
public class FileBackend {
@@ -288,7 +289,7 @@ public class FileBackend {
}
public void copyFileToPrivateStorage(Message message, Uri uri) throws FileCopyException {
- String mime = mXmppConnectionService.getContentResolver().getType(uri);
+ String mime = MimeUtils.guessMimeTypeFromUri(mXmppConnectionService, uri);
Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage (mime=" + mime + ")");
String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mime);
if (extension == null) {
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index a15640462..5a76d3f88 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -112,6 +112,7 @@ import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.ExceptionHelper;
import de.pixart.messenger.utils.FileUtils;
import de.pixart.messenger.utils.FileWriterException;
+import de.pixart.messenger.utils.MimeUtils;
import de.pixart.messenger.utils.OnPhoneContactsLoadedListener;
import de.pixart.messenger.utils.PRNGFixes;
import de.pixart.messenger.utils.PhoneHelper;
@@ -146,7 +147,6 @@ import de.pixart.messenger.xmpp.stanzas.PresencePacket;
import me.leolin.shortcutbadger.ShortcutBadger;
import static de.pixart.messenger.persistance.FileBackend.close;
-import static de.pixart.messenger.services.NotificationService.NOTIFICATION_ID;
public class XmppConnectionService extends Service {
@@ -513,9 +513,11 @@ public class XmppConnectionService extends Service {
callback.error(R.string.security_error_invalid_file_access, null);
return;
}
+ final String mimeType = MimeUtils.guessMimeTypeFromUri(this, uri);
final String compressPictures = getCompressPicturesPreference();
if ("never".equals(compressPictures)
- || ("auto".equals(compressPictures) && getFileBackend().useImageAsIs(uri))) {
+ || ("auto".equals(compressPictures) && getFileBackend().useImageAsIs(uri))
+ || (mimeType != null && mimeType.endsWith("/gif"))) {
Log.d(Config.LOGTAG, conversation.getAccount().getJid().toBareJid() + ": not compressing picture. sending as file");
attachFileToConversation(conversation, uri, callback);
return;
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
index 3fa34d6a4..4d9292b61 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
@@ -1946,6 +1946,10 @@ public class ConversationActivity extends XmppActivity
});
}
+ public void attachImageToConversation(Uri uri) {
+ this.attachImageToConversation(getSelectedConversation(), uri);
+ }
+
private void attachImageToConversation(Conversation conversation, Uri uri) {
if (conversation == null) {
return;
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
index 5363b3db6..ec0242131 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
@@ -11,6 +11,8 @@ import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.os.Handler;
+import android.support.v13.view.inputmethod.InputConnectionCompat;
+import android.support.v13.view.inputmethod.InputContentInfoCompat;
import android.text.Editable;
import android.text.InputType;
import android.util.Log;
@@ -287,6 +289,40 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
}
};
+
+ private EditMessage.OnCommitContentListener mEditorContentListener = new EditMessage.OnCommitContentListener() {
+
+ @Override
+ public boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts, String[] contentMimeTypes) {
+ // try to get permission to read the image, if applicable
+ if ((flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
+ try {
+ inputContentInfo.requestPermission();
+ } catch (Exception e) {
+ Log.e(Config.LOGTAG, "InputContentInfoCompat#requestPermission() failed.", e);
+ Toast.makeText(
+ activity,
+ activity.getString(R.string.no_permission_to_access_x, inputContentInfo.getDescription()),
+ Toast.LENGTH_LONG
+ ).show();
+ return false;
+ }
+ }
+
+ // send the image
+ activity.attachImageToConversation(inputContentInfo.getContentUri());
+
+ // TODO: revoke permissions?
+ // since uploading an image is async its tough to wire a callback to when
+ // the image has finished uploading.
+ // According to the docs: "calling IC#releasePermission() is just to be a
+ // good citizen. Even if we failed to call that method, the system would eventually revoke
+ // the permission sometime after inputContentInfo object gets garbage-collected."
+ // See: https://developer.android.com/samples/CommitContentSampleApp/src/com.example.android.commitcontent.app/MainActivity.html#l164
+ return true;
+ }
+ };
+
private OnClickListener mSendButtonListener = new OnClickListener() {
@Override
@@ -428,6 +464,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_conversation, container, false);
view.setOnClickListener(null);
+ String[] allImagesMimeType = {"image/*"};
mEditMessage = (EditMessage) view.findViewById(R.id.textinput);
mEditMessage.setOnClickListener(new OnClickListener() {
@@ -439,6 +476,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
});
mEditMessage.setOnEditorActionListener(mEditorActionListener);
+ mEditMessage.setRichContentListener(allImagesMimeType, mEditorContentListener);
mSendButton = (ImageButton) view.findViewById(R.id.textSendButton);
mSendButton.setOnClickListener(this.mSendButtonListener);
@@ -522,32 +560,32 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
});
messageListAdapter.setOnQuoteListener(new MessageAdapter.OnQuoteListener() {
- @Override
- public void onQuote(String text) {
- if (mEditMessage.isEnabled()) {
- text = text.replaceAll("(\n *){2,}", "\n").replaceAll("(^|\n)", "$1> ").replaceAll("\n$", "");
- Editable editable = mEditMessage.getEditableText();
- int position = mEditMessage.getSelectionEnd();
- if (position == -1) position = editable.length();
- if (position > 0 && editable.charAt(position - 1) != '\n') {
- editable.insert(position++, "\n");
- }
- editable.insert(position, text);
- position += text.length();
- editable.insert(position++, "\n");
- if (position < editable.length() && editable.charAt(position) != '\n') {
- editable.insert(position, "\n");
- }
- mEditMessage.setSelection(position);
- mEditMessage.requestFocus();
- InputMethodManager inputMethodManager = (InputMethodManager) getActivity()
- .getSystemService(Context.INPUT_METHOD_SERVICE);
- if (inputMethodManager != null) {
- inputMethodManager.showSoftInput(mEditMessage, InputMethodManager.SHOW_IMPLICIT);
- }
- }
- }
- });
+ @Override
+ public void onQuote(String text) {
+ if (mEditMessage.isEnabled()) {
+ text = text.replaceAll("(\n *){2,}", "\n").replaceAll("(^|\n)", "$1> ").replaceAll("\n$", "");
+ Editable editable = mEditMessage.getEditableText();
+ int position = mEditMessage.getSelectionEnd();
+ if (position == -1) position = editable.length();
+ if (position > 0 && editable.charAt(position - 1) != '\n') {
+ editable.insert(position++, "\n");
+ }
+ editable.insert(position, text);
+ position += text.length();
+ editable.insert(position++, "\n");
+ if (position < editable.length() && editable.charAt(position) != '\n') {
+ editable.insert(position, "\n");
+ }
+ mEditMessage.setSelection(position);
+ mEditMessage.requestFocus();
+ InputMethodManager inputMethodManager = (InputMethodManager) getActivity()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (inputMethodManager != null) {
+ inputMethodManager.showSoftInput(mEditMessage, InputMethodManager.SHOW_IMPLICIT);
+ }
+ }
+ }
+ });
messagesView.setAdapter(messageListAdapter);
registerForContextMenu(messagesView);
diff --git a/src/main/java/de/pixart/messenger/ui/EditMessage.java b/src/main/java/de/pixart/messenger/ui/EditMessage.java
index 8c0a7f934..fceed3408 100644
--- a/src/main/java/de/pixart/messenger/ui/EditMessage.java
+++ b/src/main/java/de/pixart/messenger/ui/EditMessage.java
@@ -2,18 +2,31 @@ package de.pixart.messenger.ui;
import android.content.Context;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
+import android.support.v13.view.inputmethod.EditorInfoCompat;
+import android.support.v13.view.inputmethod.InputConnectionCompat;
+import android.support.v13.view.inputmethod.InputContentInfoCompat;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.AttributeSet;
import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
import de.pixart.messenger.Config;
import github.ankushsachdeva.emojicon.EmojiconEditText;
public class EditMessage extends EmojiconEditText {
+ private OnCommitContentListener mCommitContentListener = null;
+ private String[] mimeTypes = null;
+
+ public interface OnCommitContentListener {
+ boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts, String[] mimeTypes);
+ }
+
public EditMessage(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -130,4 +143,27 @@ public class EditMessage extends EmojiconEditText {
return super.onTextContextMenuItem(id);
}
}
+
+ public void setRichContentListener(String[] mimeTypes, OnCommitContentListener listener) {
+ this.mimeTypes = mimeTypes;
+ this.mCommitContentListener = listener;
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
+ final InputConnection ic = super.onCreateInputConnection(editorInfo);
+
+ if (mimeTypes != null && mCommitContentListener != null) {
+ EditorInfoCompat.setContentMimeTypes(editorInfo, mimeTypes);
+ return InputConnectionCompat.createWrapper(ic, editorInfo, new InputConnectionCompat.OnCommitContentListener() {
+
+ @Override
+ public boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) {
+ return EditMessage.this.mCommitContentListener.onCommitContent(inputContentInfo, flags, opts, mimeTypes);
+ }
+ });
+ } else {
+ return ic;
+ }
+ }
}
diff --git a/src/main/java/de/pixart/messenger/utils/MimeUtils.java b/src/main/java/de/pixart/messenger/utils/MimeUtils.java
index 366ed308b..bdcd82bae 100644
--- a/src/main/java/de/pixart/messenger/utils/MimeUtils.java
+++ b/src/main/java/de/pixart/messenger/utils/MimeUtils.java
@@ -15,6 +15,9 @@
*/
package de.pixart.messenger.utils;
+import android.content.Context;
+import android.net.Uri;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -499,4 +502,22 @@ public final class MimeUtils {
}
return mimeTypeToExtensionMap.get(mimeType);
}
+
+ public static String guessMimeTypeFromUri(Context context, Uri uri) {
+ // try the content resolver
+ String mimeType = context.getContentResolver().getType(uri);
+ // try the extension
+ if (mimeType == null && uri.getPath() != null) {
+ String path = uri.getPath();
+ int start = path.lastIndexOf('.') + 1;
+ if (start < path.length()) {
+ mimeType = MimeUtils.guessMimeTypeFromExtension(path.substring(start));
+ }
+ }
+ // sometimes this works (as with the commit content api)
+ if (mimeType == null) {
+ mimeType = uri.getQueryParameter("mimeType");
+ }
+ return mimeType;
+ }
}