diff --git a/res/layout/chat_bubble_alt_incoming.xml b/res/layout/chat_bubble_alt_incoming.xml
index de8d7bb5b..50919279b 100644
--- a/res/layout/chat_bubble_alt_incoming.xml
+++ b/res/layout/chat_bubble_alt_incoming.xml
@@ -18,6 +18,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
+
+
+
+
Reçu
Actif en arrière plan
+
+ Télécharger
+ Téléchargement échoué. Vérifiez votre connexion internet ou reéssayez plus tard.
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c6000aa2c..d6dfa7106 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -425,4 +425,7 @@
Incoming
Background mode
+
+ Download
+ Download failed. Check your internet connection or try again later.
diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java
index 8ef341230..acd14c710 100644
--- a/src/org/linphone/ChatFragment.java
+++ b/src/org/linphone/ChatFragment.java
@@ -308,10 +308,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
if (msg.getMessage() != null) {
displayMessage(msg.getId(), msg.getMessage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout);
} else {
- displayImageMessage(msg.getId(), msg.getImage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout);
+ displayImageMessage(msg.getId(), msg.getImage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout, msg.getUrl());
}
- if (!msg.isRed())
+ if (!msg.isRead())
chatStorage.markMessageAsRead(msg.getId());
}
LinphoneActivity.instance().updateMissedChatCount();
@@ -373,13 +373,43 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
registerForContextMenu(v);
}
- private void displayImageMessage(int id, Bitmap image, String time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout) {
+ private void displayImageMessage(final int id, Bitmap image, String time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout, final String url) {
BubbleChat bubble = new BubbleChat(layout.getContext(), id, null, image, time, isIncoming, status, previousMessageID);
if (!isIncoming) {
lastSentMessageBubble = bubble;
}
+
+ final View v = bubble.getView();
+ bubble.setDownloadImageButtonListener(new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ final Bitmap bm = ChatFragment.downloadImage(url);
+ if (bm != null) {
+ LinphoneActivity.instance().getChatStorage().saveImage(id, bm);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ ((ImageView)v.findViewById(R.id.image)).setImageBitmap(bm);
+ v.findViewById(R.id.image).setVisibility(View.VISIBLE);
+ v.findViewById(R.id.download).setVisibility(View.GONE);
+ }
+ });
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ LinphoneActivity.instance().displayCustomToast(getString(R.string.download_image_failed), Toast.LENGTH_LONG);
+ }
+ });
+ }
+ }
+ }).start();
+ }
+ });
- View v = bubble.getView();
previousMessageID = id;
layout.addView(v);
registerForContextMenu(v);
@@ -541,7 +571,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
}
latestImageMessages.put(newId, url);
- displayImageMessage(newId, bitmap, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout);
+ displayImageMessage(newId, bitmap, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout, url);
scrollToEnd();
} else if (!isNetworkReachable && LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().displayCustomToast(getString(R.string.error_network_unreachable), Toast.LENGTH_LONG);
@@ -576,13 +606,22 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
});
} else if (message.getExternalBodyUrl() != null) {
byte[] rawImage = LinphoneActivity.instance().getChatStorage().getRawImageFromMessage(id);
- final Bitmap bm = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- displayImageMessage(id, bm, String.valueOf(message.getTime()), true, null, messagesLayout);
- }
- });
+ if (rawImage == null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ displayImageMessage(id, null, String.valueOf(message.getTime()), true, null, messagesLayout, message.getExternalBodyUrl());
+ }
+ });
+ } else {
+ final Bitmap bm = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ displayImageMessage(id, bm, String.valueOf(message.getTime()), true, null, messagesLayout, "");
+ }
+ });
+ }
}
scrollToEnd();
}
diff --git a/src/org/linphone/ChatMessage.java b/src/org/linphone/ChatMessage.java
index 185e3f474..eb45e3b4c 100644
--- a/src/org/linphone/ChatMessage.java
+++ b/src/org/linphone/ChatMessage.java
@@ -29,13 +29,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
public class ChatMessage {
private String message;
private String timestamp;
+ private String url;
private boolean incoming;
private int status;
private int id;
private Bitmap image;
- private boolean isRed;
+ private boolean isRead;
- public ChatMessage(int id, String message, byte[] rawImage, String timestamp, boolean incoming, int status, boolean red) {
+ public ChatMessage(int id, String message, byte[] rawImage, String timestamp, boolean incoming, int status, boolean read) {
super();
this.id = id;
this.message = message;
@@ -43,7 +44,7 @@ public class ChatMessage {
this.incoming = incoming;
this.status = status;
this.image = rawImage != null ? BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length) : null;
- this.isRed = red;
+ this.isRead = read;
}
public int getId() {
@@ -86,7 +87,15 @@ public class ChatMessage {
return image;
}
- public boolean isRed() {
- return isRed;
+ public boolean isRead() {
+ return isRead;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
}
}
diff --git a/src/org/linphone/ChatStorage.java b/src/org/linphone/ChatStorage.java
index aff4fc8bb..e8bd64de0 100644
--- a/src/org/linphone/ChatStorage.java
+++ b/src/org/linphone/ChatStorage.java
@@ -81,7 +81,7 @@ public class ChatStorage {
db.update(TABLE_NAME, values, "id LIKE " + id, null);
}
- public int saveMessage(String from, String to, String message, long time) {
+ public int saveTextMessage(String from, String to, String message, long time) {
ContentValues values = new ContentValues();
if (from.equals("")) {
values.put("localContact", from);
@@ -101,10 +101,7 @@ public class ChatStorage {
return (int) db.insert(TABLE_NAME, null, values);
}
- public int saveMessage(String from, String to, Bitmap image, long time) {
- if (image == null)
- return -1;
-
+ public int saveImageMessage(String from, String to, Bitmap image, String url, long time) {
ContentValues values = new ContentValues();
if (from.equals("")) {
values.put("localContact", from);
@@ -119,13 +116,28 @@ public class ChatStorage {
values.put("read", NOT_READ);
values.put("status", LinphoneChatMessage.State.Idle.toInt());
}
+ values.put("url", url);
+ if (image != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ image.compress(CompressFormat.JPEG, 100, baos);
+ values.put("image", baos.toByteArray());
+ }
+
+ values.put("time", time);
+ return (int) db.insert(TABLE_NAME, null, values);
+ }
+
+ public void saveImage(int id, Bitmap image) {
+ if (image == null)
+ return;
+
+ ContentValues values = new ContentValues();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(CompressFormat.JPEG, 100, baos);
values.put("image", baos.toByteArray());
- values.put("time", time);
- return (int) db.insert(TABLE_NAME, null, values);
+ db.update(TABLE_NAME, values, "id LIKE " + id, null);
}
public int saveDraft(String to, String message) {
@@ -186,7 +198,7 @@ public class ChatStorage {
while (c.moveToNext()) {
try {
- String message, timestamp;
+ String message, timestamp, url;
int id = c.getInt(c.getColumnIndex("id"));
int direction = c.getInt(c.getColumnIndex("direction"));
message = c.getString(c.getColumnIndex("message"));
@@ -194,8 +206,10 @@ public class ChatStorage {
int status = c.getInt(c.getColumnIndex("status"));
byte[] rawImage = c.getBlob(c.getColumnIndex("image"));
int read = c.getInt(c.getColumnIndex("read"));
+ url = c.getString(c.getColumnIndex("url"));
ChatMessage chatMessage = new ChatMessage(id, message, rawImage, timestamp, direction == INCOMING, status, read == READ);
+ chatMessage.setUrl(url);
chatMessages.add(chatMessage);
} catch (Exception e) {
e.printStackTrace();
@@ -274,7 +288,7 @@ public class ChatStorage {
if (c.moveToFirst()) {
byte[] rawImage = c.getBlob(c.getColumnIndex("image"));
c.close();
- return rawImage;
+ return (rawImage == null || rawImage.length == 0) ? null : rawImage;
}
c.close();
@@ -283,7 +297,7 @@ public class ChatStorage {
class ChatHelper extends SQLiteOpenHelper {
- private static final int DATABASE_VERSION = 14;
+ private static final int DATABASE_VERSION = 15;
private static final String DATABASE_NAME = "linphone-android";
ChatHelper(Context context) {
@@ -292,7 +306,7 @@ public class ChatStorage {
@Override
public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, image BLOB, time NUMERIC, read INTEGER, status INTEGER);");
+ db.execSQL("CREATE TABLE " + TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, image BLOB, url TEXT, time NUMERIC, read INTEGER, status INTEGER);");
db.execSQL("CREATE TABLE " + DRAFT_TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, remoteContact TEXT NOT NULL, message TEXT);");
}
diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java
index d216aaf22..98f9d0efe 100644
--- a/src/org/linphone/LinphoneActivity.java
+++ b/src/org/linphone/LinphoneActivity.java
@@ -739,12 +739,12 @@ public class LinphoneActivity extends FragmentActivity implements
public int onMessageSent(String to, String message) {
getChatStorage().deleteDraft(to);
- return getChatStorage().saveMessage("", to, message, System.currentTimeMillis());
+ return getChatStorage().saveTextMessage("", to, message, System.currentTimeMillis());
}
public int onMessageSent(String to, Bitmap image, String imageURL) {
getChatStorage().deleteDraft(to);
- return getChatStorage().saveMessage("", to, image, System.currentTimeMillis());
+ return getChatStorage().saveImageMessage("", to, image, imageURL, System.currentTimeMillis());
}
public void onMessageStateChanged(String to, String message, int newState) {
diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java
index 96ddd636f..8d142d956 100644
--- a/src/org/linphone/LinphoneManager.java
+++ b/src/org/linphone/LinphoneManager.java
@@ -95,7 +95,6 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
-import android.graphics.Bitmap;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -1118,11 +1117,11 @@ public class LinphoneManager implements LinphoneCoreListener {
String notificationText = null;
int id = -1;
if (textMessage != null && textMessage.length() > 0) {
- id = chatStorage.saveMessage(from.asStringUriOnly(), "", textMessage, message.getTime());
+ id = chatStorage.saveTextMessage(from.asStringUriOnly(), "", textMessage, message.getTime());
notificationText = textMessage;
} else if (url != null && url.length() > 0) {
- Bitmap bm = ChatFragment.downloadImage(url);
- id = chatStorage.saveMessage(from.asStringUriOnly(), "", bm, message.getTime());
+ //Bitmap bm = ChatFragment.downloadImage(url);
+ id = chatStorage.saveImageMessage(from.asStringUriOnly(), "", null, message.getExternalBodyUrl(), message.getTime());
notificationText = url;
}
diff --git a/src/org/linphone/ui/BubbleChat.java b/src/org/linphone/ui/BubbleChat.java
index e443cbcf8..7df7792f7 100644
--- a/src/org/linphone/ui/BubbleChat.java
+++ b/src/org/linphone/ui/BubbleChat.java
@@ -26,6 +26,7 @@ import org.linphone.LinphoneUtils;
import org.linphone.R;
import org.linphone.core.LinphoneChatMessage;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
@@ -37,6 +38,8 @@ import android.text.method.LinkMovementMethod;
import android.text.style.ImageSpan;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
@@ -46,6 +49,7 @@ import android.widget.TextView;
/**
* @author Sylvain Berfini
*/
+@SuppressLint("SimpleDateFormat")
public class BubbleChat {
private static final HashMap emoticons = new HashMap();
static {
@@ -81,6 +85,7 @@ public class BubbleChat {
private RelativeLayout view;
private ImageView statusView;
+ private Button download;
public BubbleChat(Context context, int id, String message, Bitmap image, String time, boolean isIncoming, LinphoneChatMessage.State status, int previousID) {
view = new RelativeLayout(context);
@@ -144,6 +149,11 @@ public class BubbleChat {
imageView.setVisibility(View.GONE);
}
+ download = (Button) layout.findViewById(R.id.download);
+ if (download != null && image == null && message == null) {
+ download.setVisibility(View.VISIBLE);
+ }
+
TextView timeView = (TextView) layout.findViewById(R.id.time);
timeView.setText(timestampToHumanDate(context, time));
@@ -261,4 +271,10 @@ public class BubbleChat {
return Html.fromHtml(text);
}
+
+ public void setDownloadImageButtonListener(OnClickListener onClickListener) {
+ if (download != null) {
+ download.setOnClickListener(onClickListener);
+ }
+ }
}