diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e47295d10..3e98b775f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -25,6 +25,8 @@
+
+
diff --git a/res/drawable-hdpi/all_default.png b/res/drawable-hdpi/all_default.png
deleted file mode 100644
index 18e7eebd4..000000000
Binary files a/res/drawable-hdpi/all_default.png and /dev/null differ
diff --git a/res/drawable-hdpi/all_selected.png b/res/drawable-hdpi/all_selected.png
deleted file mode 100644
index d062ce11c..000000000
Binary files a/res/drawable-hdpi/all_selected.png and /dev/null differ
diff --git a/res/drawable-hdpi/back_default.png b/res/drawable-hdpi/back_default.png
index 37c4f57b4..d7088080a 100644
Binary files a/res/drawable-hdpi/back_default.png and b/res/drawable-hdpi/back_default.png differ
diff --git a/res/drawable-hdpi/back_disabled.png b/res/drawable-hdpi/back_disabled.png
new file mode 100644
index 000000000..d6e641fa5
Binary files /dev/null and b/res/drawable-hdpi/back_disabled.png differ
diff --git a/res/drawable-hdpi/back_over.png b/res/drawable-hdpi/back_over.png
index 08c7cf98a..d06321994 100644
Binary files a/res/drawable-hdpi/back_over.png and b/res/drawable-hdpi/back_over.png differ
diff --git a/res/drawable-hdpi/chat_back_default.png b/res/drawable-hdpi/chat_back_default.png
new file mode 100644
index 000000000..18ec0869e
Binary files /dev/null and b/res/drawable-hdpi/chat_back_default.png differ
diff --git a/res/drawable-hdpi/chat_back_over.png b/res/drawable-hdpi/chat_back_over.png
new file mode 100644
index 000000000..8f4563934
Binary files /dev/null and b/res/drawable-hdpi/chat_back_over.png differ
diff --git a/res/drawable-hdpi/chat_default.png b/res/drawable-hdpi/chat_default.png
index 40392141a..27be92470 100644
Binary files a/res/drawable-hdpi/chat_default.png and b/res/drawable-hdpi/chat_default.png differ
diff --git a/res/drawable-hdpi/chat_edit_default.png b/res/drawable-hdpi/chat_edit_default.png
index 428ce5df8..09226ff9e 100644
Binary files a/res/drawable-hdpi/chat_edit_default.png and b/res/drawable-hdpi/chat_edit_default.png differ
diff --git a/res/drawable-hdpi/chat_edit_over.png b/res/drawable-hdpi/chat_edit_over.png
index 62c0a4c34..6a800364a 100644
Binary files a/res/drawable-hdpi/chat_edit_over.png and b/res/drawable-hdpi/chat_edit_over.png differ
diff --git a/res/drawable-hdpi/chat_field_background.9.png b/res/drawable-hdpi/chat_field_background.9.png
new file mode 100644
index 000000000..75b262e7c
Binary files /dev/null and b/res/drawable-hdpi/chat_field_background.9.png differ
diff --git a/res/drawable-hdpi/chat_icon_over.png b/res/drawable-hdpi/chat_icon_over.png
index 7da46015c..6644f4f98 100644
Binary files a/res/drawable-hdpi/chat_icon_over.png and b/res/drawable-hdpi/chat_icon_over.png differ
diff --git a/res/drawable-hdpi/chat_message_background.png b/res/drawable-hdpi/chat_message_background.png
deleted file mode 100644
index 17a1bee8d..000000000
Binary files a/res/drawable-hdpi/chat_message_background.png and /dev/null differ
diff --git a/res/drawable-hdpi/chat_new_default.png b/res/drawable-hdpi/chat_new_default.png
index 053723d22..14811328c 100644
Binary files a/res/drawable-hdpi/chat_new_default.png and b/res/drawable-hdpi/chat_new_default.png differ
diff --git a/res/drawable-hdpi/chat_new_over.png b/res/drawable-hdpi/chat_new_over.png
index 34ffdf83f..e63d15a94 100644
Binary files a/res/drawable-hdpi/chat_new_over.png and b/res/drawable-hdpi/chat_new_over.png differ
diff --git a/res/drawable-hdpi/chat_ok_default.png b/res/drawable-hdpi/chat_ok_default.png
index 0c49ac3d5..afc875957 100644
Binary files a/res/drawable-hdpi/chat_ok_default.png and b/res/drawable-hdpi/chat_ok_default.png differ
diff --git a/res/drawable-hdpi/chat_ok_over.png b/res/drawable-hdpi/chat_ok_over.png
index 4fe6248f8..3b12187f2 100644
Binary files a/res/drawable-hdpi/chat_ok_over.png and b/res/drawable-hdpi/chat_ok_over.png differ
diff --git a/res/drawable-hdpi/chat_over.png b/res/drawable-hdpi/chat_over.png
index d8482543f..55f66d83a 100644
Binary files a/res/drawable-hdpi/chat_over.png and b/res/drawable-hdpi/chat_over.png differ
diff --git a/res/drawable-hdpi/chat_photo_default.png b/res/drawable-hdpi/chat_photo_default.png
new file mode 100644
index 000000000..6867dafa7
Binary files /dev/null and b/res/drawable-hdpi/chat_photo_default.png differ
diff --git a/res/drawable-hdpi/chat_photo_disabled.png b/res/drawable-hdpi/chat_photo_disabled.png
new file mode 100644
index 000000000..1a3152ffe
Binary files /dev/null and b/res/drawable-hdpi/chat_photo_disabled.png differ
diff --git a/res/drawable-hdpi/chat_photo_over.png b/res/drawable-hdpi/chat_photo_over.png
new file mode 100644
index 000000000..26fbf1a25
Binary files /dev/null and b/res/drawable-hdpi/chat_photo_over.png differ
diff --git a/res/drawable-hdpi/chat_progressbar_background.jpg b/res/drawable-hdpi/chat_progressbar_background.jpg
new file mode 100644
index 000000000..bddac059f
Binary files /dev/null and b/res/drawable-hdpi/chat_progressbar_background.jpg differ
diff --git a/res/drawable-hdpi/chat_selected.png b/res/drawable-hdpi/chat_selected.png
index 86823325d..a20549119 100644
Binary files a/res/drawable-hdpi/chat_selected.png and b/res/drawable-hdpi/chat_selected.png differ
diff --git a/res/drawable-hdpi/chat_send_default.png b/res/drawable-hdpi/chat_send_default.png
new file mode 100644
index 000000000..d441de3f2
Binary files /dev/null and b/res/drawable-hdpi/chat_send_default.png differ
diff --git a/res/drawable-hdpi/chat_send_disabled.png b/res/drawable-hdpi/chat_send_disabled.png
new file mode 100644
index 000000000..75b831602
Binary files /dev/null and b/res/drawable-hdpi/chat_send_disabled.png differ
diff --git a/res/drawable-hdpi/chat_send_message_default.png b/res/drawable-hdpi/chat_send_message_default.png
deleted file mode 100644
index 1bee48a2f..000000000
Binary files a/res/drawable-hdpi/chat_send_message_default.png and /dev/null differ
diff --git a/res/drawable-hdpi/chat_send_message_disabled.png b/res/drawable-hdpi/chat_send_message_disabled.png
deleted file mode 100644
index e16748ec1..000000000
Binary files a/res/drawable-hdpi/chat_send_message_disabled.png and /dev/null differ
diff --git a/res/drawable-hdpi/chat_send_message_over.png b/res/drawable-hdpi/chat_send_message_over.png
deleted file mode 100644
index a130fe1bf..000000000
Binary files a/res/drawable-hdpi/chat_send_message_over.png and /dev/null differ
diff --git a/res/drawable-hdpi/chat_send_over.png b/res/drawable-hdpi/chat_send_over.png
new file mode 100644
index 000000000..49976fe0d
Binary files /dev/null and b/res/drawable-hdpi/chat_send_over.png differ
diff --git a/res/drawable-hdpi/contact_add_default.png b/res/drawable-hdpi/contact_add_default.png
new file mode 100644
index 000000000..6ce83f41a
Binary files /dev/null and b/res/drawable-hdpi/contact_add_default.png differ
diff --git a/res/drawable-hdpi/contact_add_over.png b/res/drawable-hdpi/contact_add_over.png
new file mode 100644
index 000000000..3fb6320f7
Binary files /dev/null and b/res/drawable-hdpi/contact_add_over.png differ
diff --git a/res/drawable-hdpi/contact_back_default.png b/res/drawable-hdpi/contact_back_default.png
new file mode 100644
index 000000000..18ec0869e
Binary files /dev/null and b/res/drawable-hdpi/contact_back_default.png differ
diff --git a/res/drawable-hdpi/contact_back_over.png b/res/drawable-hdpi/contact_back_over.png
new file mode 100644
index 000000000..8f4563934
Binary files /dev/null and b/res/drawable-hdpi/contact_back_over.png differ
diff --git a/res/drawable-hdpi/contact_cancel_default.png b/res/drawable-hdpi/contact_cancel_default.png
new file mode 100644
index 000000000..80dd44944
Binary files /dev/null and b/res/drawable-hdpi/contact_cancel_default.png differ
diff --git a/res/drawable-hdpi/contact_cancel_over.png b/res/drawable-hdpi/contact_cancel_over.png
new file mode 100644
index 000000000..9cfebd8d6
Binary files /dev/null and b/res/drawable-hdpi/contact_cancel_over.png differ
diff --git a/res/drawable-hdpi/contact_edit_default.png b/res/drawable-hdpi/contact_edit_default.png
index 428ce5df8..09226ff9e 100644
Binary files a/res/drawable-hdpi/contact_edit_default.png and b/res/drawable-hdpi/contact_edit_default.png differ
diff --git a/res/drawable-hdpi/contact_edit_over.png b/res/drawable-hdpi/contact_edit_over.png
index 62c0a4c34..6a800364a 100644
Binary files a/res/drawable-hdpi/contact_edit_over.png and b/res/drawable-hdpi/contact_edit_over.png differ
diff --git a/res/drawable-hdpi/contact_ok_default.png b/res/drawable-hdpi/contact_ok_default.png
new file mode 100644
index 000000000..afc875957
Binary files /dev/null and b/res/drawable-hdpi/contact_ok_default.png differ
diff --git a/res/drawable-hdpi/contact_ok_disabled.png b/res/drawable-hdpi/contact_ok_disabled.png
new file mode 100644
index 000000000..5e72c3f55
Binary files /dev/null and b/res/drawable-hdpi/contact_ok_disabled.png differ
diff --git a/res/drawable-hdpi/contact_ok_over.png b/res/drawable-hdpi/contact_ok_over.png
new file mode 100644
index 000000000..3b12187f2
Binary files /dev/null and b/res/drawable-hdpi/contact_ok_over.png differ
diff --git a/res/drawable-hdpi/contacts_add_default.png b/res/drawable-hdpi/contacts_add_default.png
new file mode 100644
index 000000000..09936c840
Binary files /dev/null and b/res/drawable-hdpi/contacts_add_default.png differ
diff --git a/res/drawable-hdpi/contacts_add_over.png b/res/drawable-hdpi/contacts_add_over.png
new file mode 100644
index 000000000..38cc680e1
Binary files /dev/null and b/res/drawable-hdpi/contacts_add_over.png differ
diff --git a/res/drawable-hdpi/contacts_all_default.png b/res/drawable-hdpi/contacts_all_default.png
new file mode 100644
index 000000000..2aceb2b41
Binary files /dev/null and b/res/drawable-hdpi/contacts_all_default.png differ
diff --git a/res/drawable-hdpi/contacts_all_selected.png b/res/drawable-hdpi/contacts_all_selected.png
new file mode 100644
index 000000000..d5dd11195
Binary files /dev/null and b/res/drawable-hdpi/contacts_all_selected.png differ
diff --git a/res/drawable-hdpi/contacts_back_default.png b/res/drawable-hdpi/contacts_back_default.png
new file mode 100644
index 000000000..55a03444d
Binary files /dev/null and b/res/drawable-hdpi/contacts_back_default.png differ
diff --git a/res/drawable-hdpi/contacts_back_over.png b/res/drawable-hdpi/contacts_back_over.png
new file mode 100644
index 000000000..eccbad3cd
Binary files /dev/null and b/res/drawable-hdpi/contacts_back_over.png differ
diff --git a/res/drawable-hdpi/contacts_default.png b/res/drawable-hdpi/contacts_default.png
index 9f8c57147..fb2146a91 100644
Binary files a/res/drawable-hdpi/contacts_default.png and b/res/drawable-hdpi/contacts_default.png differ
diff --git a/res/drawable-hdpi/contacts_linphone_default.png b/res/drawable-hdpi/contacts_linphone_default.png
new file mode 100644
index 000000000..c4a013fd5
Binary files /dev/null and b/res/drawable-hdpi/contacts_linphone_default.png differ
diff --git a/res/drawable-hdpi/contacts_linphone_selected.png b/res/drawable-hdpi/contacts_linphone_selected.png
new file mode 100644
index 000000000..eff04f247
Binary files /dev/null and b/res/drawable-hdpi/contacts_linphone_selected.png differ
diff --git a/res/drawable-hdpi/contacts_over.png b/res/drawable-hdpi/contacts_over.png
index 88a86b8a7..7e0f661ba 100644
Binary files a/res/drawable-hdpi/contacts_over.png and b/res/drawable-hdpi/contacts_over.png differ
diff --git a/res/drawable-hdpi/contacts_selected.png b/res/drawable-hdpi/contacts_selected.png
index dc033743c..04f579806 100644
Binary files a/res/drawable-hdpi/contacts_selected.png and b/res/drawable-hdpi/contacts_selected.png differ
diff --git a/res/drawable-hdpi/dialer_default.png b/res/drawable-hdpi/dialer_default.png
index b23fcbb41..2fc61b3af 100644
Binary files a/res/drawable-hdpi/dialer_default.png and b/res/drawable-hdpi/dialer_default.png differ
diff --git a/res/drawable-hdpi/dialer_over.png b/res/drawable-hdpi/dialer_over.png
index 3727c5fba..7b718469f 100644
Binary files a/res/drawable-hdpi/dialer_over.png and b/res/drawable-hdpi/dialer_over.png differ
diff --git a/res/drawable-hdpi/dialer_selected.png b/res/drawable-hdpi/dialer_selected.png
index 5883398d2..80cd520f5 100644
Binary files a/res/drawable-hdpi/dialer_selected.png and b/res/drawable-hdpi/dialer_selected.png differ
diff --git a/res/drawable-hdpi/history_all_default.png b/res/drawable-hdpi/history_all_default.png
index fe9f61f2f..d063f0242 100644
Binary files a/res/drawable-hdpi/history_all_default.png and b/res/drawable-hdpi/history_all_default.png differ
diff --git a/res/drawable-hdpi/history_all_selected.png b/res/drawable-hdpi/history_all_selected.png
index 9790cc945..927d1228f 100644
Binary files a/res/drawable-hdpi/history_all_selected.png and b/res/drawable-hdpi/history_all_selected.png differ
diff --git a/res/drawable-hdpi/history_default.png b/res/drawable-hdpi/history_default.png
index 2d3fed230..92a298d2f 100644
Binary files a/res/drawable-hdpi/history_default.png and b/res/drawable-hdpi/history_default.png differ
diff --git a/res/drawable-hdpi/history_delete_default.png b/res/drawable-hdpi/history_delete_default.png
new file mode 100644
index 000000000..dce0ad0b3
Binary files /dev/null and b/res/drawable-hdpi/history_delete_default.png differ
diff --git a/res/drawable-hdpi/history_delete_disabled.png b/res/drawable-hdpi/history_delete_disabled.png
new file mode 100644
index 000000000..814c07993
Binary files /dev/null and b/res/drawable-hdpi/history_delete_disabled.png differ
diff --git a/res/drawable-hdpi/history_delete_over.png b/res/drawable-hdpi/history_delete_over.png
new file mode 100644
index 000000000..b8d99e352
Binary files /dev/null and b/res/drawable-hdpi/history_delete_over.png differ
diff --git a/res/drawable-hdpi/history_details_add_default.png b/res/drawable-hdpi/history_details_add_default.png
new file mode 100644
index 000000000..6ce83f41a
Binary files /dev/null and b/res/drawable-hdpi/history_details_add_default.png differ
diff --git a/res/drawable-hdpi/history_details_add_over.png b/res/drawable-hdpi/history_details_add_over.png
new file mode 100644
index 000000000..3fb6320f7
Binary files /dev/null and b/res/drawable-hdpi/history_details_add_over.png differ
diff --git a/res/drawable-hdpi/history_details_back_default.png b/res/drawable-hdpi/history_details_back_default.png
new file mode 100644
index 000000000..18ec0869e
Binary files /dev/null and b/res/drawable-hdpi/history_details_back_default.png differ
diff --git a/res/drawable-hdpi/history_details_back_over.png b/res/drawable-hdpi/history_details_back_over.png
new file mode 100644
index 000000000..8f4563934
Binary files /dev/null and b/res/drawable-hdpi/history_details_back_over.png differ
diff --git a/res/drawable-hdpi/history_edit_default.png b/res/drawable-hdpi/history_edit_default.png
index bfb27dedc..9cb5d942f 100644
Binary files a/res/drawable-hdpi/history_edit_default.png and b/res/drawable-hdpi/history_edit_default.png differ
diff --git a/res/drawable-hdpi/history_edit_over.png b/res/drawable-hdpi/history_edit_over.png
index 679ae9f8b..7b29cfb5b 100644
Binary files a/res/drawable-hdpi/history_edit_over.png and b/res/drawable-hdpi/history_edit_over.png differ
diff --git a/res/drawable-hdpi/history_missed_default.png b/res/drawable-hdpi/history_missed_default.png
index 0f2f99b4e..4cc4a5c96 100644
Binary files a/res/drawable-hdpi/history_missed_default.png and b/res/drawable-hdpi/history_missed_default.png differ
diff --git a/res/drawable-hdpi/history_missed_selected.png b/res/drawable-hdpi/history_missed_selected.png
index cb413d997..498e62c22 100644
Binary files a/res/drawable-hdpi/history_missed_selected.png and b/res/drawable-hdpi/history_missed_selected.png differ
diff --git a/res/drawable-hdpi/history_ok_default.png b/res/drawable-hdpi/history_ok_default.png
new file mode 100644
index 000000000..4b402b50c
Binary files /dev/null and b/res/drawable-hdpi/history_ok_default.png differ
diff --git a/res/drawable-hdpi/history_ok_over.png b/res/drawable-hdpi/history_ok_over.png
new file mode 100644
index 000000000..325d61378
Binary files /dev/null and b/res/drawable-hdpi/history_ok_over.png differ
diff --git a/res/drawable-hdpi/history_over.png b/res/drawable-hdpi/history_over.png
index 6e9a4cdff..1d2ddf91c 100644
Binary files a/res/drawable-hdpi/history_over.png and b/res/drawable-hdpi/history_over.png differ
diff --git a/res/drawable-hdpi/history_selected.png b/res/drawable-hdpi/history_selected.png
index 5154e603e..bf1a0867c 100644
Binary files a/res/drawable-hdpi/history_selected.png and b/res/drawable-hdpi/history_selected.png differ
diff --git a/res/drawable-hdpi/linphone_default.png b/res/drawable-hdpi/linphone_default.png
deleted file mode 100644
index 9d240afeb..000000000
Binary files a/res/drawable-hdpi/linphone_default.png and /dev/null differ
diff --git a/res/drawable-hdpi/linphone_selected.png b/res/drawable-hdpi/linphone_selected.png
deleted file mode 100644
index 0a75d15f0..000000000
Binary files a/res/drawable-hdpi/linphone_selected.png and /dev/null differ
diff --git a/res/drawable-hdpi/micro_off_default.png b/res/drawable-hdpi/micro_off_default.png
index 2ec3be550..a877f654c 100644
Binary files a/res/drawable-hdpi/micro_off_default.png and b/res/drawable-hdpi/micro_off_default.png differ
diff --git a/res/drawable-hdpi/micro_off_disabled.png b/res/drawable-hdpi/micro_off_disabled.png
index 39f55197e..4baf0de70 100644
Binary files a/res/drawable-hdpi/micro_off_disabled.png and b/res/drawable-hdpi/micro_off_disabled.png differ
diff --git a/res/drawable-hdpi/micro_off_over.png b/res/drawable-hdpi/micro_off_over.png
index 7c898d75d..8663a11ef 100644
Binary files a/res/drawable-hdpi/micro_off_over.png and b/res/drawable-hdpi/micro_off_over.png differ
diff --git a/res/drawable-hdpi/micro_on_default.png b/res/drawable-hdpi/micro_on_default.png
index ca63b44ff..8c73609fe 100644
Binary files a/res/drawable-hdpi/micro_on_default.png and b/res/drawable-hdpi/micro_on_default.png differ
diff --git a/res/drawable-hdpi/micro_on_disabled.png b/res/drawable-hdpi/micro_on_disabled.png
index 87fee6aa1..35fb4bfeb 100644
Binary files a/res/drawable-hdpi/micro_on_disabled.png and b/res/drawable-hdpi/micro_on_disabled.png differ
diff --git a/res/drawable-hdpi/micro_on_over.png b/res/drawable-hdpi/micro_on_over.png
index fd9d00a84..96f645d52 100644
Binary files a/res/drawable-hdpi/micro_on_over.png and b/res/drawable-hdpi/micro_on_over.png differ
diff --git a/res/drawable-hdpi/new_contact_default.png b/res/drawable-hdpi/new_contact_default.png
deleted file mode 100644
index 8498a06a0..000000000
Binary files a/res/drawable-hdpi/new_contact_default.png and /dev/null differ
diff --git a/res/drawable-hdpi/new_contact_over.png b/res/drawable-hdpi/new_contact_over.png
deleted file mode 100644
index 71b833359..000000000
Binary files a/res/drawable-hdpi/new_contact_over.png and /dev/null differ
diff --git a/res/drawable-hdpi/options_add_default.png b/res/drawable-hdpi/options_add_default.png
index 387a58640..59ea816e7 100644
Binary files a/res/drawable-hdpi/options_add_default.png and b/res/drawable-hdpi/options_add_default.png differ
diff --git a/res/drawable-hdpi/options_add_disabled.png b/res/drawable-hdpi/options_add_disabled.png
index 8e85bb0e9..a8d6f75d8 100644
Binary files a/res/drawable-hdpi/options_add_disabled.png and b/res/drawable-hdpi/options_add_disabled.png differ
diff --git a/res/drawable-hdpi/options_add_over.png b/res/drawable-hdpi/options_add_over.png
index a61c79c90..06ec439f1 100644
Binary files a/res/drawable-hdpi/options_add_over.png and b/res/drawable-hdpi/options_add_over.png differ
diff --git a/res/drawable-hdpi/options_default.png b/res/drawable-hdpi/options_default.png
index eee6a123d..cdec05400 100644
Binary files a/res/drawable-hdpi/options_default.png and b/res/drawable-hdpi/options_default.png differ
diff --git a/res/drawable-hdpi/options_disabled.png b/res/drawable-hdpi/options_disabled.png
index 345770e41..6199d95b9 100644
Binary files a/res/drawable-hdpi/options_disabled.png and b/res/drawable-hdpi/options_disabled.png differ
diff --git a/res/drawable-hdpi/options_over.png b/res/drawable-hdpi/options_over.png
index 0f9a8ca1c..4000c7b53 100644
Binary files a/res/drawable-hdpi/options_over.png and b/res/drawable-hdpi/options_over.png differ
diff --git a/res/drawable-hdpi/options_selected.png b/res/drawable-hdpi/options_selected.png
index 14f9dda93..ab105de64 100644
Binary files a/res/drawable-hdpi/options_selected.png and b/res/drawable-hdpi/options_selected.png differ
diff --git a/res/drawable-hdpi/options_transfer_disabled.png b/res/drawable-hdpi/options_transfer_disabled.png
index 81bd23e26..6e8cd79a2 100644
Binary files a/res/drawable-hdpi/options_transfer_disabled.png and b/res/drawable-hdpi/options_transfer_disabled.png differ
diff --git a/res/drawable-hdpi/options_transfer_over.png b/res/drawable-hdpi/options_transfer_over.png
index c725c8ee7..ea07e8d7f 100644
Binary files a/res/drawable-hdpi/options_transfer_over.png and b/res/drawable-hdpi/options_transfer_over.png differ
diff --git a/res/drawable-hdpi/settings_default.png b/res/drawable-hdpi/settings_default.png
index f7059430d..a64d11de2 100644
Binary files a/res/drawable-hdpi/settings_default.png and b/res/drawable-hdpi/settings_default.png differ
diff --git a/res/drawable-hdpi/settings_over.png b/res/drawable-hdpi/settings_over.png
index d36d535b9..75ccd32a1 100644
Binary files a/res/drawable-hdpi/settings_over.png and b/res/drawable-hdpi/settings_over.png differ
diff --git a/res/drawable-hdpi/settings_selected.png b/res/drawable-hdpi/settings_selected.png
index 1dfca0180..d88cf8c97 100644
Binary files a/res/drawable-hdpi/settings_selected.png and b/res/drawable-hdpi/settings_selected.png differ
diff --git a/res/drawable-hdpi/setup_back_default.png b/res/drawable-hdpi/setup_back_default.png
index ba7b27360..ddb63847f 100644
Binary files a/res/drawable-hdpi/setup_back_default.png and b/res/drawable-hdpi/setup_back_default.png differ
diff --git a/res/drawable-hdpi/setup_back_disabled.png b/res/drawable-hdpi/setup_back_disabled.png
index 805084589..bbc23f190 100644
Binary files a/res/drawable-hdpi/setup_back_disabled.png and b/res/drawable-hdpi/setup_back_disabled.png differ
diff --git a/res/drawable-hdpi/setup_back_over.png b/res/drawable-hdpi/setup_back_over.png
index ed550a18d..f0f2aaec7 100644
Binary files a/res/drawable-hdpi/setup_back_over.png and b/res/drawable-hdpi/setup_back_over.png differ
diff --git a/res/drawable-hdpi/setup_cancel_default.png b/res/drawable-hdpi/setup_cancel_default.png
index 3de15c99a..411381928 100644
Binary files a/res/drawable-hdpi/setup_cancel_default.png and b/res/drawable-hdpi/setup_cancel_default.png differ
diff --git a/res/drawable-hdpi/setup_cancel_disabled.png b/res/drawable-hdpi/setup_cancel_disabled.png
index 30b9978fa..97674e02c 100644
Binary files a/res/drawable-hdpi/setup_cancel_disabled.png and b/res/drawable-hdpi/setup_cancel_disabled.png differ
diff --git a/res/drawable-hdpi/setup_cancel_over.png b/res/drawable-hdpi/setup_cancel_over.png
index 470da607e..aab926147 100644
Binary files a/res/drawable-hdpi/setup_cancel_over.png and b/res/drawable-hdpi/setup_cancel_over.png differ
diff --git a/res/drawable-hdpi/setup_letsgo_default.png b/res/drawable-hdpi/setup_letsgo_default.png
index b0f7aa709..342a59a6c 100644
Binary files a/res/drawable-hdpi/setup_letsgo_default.png and b/res/drawable-hdpi/setup_letsgo_default.png differ
diff --git a/res/drawable-hdpi/setup_letsgo_disabled.png b/res/drawable-hdpi/setup_letsgo_disabled.png
index 1c66451b3..c57868e0a 100644
Binary files a/res/drawable-hdpi/setup_letsgo_disabled.png and b/res/drawable-hdpi/setup_letsgo_disabled.png differ
diff --git a/res/drawable-hdpi/setup_letsgo_over.png b/res/drawable-hdpi/setup_letsgo_over.png
index 160a9e1c2..7fc26c6fd 100644
Binary files a/res/drawable-hdpi/setup_letsgo_over.png and b/res/drawable-hdpi/setup_letsgo_over.png differ
diff --git a/res/drawable-hdpi/speaker_off_default.png b/res/drawable-hdpi/speaker_off_default.png
index 5094dd200..43f95c20f 100644
Binary files a/res/drawable-hdpi/speaker_off_default.png and b/res/drawable-hdpi/speaker_off_default.png differ
diff --git a/res/drawable-hdpi/speaker_off_disabled.png b/res/drawable-hdpi/speaker_off_disabled.png
index cb5a1dcf7..440af308e 100644
Binary files a/res/drawable-hdpi/speaker_off_disabled.png and b/res/drawable-hdpi/speaker_off_disabled.png differ
diff --git a/res/drawable-hdpi/speaker_off_over.png b/res/drawable-hdpi/speaker_off_over.png
index bd1779182..0b42163d2 100644
Binary files a/res/drawable-hdpi/speaker_off_over.png and b/res/drawable-hdpi/speaker_off_over.png differ
diff --git a/res/drawable-hdpi/speaker_on_default.png b/res/drawable-hdpi/speaker_on_default.png
index 2f4f58440..ffc9d1763 100644
Binary files a/res/drawable-hdpi/speaker_on_default.png and b/res/drawable-hdpi/speaker_on_default.png differ
diff --git a/res/drawable-hdpi/speaker_on_disabled.png b/res/drawable-hdpi/speaker_on_disabled.png
index a07dc1f5c..1869a1327 100644
Binary files a/res/drawable-hdpi/speaker_on_disabled.png and b/res/drawable-hdpi/speaker_on_disabled.png differ
diff --git a/res/drawable-hdpi/speaker_on_over.png b/res/drawable-hdpi/speaker_on_over.png
index e9b54f839..adc72500d 100644
Binary files a/res/drawable-hdpi/speaker_on_over.png and b/res/drawable-hdpi/speaker_on_over.png differ
diff --git a/res/drawable-hdpi/video_off_default.png b/res/drawable-hdpi/video_off_default.png
index 8e80dd7a6..088412bd7 100644
Binary files a/res/drawable-hdpi/video_off_default.png and b/res/drawable-hdpi/video_off_default.png differ
diff --git a/res/drawable-hdpi/video_off_disabled.png b/res/drawable-hdpi/video_off_disabled.png
index d9806305d..cccfe8d25 100644
Binary files a/res/drawable-hdpi/video_off_disabled.png and b/res/drawable-hdpi/video_off_disabled.png differ
diff --git a/res/drawable-hdpi/video_off_over.png b/res/drawable-hdpi/video_off_over.png
index 26a00c41e..b4bb25bda 100644
Binary files a/res/drawable-hdpi/video_off_over.png and b/res/drawable-hdpi/video_off_over.png differ
diff --git a/res/drawable-hdpi/video_on_default.png b/res/drawable-hdpi/video_on_default.png
index dde8964d9..5c852ac03 100644
Binary files a/res/drawable-hdpi/video_on_default.png and b/res/drawable-hdpi/video_on_default.png differ
diff --git a/res/drawable-hdpi/video_on_disabled.png b/res/drawable-hdpi/video_on_disabled.png
index 02a1cc236..bdfcbe8f6 100644
Binary files a/res/drawable-hdpi/video_on_disabled.png and b/res/drawable-hdpi/video_on_disabled.png differ
diff --git a/res/drawable-hdpi/video_on_over.png b/res/drawable-hdpi/video_on_over.png
index 20fa87e9b..13dd3546e 100644
Binary files a/res/drawable-hdpi/video_on_over.png and b/res/drawable-hdpi/video_on_over.png differ
diff --git a/res/drawable/all_contacts.xml b/res/drawable/all_contacts.xml
index 6746f8f0f..ed171796c 100644
--- a/res/drawable/all_contacts.xml
+++ b/res/drawable/all_contacts.xml
@@ -1,8 +1,8 @@
+ android:drawable="@drawable/contacts_all_selected" />
+ android:drawable="@drawable/contacts_all_default" />
diff --git a/res/drawable/chat_message_delivered.png b/res/drawable/chat_message_delivered.png
new file mode 100644
index 000000000..f8edc012d
Binary files /dev/null and b/res/drawable/chat_message_delivered.png differ
diff --git a/res/drawable/chat_message_inprogress.png b/res/drawable/chat_message_inprogress.png
new file mode 100644
index 000000000..f725a3eb9
Binary files /dev/null and b/res/drawable/chat_message_inprogress.png differ
diff --git a/res/drawable/chat_message_not_delivered.png b/res/drawable/chat_message_not_delivered.png
new file mode 100644
index 000000000..c174df390
Binary files /dev/null and b/res/drawable/chat_message_not_delivered.png differ
diff --git a/res/drawable/chat_send_message.xml b/res/drawable/chat_send_message.xml
index fc995665b..3336f7499 100644
--- a/res/drawable/chat_send_message.xml
+++ b/res/drawable/chat_send_message.xml
@@ -1,10 +1,10 @@
+ android:drawable="@drawable/chat_send_over" />
+ android:drawable="@drawable/chat_send_disabled" />
+ android:drawable="@drawable/chat_send_default" />
diff --git a/res/drawable/chat_send_picture.xml b/res/drawable/chat_send_picture.xml
new file mode 100644
index 000000000..173e351a2
--- /dev/null
+++ b/res/drawable/chat_send_picture.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/res/drawable/contact_add.xml b/res/drawable/contact_add.xml
new file mode 100644
index 000000000..bdfe8f4d9
--- /dev/null
+++ b/res/drawable/contact_add.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/res/drawable/history_delete.xml b/res/drawable/history_delete.xml
new file mode 100644
index 000000000..291afe4bf
--- /dev/null
+++ b/res/drawable/history_delete.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/res/drawable/history_ok.xml b/res/drawable/history_ok.xml
new file mode 100644
index 000000000..ae9b0b5b1
--- /dev/null
+++ b/res/drawable/history_ok.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/res/drawable/linphone_contacts.xml b/res/drawable/linphone_contacts.xml
index ba9480ade..1b8ff0fd7 100644
--- a/res/drawable/linphone_contacts.xml
+++ b/res/drawable/linphone_contacts.xml
@@ -1,7 +1,7 @@
+ android:drawable="@drawable/contacts_linphone_selected" />
+ android:drawable="@drawable/contacts_linphone_default" />
\ No newline at end of file
diff --git a/res/drawable/new_contact.xml b/res/drawable/new_contact.xml
index 7989160af..f5f16757a 100644
--- a/res/drawable/new_contact.xml
+++ b/res/drawable/new_contact.xml
@@ -1,9 +1,9 @@
+ android:drawable="@drawable/contacts_add_over" />
+ android:drawable="@drawable/contacts_add_over" />
+ android:drawable="@drawable/contacts_add_default" />
diff --git a/res/drawable/wizard_notok.png b/res/drawable/wizard_notok.png
index 84813bc2d..c174df390 100644
Binary files a/res/drawable/wizard_notok.png and b/res/drawable/wizard_notok.png differ
diff --git a/res/drawable/wizard_ok.png b/res/drawable/wizard_ok.png
index 769986fb7..f8edc012d 100644
Binary files a/res/drawable/wizard_ok.png and b/res/drawable/wizard_ok.png differ
diff --git a/res/layout/chat.xml b/res/layout/chat.xml
index cdbc226b4..e7f5a0b04 100644
--- a/res/layout/chat.xml
+++ b/res/layout/chat.xml
@@ -49,31 +49,54 @@
-
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="@drawable/chat_field_background">
+
+
+
+
-
-
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/sendPicture"
+ android:layout_toLeftOf="@id/sendMessage"
+ android:padding="20dp"/>
-
+
+
+
\ No newline at end of file
diff --git a/res/layout/contact.xml b/res/layout/contact.xml
index c8b2e13bc..8e88fc8c5 100644
--- a/res/layout/contact.xml
+++ b/res/layout/contact.xml
@@ -11,18 +11,9 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
-
-
+
+
+
+
\ No newline at end of file
diff --git a/res/values-FR/strings.xml b/res/values-FR/strings.xml
index 0febe59b4..75a85ea83 100644
--- a/res/values-FR/strings.xml
+++ b/res/values-FR/strings.xml
@@ -269,5 +269,14 @@
Annuler
Retour
Allons-y
+
+ Petite
+ Moyenne
+ Grande
+ Taille réelle
+ Sauvegarder l\'image
+ Choisissez la source
+ Image sauvegardée
+ Erreur, image non sauvegardée
diff --git a/res/values/custom.xml b/res/values/custom.xml
index 77c17cd97..754c82dab 100644
--- a/res/values/custom.xml
+++ b/res/values/custom.xml
@@ -3,6 +3,7 @@
HH:mm d MMM
HH:mm
+ linphone-mms-%s.jpg
Linphone 2
Linphone
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a603286b3..3552b8106 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -319,5 +319,14 @@
Cancel
Back
Let\'s go
+
+ Small
+ Medium
+ Large
+ Real size
+ Save picture
+ Select source
+ Image saved
+ Error, image not saved
diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java
index 8a40ded69..708671c12 100644
--- a/src/org/linphone/ChatFragment.java
+++ b/src/org/linphone/ChatFragment.java
@@ -22,14 +22,17 @@ import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
+import java.util.ArrayList;
import java.util.List;
import org.apache.http.util.ByteArrayBuffer;
-import org.linphone.LinphoneSimpleListener.LinphoneOnMessageReceivedListener;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.State;
@@ -40,15 +43,19 @@ import org.linphone.ui.AvatarWithShadow;
import org.linphone.ui.BubbleChat;
import android.app.Activity;
-import android.app.ProgressDialog;
+import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
+import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.content.CursorLoader;
@@ -61,19 +68,33 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
+import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
+import android.widget.Toast;
/**
* @author Sylvain Berfini
*/
-public class ChatFragment extends Fragment implements OnClickListener, LinphoneOnMessageReceivedListener, LinphoneChatMessage.StateListener {
+public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.StateListener {
private static final int ADD_PHOTO = 0;
+ private static final int MENU_DELETE_MESSAGE = 0;
+ private static final int MENU_SAVE_PICTURE = 1;
+ 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 COMPRESSOR_QUALITY = 100;
+ private static final int SIZE_SMALL = 500;
+ private static final int SIZE_MEDIUM = 1000;
+ private static final int SIZE_LARGE = 1500;
+
private LinphoneChatRoom chatRoom;
private View view;
private String sipUri;
private EditText message;
+ private ImageView sendImage;
private TextView contactName;
private AvatarWithShadow contactPicture;
private RelativeLayout messagesLayout;
@@ -81,7 +102,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
private int previousMessageID;
private Handler mHandler = new Handler();
private BubbleChat lastSentMessageBubble;
- private ProgressDialog mProgressDialog;
+ private ProgressBar progressBar;
+ private int bytesSent;
+ private String uploadServerUri;
+ private String fileToUploadPath;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -94,12 +118,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
contactName = (TextView) view.findViewById(R.id.contactName);
contactPicture = (AvatarWithShadow) view.findViewById(R.id.contactPicture);
- contactPicture.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- pickImage(); //FIXME: use a specific button instead
- }
- });
ImageView sendMessage = (ImageView) view.findViewById(R.id.sendMessage);
sendMessage.setOnClickListener(this);
@@ -107,13 +125,26 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
messagesLayout = (RelativeLayout) view.findViewById(R.id.messages);
messagesScrollView = (ScrollView) view.findViewById(R.id.chatScrollView);
+ progressBar = (ProgressBar) view.findViewById(R.id.progressbar);
+
+ sendImage = (ImageView) view.findViewById(R.id.sendPicture);
+ registerForContextMenu(sendImage);
+ sendImage.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ pickImage();
+ }
+ });
displayChat(displayName, pictureUri);
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
- if (lc != null)
+ if (lc != null) {
chatRoom = lc.createChatRoom(sipUri);
-
+ }
+
+ uploadServerUri = getActivity().getResources().getString(R.string.upload_url);
+
return view;
}
@@ -198,13 +229,44 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
- menu.add(0, v.getId(), 0, getString(R.string.delete));
+
+ 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));
+ 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));
+ ImageView iv = (ImageView) v.findViewById(R.id.image);
+ if (iv != null && iv.getVisibility() == View.VISIBLE) {
+ menu.add(v.getId(), MENU_SAVE_PICTURE, 0, getString(R.string.save_picture));
+ }
+ }
}
@Override
public boolean onContextItemSelected(MenuItem item) {
- LinphoneActivity.instance().getChatStorage().deleteMessage(item.getItemId());
- invalidate();
+ switch (item.getItemId()) {
+ case MENU_DELETE_MESSAGE:
+ LinphoneActivity.instance().getChatStorage().deleteMessage(item.getGroupId());
+ invalidate();
+ break;
+ case MENU_SAVE_PICTURE:
+ saveImage(item.getGroupId());
+ break;
+ case MENU_PICTURE_SMALL:
+ uploadAndSendImage(fileToUploadPath, ImageSize.SMALL);
+ break;
+ case MENU_PICTURE_MEDIUM:
+ uploadAndSendImage(fileToUploadPath, ImageSize.MEDIUM);
+ break;
+ case MENU_PICTURE_LARGE:
+ uploadAndSendImage(fileToUploadPath, ImageSize.LARGE);
+ break;
+ case MENU_PICTURE_REAL:
+ uploadAndSendImage(fileToUploadPath, ImageSize.REAL);
+ break;
+ }
return true;
}
@@ -231,11 +293,12 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
LinphoneChatMessage chatMessage = chatRoom.createLinphoneChatMessage(messageToSend);
chatRoom.sendMessage(chatMessage, this);
+ int newId = -1;
if (LinphoneActivity.isInstanciated()) {
- LinphoneActivity.instance().onMessageSent(sipUri, messageToSend);
+ newId = LinphoneActivity.instance().onMessageSent(sipUri, messageToSend);
}
- displayMessage(previousMessageID + 2, messageToSend, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout);
+ displayMessage(newId, messageToSend, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout);
scrollToEnd();
}
}
@@ -246,12 +309,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
chatMessage.setExternalBodyUrl(url);
chatRoom.sendMessage(chatMessage, this);
+ int newId = -1;
if (LinphoneActivity.isInstanciated()) {
- LinphoneActivity.instance().onMessageSent(sipUri, bitmap);
+ newId = LinphoneActivity.instance().onMessageSent(sipUri, bitmap, url);
}
+
+ displayImageMessage(newId, bitmap, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout);
+ scrollToEnd();
}
- displayImageMessage(previousMessageID + 2, bitmap, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout);
- scrollToEnd();
}
private void scrollToEnd() {
@@ -263,10 +328,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
}, 100);
}
- @Override
- public void onMessageReceived(LinphoneAddress from, LinphoneChatMessage message) {
+ public void onMessageReceived(int id, LinphoneAddress from, LinphoneChatMessage message) {
if (from.asStringUriOnly().equals(sipUri)) {
- int id = previousMessageID + 2;
if (message.getMessage() != null) {
displayMessage(id, message.getMessage(), String.valueOf(System.currentTimeMillis()), true, null, messagesLayout);
} else if (message.getExternalBodyUrl() != null) {
@@ -280,7 +343,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
@Override
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) {
final String finalMessage = msg.getMessage();
- final Bitmap finalImage = downloadImage(msg.getMessage());
+ final String finalImage = msg.getExternalBodyUrl();
final State finalState = state;
if (LinphoneActivity.isInstanciated() && state != State.InProgress) {
mHandler.post(new Runnable() {
@@ -289,9 +352,11 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
if (finalMessage != null) {
LinphoneActivity.instance().onMessageStateChanged(sipUri, finalMessage, finalState.toInt());
} else if (finalImage != null) {
- LinphoneActivity.instance().onMessageStateChanged(sipUri, finalImage, finalState.toInt());
+ LinphoneActivity.instance().onImageMessageStateChanged(sipUri, finalImage, finalState.toInt());
+ }
+ if (lastSentMessageBubble != null) {
+ lastSentMessageBubble.updateStatusView(finalState);
}
- lastSentMessageBubble.updateStatusView(finalState);
}
});
}
@@ -302,12 +367,26 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
}
private void pickImage() {
- //TODO allow user to take a photo or to choose an existing one
- Intent intent = new Intent();
- intent.setType("image/*");
- intent.setAction(Intent.ACTION_GET_CONTENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- startActivityForResult(intent, ADD_PHOTO);
+ final List cameraIntents = new ArrayList();
+ final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
+ final PackageManager packageManager = getActivity().getPackageManager();
+ final List listCam = packageManager.queryIntentActivities(captureIntent, 0);
+ for(ResolveInfo res : listCam) {
+ final String packageName = res.activityInfo.packageName;
+ 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();
+ galleryIntent.setType("image/*");
+ galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
+
+ final 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 static Bitmap downloadImage(String stringUrl) {
@@ -335,9 +414,29 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
return bm;
}
- private String uploadImage(String filePath, Bitmap file) {
- String upLoadServerUri = getActivity().getResources().getString(R.string.upload_url);
-
+ private void saveImage(int id) {
+ try {
+ byte[] rawImage = LinphoneActivity.instance().getChatStorage().getRawImageFromMessage(id);
+ Bitmap bm = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
+
+ String path = Environment.getExternalStorageDirectory().toString();
+ OutputStream fOut = null;
+ File file = new File(path, getString(R.string.picture_name_format).replace("%s", String.valueOf(id)));
+ fOut = new FileOutputStream(file);
+
+ bm.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
+ fOut.flush();
+ fOut.close();
+
+ Toast.makeText(getActivity(), getString(R.string.image_saved), Toast.LENGTH_SHORT).show();
+ MediaStore.Images.Media.insertImage(getActivity().getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
+ } catch (Exception e) {
+ Toast.makeText(getActivity(), getString(R.string.image_not_saved), Toast.LENGTH_LONG).show();
+ e.printStackTrace();
+ }
+ }
+
+ private String uploadImage(String filePath, Bitmap file, int compressorQuality, final int imageSize) {
File sourceFile = new File(filePath);
if (!sourceFile.isFile()) {
Log.e("Can't read source file " + filePath + ", upload failed");
@@ -352,7 +451,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
String boundary = "---------------------------14737809831466499882746641449";
FileInputStream fileInputStream = new FileInputStream(sourceFile);
- URL url = new URL(upLoadServerUri);
+ URL url = new URL(uploadServerUri);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
@@ -362,14 +461,23 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploaded_file", sourceFile.getName());
- DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
+
+ ProgressOutputStream pos = new ProgressOutputStream(conn.getOutputStream());
+ pos.setListener(new OutputStreamListener() {
+ @Override
+ public void onBytesWrite(int count) {
+ bytesSent += count;
+ progressBar.setProgress(bytesSent * 100 / imageSize);
+ }
+ });
+ DataOutputStream dos = new DataOutputStream(pos);
dos.writeBytes(lineEnd + twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"userfile\"; filename=\""+ sourceFile.getName() + "\"" + lineEnd);
dos.writeBytes("Content-Type: application/octet-stream" + lineEnd);
dos.writeBytes(lineEnd);
- file.compress(CompressFormat.JPEG, 75, dos);
+ file.compress(CompressFormat.JPEG, compressorQuality, dos);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
@@ -411,34 +519,94 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneO
return cursor.getString(column_index);
}
+ private void showPopupMenuAskingImageSize(String filePath) {
+ fileToUploadPath = filePath;
+ getActivity().openContextMenu(sendImage);
+ }
+
+ private void uploadAndSendImage(final String filePath, final ImageSize size) {
+ progressBar.setVisibility(View.VISIBLE);
+ message.setVisibility(View.GONE);
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Bitmap bm = BitmapFactory.decodeFile(filePath);
+ if (bm != null && size != ImageSize.REAL) {
+ int pixelsMax = size == ImageSize.SMALL ? SIZE_SMALL : size == ImageSize.MEDIUM ? SIZE_MEDIUM : SIZE_LARGE;
+ if (bm.getWidth() > bm.getHeight() && bm.getWidth() > pixelsMax) {
+ 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);
+ }
+ }
+ final Bitmap fbm = bm;
+
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ if (bm != null) {
+ bm.compress(CompressFormat.JPEG, COMPRESSOR_QUALITY, outStream);
+ }
+
+ final String url = uploadImage(filePath, bm, COMPRESSOR_QUALITY, outStream.size());
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ progressBar.setVisibility(View.GONE);
+ message.setVisibility(View.VISIBLE);
+ if (url != null) {
+ sendImageMessage(url, fbm);
+ } else {
+ Toast.makeText(getActivity(), getString(R.string.error), Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+ }
+ }).start();
+ }
+
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ADD_PHOTO && resultCode == Activity.RESULT_OK) {
- final String filePath = getRealPathFromURI(data.getData());
- mProgressDialog = ProgressDialog.show(getActivity(), "Please wait", "Long operation starts...", true);
-
- new Thread(new Runnable() {
- @Override
- public void run() {
- Bitmap bm = BitmapFactory.decodeFile(filePath);
- final String url = uploadImage(filePath, bm);
-
- ByteArrayOutputStream outStream = new ByteArrayOutputStream();
- bm.compress(CompressFormat.JPEG, 75, outStream);
- bm.recycle();
- byte[] bitmap = outStream.toByteArray();
- final Bitmap fbm = BitmapFactory.decodeByteArray(bitmap, 0, bitmap.length);
-
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mProgressDialog.dismiss();
- sendImageMessage(url, fbm);
- }
- });
- }
- }).start();
+ final String filePath = getRealPathFromURI(data.getData());
+ showPopupMenuAskingImageSize(filePath);
}
super.onActivityResult(requestCode, resultCode, data);
}
+
+ class ProgressOutputStream extends OutputStream {
+ OutputStream outputStream;
+ private OutputStreamListener listener;
+
+ public ProgressOutputStream(OutputStream stream) {
+ outputStream = stream;
+ }
+
+ public void setListener(OutputStreamListener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public void write(int oneByte) throws IOException {
+ outputStream.write(oneByte);
+ }
+
+ @Override
+ public void write(byte[] buffer, int offset, int count)
+ throws IOException {
+ listener.onBytesWrite(count);
+ outputStream.write(buffer, offset, count);
+ }
+ }
+
+ interface OutputStreamListener {
+ public void onBytesWrite(int count);
+ }
+
+ enum ImageSize {
+ SMALL,
+ MEDIUM,
+ LARGE,
+ REAL;
+ }
}
diff --git a/src/org/linphone/ChatMessage.java b/src/org/linphone/ChatMessage.java
index b089ca3b4..081784ef9 100644
--- a/src/org/linphone/ChatMessage.java
+++ b/src/org/linphone/ChatMessage.java
@@ -41,7 +41,7 @@ public class ChatMessage {
this.timestamp = timestamp;
this.incoming = incoming;
this.status = status;
- this.image = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
+ this.image = rawImage != null ? BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length) : null;
}
public int getId() {
diff --git a/src/org/linphone/ChatStorage.java b/src/org/linphone/ChatStorage.java
index d6e856b88..e70edf505 100644
--- a/src/org/linphone/ChatStorage.java
+++ b/src/org/linphone/ChatStorage.java
@@ -130,6 +130,7 @@ public class ChatStorage {
ChatMessage chatMessage = new ChatMessage(id, message, rawImage, timestamp, direction == INCOMING, status);
chatMessages.add(chatMessage);
}
+ c.close();
return chatMessages;
}
@@ -146,6 +147,7 @@ public class ChatStorage {
String remoteContact = c.getString(c.getColumnIndex("remoteContact"));
chatList.add(remoteContact);
}
+ c.close();
return chatList;
}
@@ -166,7 +168,7 @@ public class ChatStorage {
class ChatHelper extends SQLiteOpenHelper {
- private static final int DATABASE_VERSION = 4;
+ private static final int DATABASE_VERSION = 9;
private static final String DATABASE_NAME = "linphone-android";
ChatHelper(Context context) {
@@ -184,4 +186,17 @@ public class ChatStorage {
onCreate(db);
}
}
+
+ public byte[] getRawImageFromMessage(int id) {
+ String[] columns = { "image" };
+ Cursor c = db.query(TABLE_NAME, columns, "id LIKE " + id + "", null, null, null, null);
+
+ if (c.moveToFirst()) {
+ byte[] rawImage = c.getBlob(c.getColumnIndex("image"));
+ c.close();
+ return rawImage;
+ }
+
+ return null;
+ }
}
\ No newline at end of file
diff --git a/src/org/linphone/ContactFragment.java b/src/org/linphone/ContactFragment.java
index cd7cfb7a0..515522ba8 100644
--- a/src/org/linphone/ContactFragment.java
+++ b/src/org/linphone/ContactFragment.java
@@ -39,7 +39,7 @@ import android.widget.TextView;
*/
public class ContactFragment extends Fragment implements OnClickListener {
private Contact contact;
- private ImageView back, editContact, newContact;
+ private ImageView editContact, newContact;
private LayoutInflater inflater;
private View view;
@@ -64,8 +64,6 @@ public class ContactFragment extends Fragment implements OnClickListener {
this.inflater = inflater;
view = inflater.inflate(R.layout.contact, container, false);
- back = (ImageView) view.findViewById(R.id.back);
- back.setOnClickListener(this);
editContact = (ImageView) view.findViewById(R.id.editContact);
editContact.setOnClickListener(this);
newContact = (ImageView) view.findViewById(R.id.newContact);
@@ -133,10 +131,6 @@ public class ContactFragment extends Fragment implements OnClickListener {
Intent intent;
switch (id) {
- case R.id.back:
- LinphoneActivity.instance().onBackPressed();
- break;
-
case R.id.editContact:
intent = Compatibility.prepareEditContactIntent(Integer.parseInt(contact.getID()));
startActivity(intent);
diff --git a/src/org/linphone/HistoryFragment.java b/src/org/linphone/HistoryFragment.java
index 2d2baf0bc..dfa546359 100644
--- a/src/org/linphone/HistoryFragment.java
+++ b/src/org/linphone/HistoryFragment.java
@@ -53,7 +53,7 @@ public class HistoryFragment extends Fragment implements OnClickListener, OnChil
private Handler mHandler = new Handler();
private ExpandableListView historyList;
private LayoutInflater mInflater;
- private ImageView allCalls, missedCalls, edit, ok;
+ private ImageView allCalls, missedCalls, edit, ok, deleteAll;
private boolean onlyDisplayMissedCalls, isEditMode;
private SparseArray> mLogs;
@@ -67,14 +67,22 @@ public class HistoryFragment extends Fragment implements OnClickListener, OnChil
historyList.setOnChildClickListener(this);
historyList.setOnGroupClickListener(this);
+ deleteAll = (ImageView) view.findViewById(R.id.deleteAll);
+ deleteAll.setOnClickListener(this);
+ deleteAll.setEnabled(false);
+
allCalls = (ImageView) view.findViewById(R.id.allCalls);
allCalls.setOnClickListener(this);
+
missedCalls = (ImageView) view.findViewById(R.id.missedCalls);
missedCalls.setOnClickListener(this);
+
allCalls.setEnabled(false);
onlyDisplayMissedCalls = false;
+
edit = (ImageView) view.findViewById(R.id.edit);
edit.setOnClickListener(this);
+
ok = (ImageView) view.findViewById(R.id.ok);
ok.setOnClickListener(this);
@@ -187,13 +195,18 @@ public class HistoryFragment extends Fragment implements OnClickListener, OnChil
else if (id == R.id.ok) {
edit.setVisibility(View.VISIBLE);
ok.setVisibility(View.GONE);
+ deleteAll.setEnabled(false);
isEditMode = false;
}
else if (id == R.id.edit) {
edit.setVisibility(View.GONE);
ok.setVisibility(View.VISIBLE);
+ deleteAll.setEnabled(true);
isEditMode = true;
}
+ else if (id == R.id.deleteAll) {
+ LinphoneManager.getLc().clearCallLogs();
+ }
historyList.setAdapter(new CallHistoryAdapter(getActivity()));
expandAllGroups();
diff --git a/src/org/linphone/HistorySimpleFragment.java b/src/org/linphone/HistorySimpleFragment.java
index 25d631746..603f949b4 100644
--- a/src/org/linphone/HistorySimpleFragment.java
+++ b/src/org/linphone/HistorySimpleFragment.java
@@ -52,7 +52,7 @@ import android.widget.TextView;
public class HistorySimpleFragment extends Fragment implements OnClickListener, OnItemClickListener {
private ListView historyList;
private LayoutInflater mInflater;
- private ImageView allCalls, missedCalls, edit, ok;
+ private ImageView allCalls, missedCalls, edit, ok, deleteAll;
private boolean onlyDisplayMissedCalls, isEditMode;
private List mLogs;
@@ -66,14 +66,22 @@ public class HistorySimpleFragment extends Fragment implements OnClickListener,
historyList.setOnItemClickListener(this);
registerForContextMenu(historyList);
+ deleteAll = (ImageView) view.findViewById(R.id.deleteAll);
+ deleteAll.setOnClickListener(this);
+ deleteAll.setEnabled(false);
+
allCalls = (ImageView) view.findViewById(R.id.allCalls);
allCalls.setOnClickListener(this);
+
missedCalls = (ImageView) view.findViewById(R.id.missedCalls);
missedCalls.setOnClickListener(this);
+
allCalls.setEnabled(false);
onlyDisplayMissedCalls = false;
+
edit = (ImageView) view.findViewById(R.id.edit);
edit.setOnClickListener(this);
+
ok = (ImageView) view.findViewById(R.id.ok);
ok.setOnClickListener(this);
@@ -125,13 +133,18 @@ public class HistorySimpleFragment extends Fragment implements OnClickListener,
else if (id == R.id.ok) {
edit.setVisibility(View.VISIBLE);
ok.setVisibility(View.GONE);
+ deleteAll.setEnabled(false);
isEditMode = false;
}
else if (id == R.id.edit) {
edit.setVisibility(View.GONE);
ok.setVisibility(View.VISIBLE);
+ deleteAll.setEnabled(true);
isEditMode = true;
}
+ else if (id == R.id.deleteAll) {
+ LinphoneManager.getLc().clearCallLogs();
+ }
historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
}
diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java
index d390fd2b9..a7db3db37 100644
--- a/src/org/linphone/LinphoneActivity.java
+++ b/src/org/linphone/LinphoneActivity.java
@@ -611,7 +611,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
ChatFragment chatFragment = ((ChatFragment) messageListenerFragment);
if (messageListenerFragment != null && messageListenerFragment.isVisible() && chatFragment.getSipUri().equals(from.asStringUriOnly())) {
- chatFragment.onMessageReceived(from, message);
+ chatFragment.onMessageReceived(id, from, message);
getChatStorage().markMessageAsRead(id);
} else if (LinphoneService.isReady()) {
displayMissedChats(getChatStorage().getUnreadMessageCount());
@@ -624,19 +624,19 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
displayMissedChats(getChatStorage().getUnreadMessageCount());
}
- public void onMessageSent(String to, String message) {
- getChatStorage().saveMessage("", to, message);
+ public int onMessageSent(String to, String message) {
+ return getChatStorage().saveMessage("", to, message);
}
- public void onMessageSent(String to, Bitmap image) {
- getChatStorage().saveMessage("", to, image);
+ public int onMessageSent(String to, Bitmap image, String imageURL) {
+ return getChatStorage().saveMessage("", to, image);
}
public void onMessageStateChanged(String to, String message, int newState) {
getChatStorage().updateMessageStatus(to, message, newState);
}
- public void onMessageStateChanged(String to, Bitmap image, int newState) {
+ public void onImageMessageStateChanged(String to, String image, int newState) {
getChatStorage().updateMessageStatus(to, image, newState);
}
diff --git a/src/org/linphone/ui/BubbleChat.java b/src/org/linphone/ui/BubbleChat.java
index 5714ca346..85724e7ce 100644
--- a/src/org/linphone/ui/BubbleChat.java
+++ b/src/org/linphone/ui/BubbleChat.java
@@ -133,11 +133,15 @@ public class BubbleChat {
if (message != null && msgView != null) {
msgView.setText(text);
msgView.setMovementMethod(LinkMovementMethod.getInstance());
+ } else if (msgView != null) {
+ msgView.setVisibility(View.GONE);
}
ImageView imageView = (ImageView) layout.findViewById(R.id.image);
if (image != null && imageView != null) {
imageView.setImageBitmap(image);
+ } else if (imageView != null) {
+ imageView.setVisibility(View.GONE);
}
TextView timeView = (TextView) layout.findViewById(R.id.time);
@@ -146,11 +150,11 @@ public class BubbleChat {
statusView = (ImageView) layout.findViewById(R.id.status);
if (statusView != null) {
if (status == LinphoneChatMessage.State.Delivered) {
- statusView.setImageResource(R.drawable.led_connected); //FIXME
+ statusView.setImageResource(R.drawable.chat_message_delivered);
} else if (status == LinphoneChatMessage.State.NotDelivered) {
- statusView.setImageResource(R.drawable.led_error); //FIXME
+ statusView.setImageResource(R.drawable.chat_message_not_delivered);
} else {
- statusView.setImageResource(R.drawable.led_inprogress); //FIXME
+ statusView.setImageResource(R.drawable.chat_message_delivered);
}
}
@@ -174,11 +178,11 @@ public class BubbleChat {
}
if (status == LinphoneChatMessage.State.Delivered) {
- statusView.setImageResource(R.drawable.led_connected); //FIXME
+ statusView.setImageResource(R.drawable.chat_message_delivered);
} else if (status == LinphoneChatMessage.State.NotDelivered) {
- statusView.setImageResource(R.drawable.led_error); //FIXME
+ statusView.setImageResource(R.drawable.chat_message_not_delivered);
} else {
- statusView.setImageResource(R.drawable.led_inprogress); //FIXME
+ statusView.setImageResource(R.drawable.chat_message_inprogress);
}
view.invalidate();
}