Java tutorial
package org.linphone; /* ChatFragment.java Copyright (C) 2015 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import android.graphics.Matrix; import java.util.ArrayList; import java.util.List; import org.linphone.compatibility.Compatibility; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneBuffer; import org.linphone.core.LinphoneChatMessage; import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneContent; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneChatMessage.State; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListenerBase; import org.linphone.mediastream.Log; import org.linphone.ui.AvatarWithShadow; import org.linphone.ui.BubbleChat; import android.media.ExifInterface; import android.support.v4.content.CursorLoader; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Rect; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.os.Parcelable; import android.provider.MediaStore; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.BaseAdapter; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.LinphoneChatMessageListener { private static ChatFragment instance; private static final int ADD_PHOTO = 1337; private static final int MENU_DELETE_MESSAGE = 0; private static final int MENU_PICTURE_SMALL = 2; private static final int MENU_PICTURE_MEDIUM = 3; private static final int MENU_PICTURE_LARGE = 4; private static final int MENU_PICTURE_REAL = 5; private static final int MENU_COPY_TEXT = 6; private static final int MENU_RESEND_MESSAGE = 7; private static final int SIZE_SMALL = 500; private static final int SIZE_MEDIUM = 1000; private static final int SIZE_LARGE = 1500; private static final int SIZE_MAX = 2048; private LinphoneChatRoom chatRoom; private String sipUri; private String displayName; private String pictureUri; private EditText message; private ImageView cancelUpload; private LinearLayout topBar; private TextView sendImage, sendMessage, contactName, remoteComposing, back; private AvatarWithShadow contactPicture; private RelativeLayout uploadLayout, textLayout; private ListView messagesList; private ProgressBar progressBar; private Uri imageToUploadUri; private String filePathToUpload; private TextWatcher textWatcher; private ViewTreeObserver.OnGlobalLayoutListener keyboardListener; private ChatMessageAdapter adapter; private LinphoneCoreListenerBase mListener; private ByteArrayInputStream mUploadingImageStream; private LinphoneChatMessage currentMessageInFileTransferUploadState; public static boolean isInstanciated() { return instance != null; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreate(savedInstanceState); instance = this; View view = inflater.inflate(R.layout.chat, container, false); LinphoneManager.addListener(this); // Retain the fragment across configuration changes setRetainInstance(true); //Retrieve parameter from intent sipUri = getArguments().getString("SipUri"); displayName = getArguments().getString("DisplayName"); pictureUri = getArguments().getString("PictureUri"); //Initialize UI contactName = (TextView) view.findViewById(R.id.contactName); contactPicture = (AvatarWithShadow) view.findViewById(R.id.contactPicture); messagesList = (ListView) view.findViewById(R.id.chatMessageList); textLayout = (RelativeLayout) view.findViewById(R.id.messageLayout); progressBar = (ProgressBar) view.findViewById(R.id.progressbar); topBar = (LinearLayout) view.findViewById(R.id.topbar); sendMessage = (TextView) view.findViewById(R.id.sendMessage); sendMessage.setOnClickListener(this); remoteComposing = (TextView) view.findViewById(R.id.remoteComposing); remoteComposing.setVisibility(View.GONE); uploadLayout = (RelativeLayout) view.findViewById(R.id.uploadLayout); uploadLayout.setVisibility(View.GONE); displayChatHeader(displayName, pictureUri); //Manage multiline message = (EditText) view.findViewById(R.id.message); if (!getResources().getBoolean(R.bool.allow_chat_multiline)) { message.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE); message.setMaxLines(1); } sendImage = (TextView) view.findViewById(R.id.sendPicture); if (!getResources().getBoolean(R.bool.disable_chat_send_file)) { sendImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pickImage(); } }); //registerForContextMenu(sendImage); } else { sendImage.setEnabled(false); } back = (TextView) view.findViewById(R.id.back); if (back != null) { back.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getActivity().finish(); } }); } cancelUpload = (ImageView) view.findViewById(R.id.cancelUpload); cancelUpload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (currentMessageInFileTransferUploadState != null) { uploadLayout.setVisibility(View.GONE); textLayout.setVisibility(View.VISIBLE); progressBar.setProgress(0); currentMessageInFileTransferUploadState.cancelFileTransfer(); currentMessageInFileTransferUploadState = null; LinphoneManager.getInstance().setUploadPendingFileMessage(null); } } }); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (lc != null) { chatRoom = lc.getOrCreateChatRoom(sipUri); //Only works if using liblinphone storage chatRoom.markAsRead(); } mListener = new LinphoneCoreListenerBase() { @Override public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message) { LinphoneAddress from = cr.getPeerAddress(); if (from.asStringUriOnly().equals(sipUri)) { invalidate(); messagesList.setSelection(adapter.getCount() - 1); } } @Override public void isComposingReceived(LinphoneCore lc, LinphoneChatRoom room) { if (chatRoom != null && room != null && chatRoom.getPeerAddress().asStringUriOnly() .equals(room.getPeerAddress().asStringUriOnly())) { remoteComposing.setVisibility(chatRoom.isRemoteComposing() ? View.VISIBLE : View.GONE); } } }; textWatcher = new TextWatcher() { public void afterTextChanged(Editable arg0) { } public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { if (message.getText().toString().equals("")) { sendMessage.setEnabled(false); } else { if (chatRoom != null) chatRoom.compose(); sendMessage.setEnabled(true); } } }; // Force hide keyboard getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); return view; } public static ChatFragment instance() { return instance; } @Override public void onSaveInstanceState(Bundle outState) { outState.putString("messageDraft", message.getText().toString()); super.onSaveInstanceState(outState); } private void addVirtualKeyboardVisiblityListener() { keyboardListener = new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect visibleArea = new Rect(); getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleArea); int heightDiff = getActivity().getWindow().getDecorView().getRootView().getHeight() - (visibleArea.bottom - visibleArea.top); if (heightDiff > 200) { showKeyboardVisibleMode(); } else { hideKeyboardVisibleMode(); } } }; getActivity().getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(keyboardListener); } private void removeVirtualKeyboardVisiblityListener() { Compatibility.removeGlobalLayoutListener(getActivity().getWindow().getDecorView().getViewTreeObserver(), keyboardListener); } public void showKeyboardVisibleMode() { boolean isOrientationLandscape = getResources() .getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; if (isOrientationLandscape && topBar != null) { topBar.setVisibility(View.GONE); } contactPicture.setVisibility(View.GONE); } public void hideKeyboardVisibleMode() { boolean isOrientationLandscape = getResources() .getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; contactPicture.setVisibility(View.VISIBLE); if (isOrientationLandscape && topBar != null) { topBar.setVisibility(View.VISIBLE); } } class ChatMessageAdapter extends BaseAdapter { LinphoneChatMessage[] history; Context context; public ChatMessageAdapter(Context context, LinphoneChatMessage[] history) { this.history = history; this.context = context; } public void refreshHistory() { this.history = chatRoom.getHistory(); } @Override public int getCount() { return history.length; } @Override public LinphoneChatMessage getItem(int position) { return history[position]; } @Override public long getItemId(int position) { return history[position].getStorageId(); } @Override public View getView(int position, View convertView, ViewGroup parent) { LinphoneChatMessage message = history[position]; BubbleChat bubble = new BubbleChat(context, message); View v = bubble.getView(); registerForContextMenu(v); RelativeLayout rlayout = new RelativeLayout(context); if (message.isOutgoing()) { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); layoutParams.setMargins(100, 10, 10, 10); v.setLayoutParams(layoutParams); } else { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); layoutParams.setMargins(10, 10, 100, 10); v.setLayoutParams(layoutParams); } rlayout.addView(v); return rlayout; } } public void dispayMessageList() { adapter = new ChatMessageAdapter(getActivity(), chatRoom.getHistory()); messagesList.setAdapter(adapter); adapter.notifyDataSetChanged(); } private void displayChatHeader(String displayName, String pictureUri) { LinphoneAddress lAddress; try { lAddress = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri); Contact contact = ContactsManager.getInstance() .findContactWithAddress(getActivity().getContentResolver(), lAddress); if (contact != null) { LinphoneUtils.setImagePictureFromUri(getActivity(), contactPicture.getView(), contact.getPhotoUri(), contact.getThumbnailUri(), R.drawable.unknown_small); } else { contactPicture.setImageResource(R.drawable.unknown_small); } } catch (LinphoneCoreException e) { e.printStackTrace(); } if (displayName == null && getResources().getBoolean(R.bool.only_display_username_if_unknown) && LinphoneUtils.isSipAddress(sipUri)) { contactName.setText(LinphoneUtils.getUsernameFromAddress(sipUri)); } else if (displayName == null) { contactName.setText(sipUri); } else { contactName.setText(displayName); } } public void changeDisplayedChat(String newSipUri, String displayName, String pictureUri) { this.sipUri = newSipUri; this.displayName = displayName; this.pictureUri = pictureUri; if (!message.getText().toString().equals("") && LinphoneActivity.isInstanciated()) { ChatStorage chatStorage = LinphoneActivity.instance().getChatStorage(); if (chatStorage.getDraft(sipUri) == null) { chatStorage.saveDraft(sipUri, message.getText().toString()); } else { chatStorage.updateDraft(sipUri, message.getText().toString()); } } else if (LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().getChatStorage().deleteDraft(sipUri); } if (LinphoneActivity.isInstanciated()) { String draft = LinphoneActivity.instance().getChatStorage().getDraft(sipUri); if (draft == null) draft = ""; message.setText(draft); } LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (lc != null) { chatRoom = lc.getOrCreateChatRoom(sipUri); //Only works if using liblinphone storage chatRoom.markAsRead(); } displayChatHeader(displayName, pictureUri); dispayMessageList(); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { if (v.getId() == R.id.sendPicture) { menu.add(0, MENU_PICTURE_SMALL, 0, getString(R.string.share_picture_size_small)); menu.add(0, MENU_PICTURE_MEDIUM, 0, getString(R.string.share_picture_size_medium)); menu.add(0, MENU_PICTURE_LARGE, 0, getString(R.string.share_picture_size_large)); // Not a good idea, very big pictures cause Out of Memory exceptions, slow display, ... // menu.add(0, MENU_PICTURE_REAL, 0, getString(R.string.share_picture_size_real)); } else { menu.add(v.getId(), MENU_DELETE_MESSAGE, 0, getString(R.string.delete)); menu.add(v.getId(), MENU_COPY_TEXT, 0, getString(R.string.copy_text)); } LinphoneChatMessage msg = getMessageForId(v.getId()); if (msg != null && msg.getStatus() == LinphoneChatMessage.State.NotDelivered) { menu.add(v.getId(), MENU_RESEND_MESSAGE, 0, getString(R.string.retry)); } } @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_DELETE_MESSAGE: if (chatRoom != null) { LinphoneChatMessage message = getMessageForId(item.getGroupId()); if (message != null) { chatRoom.deleteMessage(message); invalidate(); } } break; case MENU_COPY_TEXT: copyTextMessageToClipboard(item.getGroupId()); break; case MENU_RESEND_MESSAGE: resendMessage(item.getGroupId()); break; case MENU_PICTURE_SMALL: sendImageMessage(filePathToUpload, SIZE_SMALL); break; case MENU_PICTURE_MEDIUM: sendImageMessage(filePathToUpload, SIZE_MEDIUM); break; case MENU_PICTURE_LARGE: sendImageMessage(filePathToUpload, SIZE_LARGE); break; case MENU_PICTURE_REAL: sendImageMessage(filePathToUpload, SIZE_MAX); break; } return true; } @Override public void onPause() { message.removeTextChangedListener(textWatcher); removeVirtualKeyboardVisiblityListener(); LinphoneService.instance().removeMessageNotification(); if (LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().updateChatFragment(null); } LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (lc != null) { lc.removeListener(mListener); } LinphoneManager.removeListener(this); onSaveInstanceState(getArguments()); uploadLayout.setVisibility(View.GONE); textLayout.setVisibility(View.VISIBLE); progressBar.setProgress(0); //Hide keybord InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(message.getWindowToken(), 0); super.onPause(); } @SuppressLint("UseSparseArrays") @Override public void onResume() { message.addTextChangedListener(textWatcher); addVirtualKeyboardVisiblityListener(); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (lc != null) { lc.addListener(mListener); } if (LinphoneActivity.isInstanciated()) { if (getResources().getBoolean(R.bool.show_statusbar_only_on_dialer)) { LinphoneActivity.instance().hideStatusBar(); } LinphoneActivity.instance().updateChatFragment(this); } LinphoneManager.addListener(this); final LinphoneChatMessage msg = LinphoneManager.getInstance().getMessageUploadPending(); if (msg != null && msg.getTo().asString().equals(sipUri)) { uploadLayout.setVisibility(View.VISIBLE); textLayout.setVisibility(View.GONE); if (msg.getFileTransferInformation() != null) { progressBar.setProgress(msg.getFileTransferInformation().getRealSize()); } cancelUpload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { uploadLayout.setVisibility(View.GONE); textLayout.setVisibility(View.VISIBLE); progressBar.setProgress(0); msg.cancelFileTransfer(); LinphoneManager.getInstance().setUploadPendingFileMessage(null); } }); } String draft = getArguments().getString("messageDraft"); message.setText(draft); remoteComposing.setVisibility(chatRoom.isRemoteComposing() ? View.VISIBLE : View.GONE); dispayMessageList(); super.onResume(); } @Override public void onClick(View v) { sendTextMessage(); } private void sendTextMessage() { sendTextMessage(message.getText().toString()); message.setText(""); } private void sendTextMessage(String messageToSend) { LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); boolean isNetworkReachable = lc == null ? false : lc.isNetworkReachable(); if (chatRoom != null && messageToSend != null && messageToSend.length() > 0 && isNetworkReachable) { LinphoneChatMessage message = chatRoom.createLinphoneChatMessage(messageToSend); chatRoom.sendChatMessage(message); if (LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().onMessageSent(sipUri, messageToSend); } message.setListener(LinphoneManager.getInstance()); invalidate(); Log.i("Sent message current status: " + message.getStatus()); } else if (!isNetworkReachable && LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().displayCustomToast(getString(R.string.error_network_unreachable), Toast.LENGTH_LONG); } } private void sendImageMessage(String path, int imageSize) { LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); boolean isNetworkReachable = lc == null ? false : lc.isNetworkReachable(); if (chatRoom != null && path != null && path.length() > 0 && isNetworkReachable) { try { Bitmap bm = BitmapFactory.decodeFile(path); if (bm != null) { FileUploadPrepareTask task = new FileUploadPrepareTask(getActivity(), path, imageSize); task.execute(bm); } else { Log.e("Error, bitmap factory can't read " + path); } } catch (RuntimeException e) { Log.e("Error, not enough memory to create the bitmap"); } } else if (!isNetworkReachable && LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().displayCustomToast(getString(R.string.error_network_unreachable), Toast.LENGTH_LONG); } } class FileUploadPrepareTask extends AsyncTask<Bitmap, Void, byte[]> { private String path; private int imageSize; private ProgressDialog progressDialog; public FileUploadPrepareTask(Context context, String fileToUploadPath, int size) { path = fileToUploadPath; imageSize = size; uploadLayout.setVisibility(View.VISIBLE); textLayout.setVisibility(View.GONE); progressDialog = new ProgressDialog(context); progressDialog.setIndeterminate(true); progressDialog.setMessage(getString(R.string.processing_image)); progressDialog.show(); } @Override protected byte[] doInBackground(Bitmap... params) { Bitmap bm = params[0]; if (bm.getWidth() >= bm.getHeight() && bm.getWidth() > SIZE_MAX) { bm = Bitmap.createScaledBitmap(bm, SIZE_MAX, (SIZE_MAX * bm.getHeight()) / bm.getWidth(), false); } else if (bm.getHeight() >= bm.getWidth() && bm.getHeight() > SIZE_MAX) { bm = Bitmap.createScaledBitmap(bm, (SIZE_MAX * bm.getWidth()) / bm.getHeight(), SIZE_MAX, false); } // Rotate the bitmap if possible/needed, using EXIF data try { if (path != null) { ExifInterface exif = new ExifInterface(path); int pictureOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); Matrix matrix = new Matrix(); if (pictureOrientation == 6) { matrix.postRotate(90); } else if (pictureOrientation == 3) { matrix.postRotate(180); } else if (pictureOrientation == 8) { matrix.postRotate(270); } bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } } catch (Exception e) { e.printStackTrace(); } ByteArrayOutputStream stream = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); return byteArray; } @Override protected void onPostExecute(byte[] result) { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } mUploadingImageStream = new ByteArrayInputStream(result); LinphoneContent content = LinphoneCoreFactory.instance().createLinphoneContent("image", "jpeg", result, null); String fileName = path.substring(path.lastIndexOf("/") + 1); content.setName(fileName); LinphoneChatMessage message = chatRoom.createFileTransferMessage(content); message.setListener(LinphoneManager.getInstance()); message.setAppData(path); LinphoneManager.getInstance().setUploadPendingFileMessage(message); LinphoneManager.getInstance().setUploadingImageStream(mUploadingImageStream); chatRoom.sendChatMessage(message); currentMessageInFileTransferUploadState = message; } } private LinphoneChatMessage getMessageForId(int id) { for (LinphoneChatMessage message : chatRoom.getHistory()) { if (message.getStorageId() == id) { return message; } } return null; } private void invalidate() { adapter.refreshHistory(); adapter.notifyDataSetChanged(); chatRoom.markAsRead(); } private void resendMessage(int id) { LinphoneChatMessage message = getMessageForId(id); if (message == null) return; chatRoom.deleteMessage(getMessageForId(id)); invalidate(); if (message.getText() != null && message.getText().length() > 0) { sendTextMessage(message.getText()); } else { sendImageMessage(message.getAppData(), 0); } } private void copyTextMessageToClipboard(int id) { String msg = LinphoneActivity.instance().getChatStorage().getTextMessageForId(chatRoom, id); if (msg != null) { Compatibility.copyTextToClipboard(getActivity(), msg); LinphoneActivity.instance().displayCustomToast(getString(R.string.text_copied_to_clipboard), Toast.LENGTH_SHORT); } } public String getSipUri() { return sipUri; } private void pickImage() { List<Intent> cameraIntents = new ArrayList<Intent>(); 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()))); imageToUploadUri = Uri.fromFile(file); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageToUploadUri); cameraIntents.add(captureIntent); Intent galleryIntent = new Intent(); galleryIntent.setType("image/*"); galleryIntent.setAction(Intent.ACTION_PICK); Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.image_picker_title)); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[] {})); startActivityForResult(chooserIntent, ADD_PHOTO); } public String getRealPathFromURI(Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; CursorLoader loader = new CursorLoader(getActivity(), contentUri, proj, null, null, null); Cursor cursor = loader.loadInBackground(); if (cursor != null && cursor.moveToFirst()) { int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); String result = cursor.getString(column_index); cursor.close(); return result; } return null; } private void showPopupMenuAskingImageSize(final String filePath) { filePathToUpload = filePath; try { sendImage.showContextMenu(); } catch (Exception e) { e.printStackTrace(); } ; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == ADD_PHOTO && resultCode == Activity.RESULT_OK) { String fileToUploadPath = null; if (data != null && data.getData() != null) { fileToUploadPath = getRealPathFromURI(data.getData()); } else if (imageToUploadUri != null) { fileToUploadPath = imageToUploadUri.getPath(); } if (fileToUploadPath != null) { //showPopupMenuAskingImageSize(fileToUploadPath); sendImageMessage(fileToUploadPath, 0); } } else { super.onActivityResult(requestCode, resultCode, data); } } @Override public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) { if (state == State.FileTransferDone || state == State.FileTransferError) { uploadLayout.setVisibility(View.GONE); textLayout.setVisibility(View.VISIBLE); progressBar.setProgress(0); currentMessageInFileTransferUploadState = null; } invalidate(); } @Override public void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer) { } @Override public void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill) { } @Override public void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total) { progressBar.setProgress(offset * 100 / total); } }