diff --git a/res/drawable/item_history_selector.xml b/res/drawable/item_history_selector.xml index 3f8e34a2271ffa3a3f39533b49cfecd0c6a2ccd8..a211cff4d2990bf289ac1230f086fdc80b87b5c2 100644 --- a/res/drawable/item_history_selector.xml +++ b/res/drawable/item_history_selector.xml @@ -2,14 +2,14 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"><shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="@color/darker_gray" /> + <solid android:color="@color/transparent_grey" /> <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" /> <corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" /> </shape></item> <item android:state_focused="true"><shape xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="@color/light" /> + <solid android:color="@color/transparent_grey" /> <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" /> diff --git a/res/layout/frag_history.xml b/res/layout/frag_history.xml index f0a0a98dbb5a088ed53cc1bcfb0b4ec0b0a8c000..228c47e980f878146fe2117da141c5bd99506f19 100644 --- a/res/layout/frag_history.xml +++ b/res/layout/frag_history.xml @@ -11,6 +11,8 @@ android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="10dp" + android:dividerHeight="3dp" + android:divider="@null" android:clickable="true" /> <TextView diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 4e10f9e99e095325b6287d7e0d261e02d095b60c..f498ce8abad8139bebdf399b86bc8e639871001d 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -57,7 +57,6 @@ as that of the covered work. <string name="drawer_close">Fermer le tiroir de navigation</string> <!-- Categories --> - <string name="frag_menu_accounts_title">Comptes</string> <string name="menu_category_settings">Paramètres</string> <string name="menu_category_help">Aide</string> @@ -102,6 +101,10 @@ as that of the covered work. <!-- FileExplorerDFragement --> <string name="file_explorer_title">Sélectionner un fichier</string> + <!-- Notifications --> + <string name="notif_missed_call_title">Appel manqué</string> + <string name="notif_missed_call_content">From %1$s</string> + <!-- Call Fragment --> <string name="me">Moi</string> <string name="action_call_attended_transfer">Transfert</string> diff --git a/res/values/strings.xml b/res/values/strings.xml index 8916251c75c4d2380ca8b9d49d964e7fbad86e91..0dc897531f7d6989de20d09172f7c595207f6aeb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -65,7 +65,7 @@ as that of the covered work. <string name="menu_item_settings">Settings</string> <string name="menu_item_settings_interface">Interface</string> - <!-- Dialing Fragmennt --> + <!-- Dialing Fragment --> <string name="dial_action_call">Call</string> <string name="dial_error_no_number_dialed">Dial a number</string> <string name="dial_hint">Type phone number</string> @@ -100,9 +100,10 @@ as that of the covered work. <string name="transfer_to_another_call">Transfer to another current call:</string> <string name="transfer_no_other_call">No other calls pending</string> <string name="transfer_type_number">Type number to transfer to:</string> - - <!-- Menu Fragment --> - <string name="frag_menu_accounts_title">Accounts</string> + + <!-- Notifications --> + <string name="notif_missed_call_title">Missed call</string> + <string name="notif_missed_call_content">De %1$s</string> <!-- Call Fragment --> <string name="me">Me</string> diff --git a/src/org/sflphone/client/AccountsManagementActivity.java b/src/org/sflphone/client/AccountsManagementActivity.java index abc59145d89345da279969f617c1fad21394f1e9..b5f6405507e9e5f92aaffb6908923e641794cec4 100644 --- a/src/org/sflphone/client/AccountsManagementActivity.java +++ b/src/org/sflphone/client/AccountsManagementActivity.java @@ -106,9 +106,6 @@ public class AccountsManagementActivity extends Activity implements AccountsMana unbindService(mConnection); mBound = false; } - - // stopService(new Intent(this, SipService.class)); - // serviceIsOn = false; super.onDestroy(); } diff --git a/src/org/sflphone/receivers/IncomingReceiver.java b/src/org/sflphone/receivers/IncomingReceiver.java index 9efc305133738835a70933fc011a4ef92bd8c009..92af380848b189624e13de8600386dffb879ad65 100644 --- a/src/org/sflphone/receivers/IncomingReceiver.java +++ b/src/org/sflphone/receivers/IncomingReceiver.java @@ -1,3 +1,33 @@ +/* + * Copyright (C) 2004-2013 Savoir-Faire Linux Inc. + * + * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ package org.sflphone.receivers; import java.util.ArrayList; @@ -153,8 +183,11 @@ public class IncomingReceiver extends BroadcastReceiver { } } else if (newState.equals("HUNGUP")) { - // Log.e(TAG, "HUNGUP call:" + b.getString("CallID")); + if (callback.getCurrent_calls().get(b.getString("CallID")) != null) { + + if(callback.getCurrent_calls().get(b.getString("CallID")).isRinging()) + callback.notificationManager.publishMissedCallNotification(callback.getCurrent_calls().get(b.getString("CallID"))); callback.getCurrent_calls().remove(b.getString("CallID")); } else { ArrayList<Conference> it = new ArrayList<Conference>(callback.getCurrent_confs().values()); diff --git a/src/org/sflphone/utils/SipNotifications.java b/src/org/sflphone/utils/SipNotifications.java index 73f31e2b533d844c9231df1961352015c2c351c2..7ec35e413573c72dea1e2cbe4dd04314af5439db 100644 --- a/src/org/sflphone/utils/SipNotifications.java +++ b/src/org/sflphone/utils/SipNotifications.java @@ -33,27 +33,29 @@ package org.sflphone.utils; - import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.sflphone.R; +import org.sflphone.client.HomeActivity; import org.sflphone.model.SipCall; import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.ContentValues; import android.content.Context; +import android.content.Intent; +import android.graphics.BitmapFactory; import android.graphics.Typeface; import android.net.sip.SipProfile; +import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.StyleSpan; import android.util.Log; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; public class SipNotifications { @@ -64,7 +66,7 @@ public class SipNotifications { private Builder messageNotification; private Builder messageVoicemail; private boolean resolveContacts = true; - + public static final String NOTIF_CREATION = "notif_creation"; public static final String NOTIF_DELETION = "notif_deletion"; @@ -85,49 +87,8 @@ public class SipNotifications { cancelCalls(); isInit = true; } - - if( ! Compatibility.isCompatible(9) ) { - searchNotificationPrimaryText(aContext); - } - } - - private Integer notificationPrimaryTextColor = null; - private static String TO_SEARCH = "Search"; - // Retrieve notification textColor with android < 2.3 - @SuppressWarnings("deprecation") - private void searchNotificationPrimaryText(Context aContext) { - try { - Notification ntf = new Notification(); - ntf.setLatestEventInfo(aContext, TO_SEARCH, "", null); - LinearLayout group = new LinearLayout(aContext); - ViewGroup event = (ViewGroup) ntf.contentView.apply(aContext, group); - recurseSearchNotificationPrimaryText(event); - group.removeAllViews(); - } catch (Exception e) { - Log.e(THIS_FILE, "Can't retrieve the color", e); - } - } - - private boolean recurseSearchNotificationPrimaryText(ViewGroup gp) { - final int count = gp.getChildCount(); - for (int i = 0; i < count; ++i) { - if (gp.getChildAt(i) instanceof TextView){ - final TextView text = (TextView) gp.getChildAt(i); - final String szText = text.getText().toString(); - if (TO_SEARCH.equals(szText)) { - notificationPrimaryTextColor = text.getTextColors().getDefaultColor(); - return true; - } - } else if (gp.getChildAt(i) instanceof ViewGroup) { - if(recurseSearchNotificationPrimaryText((ViewGroup) gp.getChildAt(i))) { - return true; - } - } - } - return false; } - // Foreground api @@ -156,8 +117,7 @@ public class SipNotifications { } /** - * This is a wrapper around the new startForeground method, using the older - * APIs if it is not available. + * This is a wrapper around the new startForeground method, using the older APIs if it is not available. */ private void startForegroundCompat(int id, Notification notification) { // If we have the new startForeground API, then use it. @@ -175,8 +135,7 @@ public class SipNotifications { } /** - * This is a wrapper around the new stopForeground method, using the older - * APIs if it is not available. + * This is a wrapper around the new stopForeground method, using the older APIs if it is not available. */ private void stopForegroundCompat(int id) { // If we have the new stopForeground API, then use it. @@ -221,83 +180,82 @@ public class SipNotifications { // Announces -// // Register -// public synchronized void notifyRegisteredAccounts(ArrayList<SipProfileState> activeAccountsInfos, boolean showNumbers) { -// if (!isServiceWrapper) { -// Log.e(THIS_FILE, "Trying to create a service notification from outside the service"); -// return; -// } -// int icon = R.drawable.ic_stat_sipok; -// CharSequence tickerText = context.getString(R.string.service_ticker_registered_text); -// long when = System.currentTimeMillis(); -// -// -// Builder nb = new NotificationCompat.Builder(context); -// nb.setSmallIcon(icon); -// nb.setTicker(tickerText); -// nb.setWhen(when); -// Intent notificationIntent = new Intent(SipManager.ACTION_SIP_DIALER); -// notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); -// PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); -// -// RegistrationNotification contentView = new RegistrationNotification(context.getPackageName()); -// contentView.clearRegistrations(); -// if(!Compatibility.isCompatible(9)) { -// contentView.setTextsColor(notificationPrimaryTextColor); -// } -// contentView.addAccountInfos(context, activeAccountsInfos); -// -// // notification.setLatestEventInfo(context, contentTitle, -// // contentText, contentIntent); -// nb.setOngoing(true); -// nb.setOnlyAlertOnce(true); -// nb.setContentIntent(contentIntent); -// nb.setContent(contentView); -// -// Notification notification = nb.build(); -// notification.flags |= Notification.FLAG_NO_CLEAR; -// // We have to re-write content view because getNotification setLatestEventInfo implicitly -// notification.contentView = contentView; -// if (showNumbers) { -// // This only affects android 2.3 and lower -// notification.number = activeAccountsInfos.size(); -// } -// startForegroundCompat(REGISTER_NOTIF_ID, notification); -// } - + // // Register + // public synchronized void notifyRegisteredAccounts(ArrayList<SipProfileState> activeAccountsInfos, boolean showNumbers) { + // if (!isServiceWrapper) { + // Log.e(THIS_FILE, "Trying to create a service notification from outside the service"); + // return; + // } + // int icon = R.drawable.ic_stat_sipok; + // CharSequence tickerText = context.getString(R.string.service_ticker_registered_text); + // long when = System.currentTimeMillis(); + // + // + // Builder nb = new NotificationCompat.Builder(context); + // nb.setSmallIcon(icon); + // nb.setTicker(tickerText); + // nb.setWhen(when); + // Intent notificationIntent = new Intent(SipManager.ACTION_SIP_DIALER); + // notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + // + // RegistrationNotification contentView = new RegistrationNotification(context.getPackageName()); + // contentView.clearRegistrations(); + // if(!Compatibility.isCompatible(9)) { + // contentView.setTextsColor(notificationPrimaryTextColor); + // } + // contentView.addAccountInfos(context, activeAccountsInfos); + // + // // notification.setLatestEventInfo(context, contentTitle, + // // contentText, contentIntent); + // nb.setOngoing(true); + // nb.setOnlyAlertOnce(true); + // nb.setContentIntent(contentIntent); + // nb.setContent(contentView); + // + // Notification notification = nb.build(); + // notification.flags |= Notification.FLAG_NO_CLEAR; + // // We have to re-write content view because getNotification setLatestEventInfo implicitly + // notification.contentView = contentView; + // if (showNumbers) { + // // This only affects android 2.3 and lower + // notification.number = activeAccountsInfos.size(); + // } + // startForegroundCompat(REGISTER_NOTIF_ID, notification); + // } + /** * Format the remote contact name for the call info - * @param callInfo the callinfo to format + * + * @param callInfo + * the callinfo to format * @return the name to display for the contact */ private String formatRemoteContactString(String remoteContact) { String formattedRemoteContact = remoteContact; - //TODO + // TODO return formattedRemoteContact; } - + /** * Format the notification title for a call info + * * @param title * @param callInfo * @return */ private String formatNotificationTitle(int title, long accId) { - //TODO + // TODO return null; } // Calls public void showNotificationForCall(SipCall callInfo) { - //TODO - } - - public void showNotificationForMissedCall(ContentValues callLog) { - //TODO + // TODO } public void showNotificationForVoiceMail(SipProfile acc, int numberOfMessages) { - //TODO + // TODO } private static String viewingRemoteFrom = null; @@ -361,4 +319,33 @@ public class SipNotifications { cancelVoicemails(); } + public void publishMissedCallNotification(SipCall sipCall) { + + CharSequence tickerText = context.getString(R.string.notif_missed_call_title); + long when = System.currentTimeMillis(); + + Builder nb = new NotificationCompat.Builder(context); + nb.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher)); + nb.setSmallIcon(R.drawable.ic_action_call); + + nb.setTicker(tickerText); + nb.setWhen(when); + nb.setContentTitle(context.getString(R.string.notif_missed_call_title)); + nb.setContentText(context.getString(R.string.notif_missed_call_content, sipCall.getContact().getmDisplayName())); + Intent notificationIntent = new Intent(context, HomeActivity.class); + notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + // notification.setLatestEventInfo(context, contentTitle, + // contentText, contentIntent); + nb.setOnlyAlertOnce(true); + nb.setContentIntent(contentIntent); + + Notification notification = nb.build(); + // We have to re-write content view because getNotification setLatestEventInfo implicitly + // notification.contentView = contentView; + + // startForegroundCompat(CALL_NOTIF_ID, notification); + notificationManager.notify(CALL_NOTIF_ID, notification); + } } \ No newline at end of file