From 7be868b1475b4720ee2467fdd2bf60b95f9b90a9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 1 Nov 2017 17:46:08 +0100 Subject: [PATCH] Started file upload in group chat view + added fix when picking documents from some special Android places --- src/android/org/linphone/LinphoneUtils.java | 56 +++++++++++++++++-- .../org/linphone/chat/ChatEventsAdapter.java | 2 +- .../org/linphone/chat/GroupChatFragment.java | 44 ++++++++++++++- 3 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/android/org/linphone/LinphoneUtils.java b/src/android/org/linphone/LinphoneUtils.java index 3c0313b4f..2a86c83be 100644 --- a/src/android/org/linphone/LinphoneUtils.java +++ b/src/android/org/linphone/LinphoneUtils.java @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import android.app.Activity; import android.app.AlertDialog; import android.content.ContentResolver; +import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.CursorLoader; @@ -38,6 +39,7 @@ import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.os.ParcelFileDescriptor; +import android.provider.DocumentsContract; import android.provider.MediaStore; import android.provider.MediaStore.Images; import android.telephony.TelephonyManager; @@ -748,9 +750,53 @@ public final class LinphoneUtils { ************************************************************************************************/ public static String getFilePath(final Context context, final Uri uri) { - // Google photo uri example - // content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2FAF1QipMObgoK_wDY66gu0QkMAi/ORIGINAL/NONE/114919 - if ("content".equalsIgnoreCase(uri.getScheme())) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if ("com.android.externalstorage.documents".equals(uri.getAuthority())) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + + // TODO handle non-primary volumes + } + // DownloadsProvider + else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) { + + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } + // MediaProvider + else if ("com.android.providers.media.documents".equals(uri.getAuthority())) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[] { + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } else if ("content".equalsIgnoreCase(uri.getScheme())) { // Content + // Google photo uri example + // content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2FAF1QipMObgoK_wDY66gu0QkMAi/ORIGINAL/NONE/114919 String type = getTypeFromUri(uri, context); String result = getDataColumn(context, uri, null, null); // if (TextUtils.isEmpty(result)) @@ -766,9 +812,7 @@ public final class LinphoneUtils { } } return result; - } - // File - else if ("file".equalsIgnoreCase(uri.getScheme())) { + } else if ("file".equalsIgnoreCase(uri.getScheme())) { // File return uri.getPath(); } return null; diff --git a/src/android/org/linphone/chat/ChatEventsAdapter.java b/src/android/org/linphone/chat/ChatEventsAdapter.java index 194994627..7c030c858 100644 --- a/src/android/org/linphone/chat/ChatEventsAdapter.java +++ b/src/android/org/linphone/chat/ChatEventsAdapter.java @@ -289,7 +289,7 @@ public class ChatEventsAdapter extends BaseAdapter implements ChatMessageListene } else { holder.fileTransferLayout.setVisibility(View.VISIBLE); } - } else if (msg != null) { // Text message + } else if (msg != null) { // This is a else for now, the day we'll be able to send both file and text this won't be anymore text = LinphoneUtils.getTextWithHttpLinks(msg); holder.messageText.setText(text); holder.messageText.setMovementMethod(LinkMovementMethod.getInstance()); diff --git a/src/android/org/linphone/chat/GroupChatFragment.java b/src/android/org/linphone/chat/GroupChatFragment.java index 00bc77fba..8f5e8a5e0 100644 --- a/src/android/org/linphone/chat/GroupChatFragment.java +++ b/src/android/org/linphone/chat/GroupChatFragment.java @@ -64,9 +64,11 @@ import org.linphone.core.ChatRoomListener; import org.linphone.core.Content; import org.linphone.core.Core; import org.linphone.core.EventLog; +import org.linphone.core.Factory; import org.linphone.core.Friend; import org.linphone.core.FriendList; import org.linphone.core.Participant; +import org.linphone.mediastream.Log; import org.linphone.receivers.ContactsUpdatedListener; import java.io.File; @@ -208,7 +210,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con @Override public void onClick(View view) { LinphoneActivity.instance().checkAndRequestPermissionsToSendImage(); - pickImage(); + pickFile(); } }); @@ -295,6 +297,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con } else if (mImageToUploadUri != null) { fileToUploadPath = mImageToUploadUri.getPath(); } + if (LinphoneUtils.isExtensionImage(fileToUploadPath)) { addImageToPendingList(fileToUploadPath); } else { @@ -303,6 +306,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con } else if (fileToUploadPath.contains("com.android.contacts/contacts/")) { fileToUploadPath = getCVSPathFromLookupUri(fileToUploadPath).toString(); } + Log.e("FILE PATH IS " + fileToUploadPath); addFileToPendingList(fileToUploadPath); } } else { @@ -462,7 +466,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con mChatEventsList.setAdapter(mMessagesAdapter); } - private void pickImage() { + private void pickFile() { List cameraIntents = new ArrayList<>(); Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File file = new File(Environment.getExternalStorageDirectory(), getString(R.string.temp_photo_name_with_date).replace("%s", String.valueOf(System.currentTimeMillis())+".jpeg")); @@ -487,6 +491,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con private void addFileToPendingList(String path) { View pendingFile = mInflater.inflate(R.layout.file_upload_cell, mFilesUploadLayout, false); + pendingFile.setTag(path); TextView text = pendingFile.findViewById(R.id.pendingFileForUpload); String extension = path.substring(path.lastIndexOf('.')); @@ -499,14 +504,18 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con public void onClick(View view) { View pendingImage = (View)view.getTag(); mFilesUploadLayout.removeView(pendingImage); + mAttachImageButton.setEnabled(true); } }); mFilesUploadLayout.addView(pendingFile); + + mAttachImageButton.setEnabled(false); // For now limit file per message to 1 } private void addImageToPendingList(String path) { View pendingImage = mInflater.inflate(R.layout.image_upload_cell, mFilesUploadLayout, false); + pendingImage.setTag(path); ImageView image = pendingImage.findViewById(R.id.pendingImageForUpload); Bitmap bm = BitmapFactory.decodeFile(path); @@ -520,16 +529,44 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con public void onClick(View view) { View pendingImage = (View)view.getTag(); mFilesUploadLayout.removeView(pendingImage); + mAttachImageButton.setEnabled(true); } }); mFilesUploadLayout.addView(pendingImage); + + mAttachImageButton.setEnabled(false); // For now limit file per message to 1 } private void sendMessage() { String text = mMessageTextToSend.getText().toString(); - ChatMessage msg = mChatRoom.createMessage(text); + + ChatMessage msg; + // For now we have to either send the picture or the text but not both + if (mFilesUploadLayout.getChildCount() > 0) { + String filePath = (String) mFilesUploadLayout.getChildAt(0).getTag(); + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1); + String extension = LinphoneUtils.getExtensionFromFileName(fileName); + Content content = Factory.instance().createContent(); + if (LinphoneUtils.isExtensionImage(fileName)) { + content.setType("image"); + } else { + content.setType("file"); + } + content.setSubtype(extension); + content.setName(fileName); + msg = mChatRoom.createFileTransferMessage(content); + msg.setFileTransferFilepath(filePath); // Let the file body handler take care of the upload + } else { + msg = mChatRoom.createMessage(text); + } + msg.setListener(new ChatMessageListenerStub() { + @Override + public void onFileTransferProgressIndication(ChatMessage message, Content content, int offset, int total) { + + } + @Override public void onMsgStateChanged(ChatMessage message, ChatMessage.State state) { ChatBubbleViewHolder holder = (ChatBubbleViewHolder) message.getUserData(); @@ -556,6 +593,7 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con msg.send(); mFilesUploadLayout.removeAllViews(); + mAttachImageButton.setEnabled(true); mMessageTextToSend.setText(""); }