Improved camera taken pictures method + improved progress bar + new tablet images

This commit is contained in:
Sylvain Berfini 2012-09-18 14:46:20 +02:00
parent 087752cb6a
commit 167ba0d174
24 changed files with 117 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/chat_stop_upload_over" />
<item
android:drawable="@drawable/chat_stop_upload_default" />
</selector>

View file

@ -36,7 +36,7 @@
android:contentDescription="@string/content_description_mark" android:contentDescription="@string/content_description_mark"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.25" android:layout_weight="0.24"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:scaleType="fitEnd" android:scaleType="fitEnd"
android:src="@drawable/dialer" android:src="@drawable/dialer"
@ -132,8 +132,8 @@
android:id="@+id/dialer" android:id="@+id/dialer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="0.25" android:layout_weight="0.24"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:contentDescription="@string/content_description_dialer" android:contentDescription="@string/content_description_dialer"
android:scaleType="fitXY" android:scaleType="fitXY"
android:src="@drawable/dialer" /> android:src="@drawable/dialer" />

View file

@ -50,6 +50,7 @@
</ScrollView> </ScrollView>
<RelativeLayout <RelativeLayout
android:id="@+id/messageLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
@ -85,15 +86,34 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@id/sendPicture" android:layout_toRightOf="@id/sendPicture"
android:layout_toLeftOf="@id/sendMessage" android:layout_toLeftOf="@id/sendMessage"
android:background="@android:color/transparent"
android:padding="20dp"/> android:padding="20dp"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/uploadLayout"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/chat_progressbar_background">
<ImageView
android:contentDescription="@string/content_description_cancel"
android:id="@+id/cancelUpload"
android:src="@drawable/chat_stop_upload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_alignParentRight="true" />
<ProgressBar <ProgressBar
android:id="@+id/progressbar" android:id="@+id/progressbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="50dp" android:layout_height="15dp"
android:layout_toRightOf="@id/sendPicture" android:layout_toLeftOf="@id/cancelUpload"
android:layout_toLeftOf="@id/sendMessage" android:layout_centerVertical="true"
android:visibility="gone"
style="@android:style/Widget.ProgressBar.Horizontal" style="@android:style/Widget.ProgressBar.Horizontal"
android:paddingTop="2dp" /> android:paddingTop="2dp" />

View file

@ -21,7 +21,6 @@ import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -38,15 +37,11 @@ import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.State; import org.linphone.core.LinphoneChatMessage.State;
import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCore;
import org.linphone.core.Log;
import org.linphone.ui.AvatarWithShadow; import org.linphone.ui.AvatarWithShadow;
import org.linphone.ui.BubbleChat; import org.linphone.ui.BubbleChat;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat; import android.graphics.Bitmap.CompressFormat;
@ -78,7 +73,7 @@ import android.widget.Toast;
* @author Sylvain Berfini * @author Sylvain Berfini
*/ */
public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.StateListener { public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.StateListener {
private static final int ADD_PHOTO = 0; private static final int ADD_PHOTO = 1337;
private static final int MENU_DELETE_MESSAGE = 0; private static final int MENU_DELETE_MESSAGE = 0;
private static final int MENU_SAVE_PICTURE = 1; private static final int MENU_SAVE_PICTURE = 1;
private static final int MENU_PICTURE_SMALL = 2; private static final int MENU_PICTURE_SMALL = 2;
@ -94,18 +89,21 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private View view; private View view;
private String sipUri; private String sipUri;
private EditText message; private EditText message;
private ImageView sendImage; private ImageView sendImage, cancelUpload;
private TextView contactName; private TextView contactName;
private AvatarWithShadow contactPicture; private AvatarWithShadow contactPicture;
private RelativeLayout messagesLayout; private RelativeLayout messagesLayout, uploadLayout, textLayout;
private ScrollView messagesScrollView; private ScrollView messagesScrollView;
private int previousMessageID; private int previousMessageID;
private Handler mHandler = new Handler(); private Handler mHandler = new Handler();
private BubbleChat lastSentMessageBubble; private BubbleChat lastSentMessageBubble;
private ProgressBar progressBar; private ProgressBar progressBar;
private int bytesSent; private int bytesSent;
private String uploadServerUri; private String uploadServerUri;
private String fileToUploadPath; private String fileToUploadPath;
private Bitmap imageToUpload;
private Uri imageToUploadUri;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -123,6 +121,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
sendMessage.setOnClickListener(this); sendMessage.setOnClickListener(this);
message = (EditText) view.findViewById(R.id.message); message = (EditText) view.findViewById(R.id.message);
uploadLayout = (RelativeLayout) view.findViewById(R.id.uploadLayout);
textLayout = (RelativeLayout) view.findViewById(R.id.messageLayout);
messagesLayout = (RelativeLayout) view.findViewById(R.id.messages); messagesLayout = (RelativeLayout) view.findViewById(R.id.messages);
messagesScrollView = (ScrollView) view.findViewById(R.id.chatScrollView); messagesScrollView = (ScrollView) view.findViewById(R.id.chatScrollView);
progressBar = (ProgressBar) view.findViewById(R.id.progressbar); progressBar = (ProgressBar) view.findViewById(R.id.progressbar);
@ -136,6 +137,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
} }
}); });
cancelUpload = (ImageView) view.findViewById(R.id.cancelUpload);
cancelUpload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//TODO
}
});
displayChat(displayName, pictureUri); displayChat(displayName, pictureUri);
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
@ -228,13 +237,12 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId() == R.id.sendPicture) { 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_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_MEDIUM, 0, getString(R.string.share_picture_size_medium));
menu.add(0, MENU_PICTURE_LARGE, 0, getString(R.string.share_picture_size_large)); menu.add(0, MENU_PICTURE_LARGE, 0, getString(R.string.share_picture_size_large));
menu.add(0, MENU_PICTURE_REAL, 0, getString(R.string.share_picture_size_real)); // 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 { } else {
menu.add(v.getId(), MENU_DELETE_MESSAGE, 0, getString(R.string.delete)); menu.add(v.getId(), MENU_DELETE_MESSAGE, 0, getString(R.string.delete));
ImageView iv = (ImageView) v.findViewById(R.id.image); ImageView iv = (ImageView) v.findViewById(R.id.image);
@ -255,16 +263,16 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
saveImage(item.getGroupId()); saveImage(item.getGroupId());
break; break;
case MENU_PICTURE_SMALL: case MENU_PICTURE_SMALL:
uploadAndSendImage(fileToUploadPath, ImageSize.SMALL); uploadAndSendImage(fileToUploadPath, imageToUpload, ImageSize.SMALL);
break; break;
case MENU_PICTURE_MEDIUM: case MENU_PICTURE_MEDIUM:
uploadAndSendImage(fileToUploadPath, ImageSize.MEDIUM); uploadAndSendImage(fileToUploadPath, imageToUpload, ImageSize.MEDIUM);
break; break;
case MENU_PICTURE_LARGE: case MENU_PICTURE_LARGE:
uploadAndSendImage(fileToUploadPath, ImageSize.LARGE); uploadAndSendImage(fileToUploadPath, imageToUpload, ImageSize.LARGE);
break; break;
case MENU_PICTURE_REAL: case MENU_PICTURE_REAL:
uploadAndSendImage(fileToUploadPath, ImageSize.REAL); uploadAndSendImage(fileToUploadPath, imageToUpload, ImageSize.REAL);
break; break;
} }
return true; return true;
@ -273,6 +281,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (LinphoneActivity.isInstanciated()) { if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().selectMenu(FragmentsAvailable.CHAT); LinphoneActivity.instance().selectMenu(FragmentsAvailable.CHAT);
LinphoneActivity.instance().updateChatFragment(this); LinphoneActivity.instance().updateChatFragment(this);
@ -368,16 +377,11 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private void pickImage() { private void pickImage() {
final List<Intent> cameraIntents = new ArrayList<Intent>(); final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getActivity().getPackageManager(); File file = new File(Environment.getExternalStorageDirectory(), "linphone-android-photo-temp.jpg");
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0); imageToUploadUri = Uri.fromFile(file);
for(ResolveInfo res : listCam) { captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageToUploadUri);
final String packageName = res.activityInfo.packageName; cameraIntents.add(captureIntent);
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
cameraIntents.add(intent);
}
final Intent galleryIntent = new Intent(); final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*"); galleryIntent.setType("image/*");
@ -437,10 +441,12 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
} }
private String uploadImage(String filePath, Bitmap file, int compressorQuality, final int imageSize) { private String uploadImage(String filePath, Bitmap file, int compressorQuality, final int imageSize) {
File sourceFile = new File(filePath); String fileName;
if (!sourceFile.isFile()) { if (filePath != null) {
Log.e("Can't read source file " + filePath + ", upload failed"); File sourceFile = new File(filePath);
return null; fileName = sourceFile.getName();
} else {
fileName = "linphone-android-photo-" + System.currentTimeMillis() + ".jpg";
} }
String response = null; String response = null;
@ -450,7 +456,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
String twoHyphens = "--"; String twoHyphens = "--";
String boundary = "---------------------------14737809831466499882746641449"; String boundary = "---------------------------14737809831466499882746641449";
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(uploadServerUri); URL url = new URL(uploadServerUri);
conn = (HttpURLConnection) url.openConnection(); conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); conn.setDoInput(true);
@ -460,7 +465,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data"); conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploaded_file", sourceFile.getName()); conn.setRequestProperty("uploaded_file", fileName);
ProgressOutputStream pos = new ProgressOutputStream(conn.getOutputStream()); ProgressOutputStream pos = new ProgressOutputStream(conn.getOutputStream());
pos.setListener(new OutputStreamListener() { pos.setListener(new OutputStreamListener() {
@ -473,7 +478,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
DataOutputStream dos = new DataOutputStream(pos); DataOutputStream dos = new DataOutputStream(pos);
dos.writeBytes(lineEnd + twoHyphens + boundary + lineEnd); dos.writeBytes(lineEnd + twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"userfile\"; filename=\""+ sourceFile.getName() + "\"" + lineEnd); dos.writeBytes("Content-Disposition: form-data; name=\"userfile\"; filename=\""+ fileName + "\"" + lineEnd);
dos.writeBytes("Content-Type: application/octet-stream" + lineEnd); dos.writeBytes("Content-Type: application/octet-stream" + lineEnd);
dos.writeBytes(lineEnd); dos.writeBytes(lineEnd);
@ -482,7 +487,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
dos.writeBytes(lineEnd); dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fileInputStream.close();
dos.flush(); dos.flush();
dos.close(); dos.close();
@ -519,27 +523,33 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
return cursor.getString(column_index); return cursor.getString(column_index);
} }
private void showPopupMenuAskingImageSize(String filePath) { private void showPopupMenuAskingImageSize(String filePath, Bitmap image) {
fileToUploadPath = filePath; fileToUploadPath = filePath;
getActivity().openContextMenu(sendImage); imageToUpload = image;
sendImage.showContextMenu();
} }
private void uploadAndSendImage(final String filePath, final ImageSize size) { private void uploadAndSendImage(final String filePath, final Bitmap image, final ImageSize size) {
progressBar.setVisibility(View.VISIBLE); uploadLayout.setVisibility(View.VISIBLE);
message.setVisibility(View.GONE); textLayout.setVisibility(View.GONE);
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
Bitmap bm = BitmapFactory.decodeFile(filePath); Bitmap bm = null;
if (bm != null && size != ImageSize.REAL) { if (filePath != null) {
int pixelsMax = size == ImageSize.SMALL ? SIZE_SMALL : size == ImageSize.MEDIUM ? SIZE_MEDIUM : SIZE_LARGE; bm = BitmapFactory.decodeFile(filePath);
if (bm.getWidth() > bm.getHeight() && bm.getWidth() > pixelsMax) { if (bm != null && size != ImageSize.REAL) {
bm = Bitmap.createScaledBitmap(bm, pixelsMax, (pixelsMax * bm.getHeight()) / bm.getWidth(), false); int pixelsMax = size == ImageSize.SMALL ? SIZE_SMALL : size == ImageSize.MEDIUM ? SIZE_MEDIUM : SIZE_LARGE;
} else if (bm.getHeight() > bm.getWidth() && bm.getHeight() > pixelsMax) { if (bm.getWidth() > bm.getHeight() && bm.getWidth() > pixelsMax) {
bm = Bitmap.createScaledBitmap(bm, (pixelsMax * bm.getWidth()) / bm.getHeight(), pixelsMax, false); bm = Bitmap.createScaledBitmap(bm, pixelsMax, (pixelsMax * bm.getHeight()) / bm.getWidth(), false);
} } else if (bm.getHeight() > bm.getWidth() && bm.getHeight() > pixelsMax) {
} bm = Bitmap.createScaledBitmap(bm, (pixelsMax * bm.getWidth()) / bm.getHeight(), pixelsMax, false);
}
}
} else if (image != null) {
bm = image;
}
final Bitmap fbm = bm; final Bitmap fbm = bm;
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ByteArrayOutputStream outStream = new ByteArrayOutputStream();
@ -548,12 +558,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
} }
final String url = uploadImage(filePath, bm, COMPRESSOR_QUALITY, outStream.size()); final String url = uploadImage(filePath, bm, COMPRESSOR_QUALITY, outStream.size());
File file = new File(Environment.getExternalStorageDirectory(), "linphone-android-photo-temp.jpg");
file.delete();
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
progressBar.setVisibility(View.GONE); uploadLayout.setVisibility(View.GONE);
message.setVisibility(View.VISIBLE); textLayout.setVisibility(View.VISIBLE);
if (url != null) { if (url != null) {
sendImageMessage(url, fbm); sendImageMessage(url, fbm);
} else { } else {
@ -568,8 +580,26 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ADD_PHOTO && resultCode == Activity.RESULT_OK) { if (requestCode == ADD_PHOTO && resultCode == Activity.RESULT_OK) {
final String filePath = getRealPathFromURI(data.getData()); if (data != null && data.getExtras() != null && data.getExtras().get("data") != null) {
showPopupMenuAskingImageSize(filePath); Bitmap bm = (Bitmap) data.getExtras().get("data");
showPopupMenuAskingImageSize(null, bm);
}
else if (data != null && data.getData() != null) {
String filePath = getRealPathFromURI(data.getData());
showPopupMenuAskingImageSize(filePath, null);
}
else if (imageToUploadUri != null) {
String filePath = imageToUploadUri.getPath();
showPopupMenuAskingImageSize(filePath, null);
}
else {
File file = new File(Environment.getExternalStorageDirectory(), "linphone-android-photo-temp.jpg");
if (file.exists()) {
imageToUploadUri = Uri.fromFile(file);
String filePath = imageToUploadUri.getPath();
showPopupMenuAskingImageSize(filePath, null);
}
}
} else { } else {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }

View file

@ -168,7 +168,7 @@ public class ChatStorage {
class ChatHelper extends SQLiteOpenHelper { class ChatHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 9; private static final int DATABASE_VERSION = 12;
private static final String DATABASE_NAME = "linphone-android"; private static final String DATABASE_NAME = "linphone-android";
ChatHelper(Context context) { ChatHelper(Context context) {