mirror of
				https://github.com/pierre42100/ComunicAndroid
				synced 2025-10-31 01:24:43 +00:00 
			
		
		
		
	Display a notification when a new call is available.
This commit is contained in:
		| @@ -76,6 +76,14 @@ | |||||||
|             android:name=".ui.activities.CallActivity" |             android:name=".ui.activities.CallActivity" | ||||||
|             android:label="@string/activity_call_label"/> |             android:label="@string/activity_call_label"/> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         <!-- New calls available receiver --> | ||||||
|  |         <receiver android:name=".ui.receivers.PendingCallsBroadcastReceiver" android:exported="false"> | ||||||
|  |             <intent-filter> | ||||||
|  |                 <action android:name="org.communiquons.android.comunic.client.NEW_CALLS_AVAILABLE" /> | ||||||
|  |             </intent-filter> | ||||||
|  |         </receiver> | ||||||
|  |  | ||||||
|     </application> |     </application> | ||||||
|  |  | ||||||
| </manifest> | </manifest> | ||||||
| @@ -1,6 +1,7 @@ | |||||||
| package org.communiquons.android.comunic.client.data.helpers; | package org.communiquons.android.comunic.client.data.helpers; | ||||||
|  |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
|  | import android.support.annotation.NonNull; | ||||||
| import android.support.annotation.Nullable; | import android.support.annotation.Nullable; | ||||||
|  |  | ||||||
| import org.communiquons.android.comunic.client.data.enums.MemberCallStatus; | import org.communiquons.android.comunic.client.data.enums.MemberCallStatus; | ||||||
| @@ -9,6 +10,7 @@ import org.communiquons.android.comunic.client.data.models.APIResponse; | |||||||
| import org.communiquons.android.comunic.client.data.models.CallInformation; | import org.communiquons.android.comunic.client.data.models.CallInformation; | ||||||
| import org.communiquons.android.comunic.client.data.models.CallMember; | import org.communiquons.android.comunic.client.data.models.CallMember; | ||||||
| import org.communiquons.android.comunic.client.data.models.CallsConfiguration; | import org.communiquons.android.comunic.client.data.models.CallsConfiguration; | ||||||
|  | import org.communiquons.android.comunic.client.data.models.NextPendingCallInformation; | ||||||
| import org.json.JSONArray; | import org.json.JSONArray; | ||||||
| import org.json.JSONException; | import org.json.JSONException; | ||||||
| import org.json.JSONObject; | import org.json.JSONObject; | ||||||
| @@ -106,7 +108,7 @@ public class CallsHelper extends BaseHelper { | |||||||
|             //Execute request |             //Execute request | ||||||
|             APIResponse response = request.exec(); |             APIResponse response = request.exec(); | ||||||
|  |  | ||||||
|             return JSONObjectToCallInformation(response.getJSONObject()); |             return JSONObjectToCallInformation(response.getJSONObject(), null); | ||||||
|  |  | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
| @@ -115,6 +117,60 @@ public class CallsHelper extends BaseHelper { | |||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the next pending call for a user | ||||||
|  |      * | ||||||
|  |      * @return Next pending call for a user | ||||||
|  |      */ | ||||||
|  |     @Nullable | ||||||
|  |     public NextPendingCallInformation getNextPendingCall(){ | ||||||
|  |  | ||||||
|  |         APIRequest request = new APIRequest(getContext(), "calls/nextPending"); | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             JSONObject object = request.exec().getJSONObject(); | ||||||
|  |  | ||||||
|  |             //Check if there is no pending call available | ||||||
|  |             NextPendingCallInformation call = new NextPendingCallInformation(); | ||||||
|  |             if(object.has("notice")){ | ||||||
|  |                 call.setHasPendingCall(false); | ||||||
|  |                 return call; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             call.setHasPendingCall(true); | ||||||
|  |             JSONObjectToCallInformation(object, call); | ||||||
|  |             return call; | ||||||
|  |  | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Try to get and return call information | ||||||
|  |      * | ||||||
|  |      * @param call Target call information | ||||||
|  |      * @return The name of call / null in case of failure | ||||||
|  |      */ | ||||||
|  |     @Nullable | ||||||
|  |     public String getCallName(@NonNull CallInformation call){ | ||||||
|  |  | ||||||
|  |         //Get call name | ||||||
|  |         String name = new ConversationsListHelper(getContext()) | ||||||
|  |                 .getConversationName(call.getConversationID()); | ||||||
|  |  | ||||||
|  |         if(name == null) | ||||||
|  |             return null; | ||||||
|  |  | ||||||
|  |         call.setCallName(name); | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Turn a {@link JSONObject} object into a {@link CallsConfiguration} object. |      * Turn a {@link JSONObject} object into a {@link CallsConfiguration} object. | ||||||
| @@ -149,13 +205,18 @@ public class CallsHelper extends BaseHelper { | |||||||
|      * Turn a {@link JSONObject} into {@link CallInformation} object |      * Turn a {@link JSONObject} into {@link CallInformation} object | ||||||
|      * |      * | ||||||
|      * @param object object to convert |      * @param object object to convert | ||||||
|  |      * @param call Call object to fill (null = none) | ||||||
|      * @return Generated CallInformation object |      * @return Generated CallInformation object | ||||||
|      * @throws JSONException in case of failure |      * @throws JSONException in case of failure | ||||||
|      */ |      */ | ||||||
|     private static CallInformation JSONObjectToCallInformation(JSONObject object) |     private static CallInformation JSONObjectToCallInformation(JSONObject object, | ||||||
|  |                                                                @Nullable CallInformation call) | ||||||
|             throws JSONException { |             throws JSONException { | ||||||
|  |  | ||||||
|         CallInformation call = new CallInformation(); |         //Check if object has to be instanced | ||||||
|  |         if(call == null) | ||||||
|  |             call = new CallInformation(); | ||||||
|  |  | ||||||
|         call.setId(object.getInt("id")); |         call.setId(object.getInt("id")); | ||||||
|         call.setConversationID(object.getInt("conversation_id")); |         call.setConversationID(object.getInt("conversation_id")); | ||||||
|         call.setLastActive(object.getInt("last_active")); |         call.setLastActive(object.getInt("last_active")); | ||||||
|   | |||||||
| @@ -56,6 +56,15 @@ public class ConversationsListHelper { | |||||||
|         this.dbHelper = dbHelper; |         this.dbHelper = dbHelper; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The constructor of the class | ||||||
|  |      * | ||||||
|  |      * @param context The context of execution of the application | ||||||
|  |      */ | ||||||
|  |     public ConversationsListHelper(Context context){ | ||||||
|  |         this(context, DatabaseHelper.getInstance(context)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the list of conversation or null in case of failure |      * Get the list of conversation or null in case of failure | ||||||
|      * |      * | ||||||
| @@ -147,17 +156,17 @@ public class ConversationsListHelper { | |||||||
|     /** |     /** | ||||||
|      * Get the display name of a conversation |      * Get the display name of a conversation | ||||||
|      * |      * | ||||||
|      * @param infos Informations about a conversation |      * @param info Information about a conversation | ||||||
|      * @return The name of the conversation |      * @return The name of the conversation | ||||||
|      */ |      */ | ||||||
|     public String getDisplayName(ConversationsInfo infos){ |     public String getDisplayName(ConversationsInfo info){ | ||||||
|  |  | ||||||
|         //Check if a specific name has been specified |         //Check if a specific name has been specified | ||||||
|         if(infos.hasName()) |         if(info.hasName()) | ||||||
|             return infos.getName(); |             return info.getName(); | ||||||
|  |  | ||||||
|         //Get the list of members of the conversation |         //Get the list of members of the conversation | ||||||
|         ArrayList<Integer> members = infos.getMembers(); |         ArrayList<Integer> members = info.getMembers(); | ||||||
|  |  | ||||||
|         //Get the ID of the three first members |         //Get the ID of the three first members | ||||||
|         ArrayList<Integer> membersToGet = new ArrayList<>(); |         ArrayList<Integer> membersToGet = new ArrayList<>(); | ||||||
| @@ -203,6 +212,24 @@ public class ConversationsListHelper { | |||||||
|         return name; |         return name; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the name of a conversation specified by its ID | ||||||
|  |      * | ||||||
|  |      * @param convID The ID of the target conversation | ||||||
|  |      * @return The name of the conversation / null in case of failure | ||||||
|  |      */ | ||||||
|  |     @Nullable | ||||||
|  |     public String getConversationName(int convID){ | ||||||
|  |  | ||||||
|  |         ConversationsInfo info = getInfosSingle(convID, true); | ||||||
|  |  | ||||||
|  |         if(info == null) | ||||||
|  |             return null; | ||||||
|  |  | ||||||
|  |         return getDisplayName(info); | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Delete a conversation specified by its ID |      * Delete a conversation specified by its ID | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -18,6 +18,9 @@ public class CallInformation { | |||||||
|     private ArrayList<CallMember> members = null; |     private ArrayList<CallMember> members = null; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     private String callName = null; | ||||||
|  |  | ||||||
|  |  | ||||||
|     public int getId() { |     public int getId() { | ||||||
|         return id; |         return id; | ||||||
|     } |     } | ||||||
| @@ -54,7 +57,29 @@ public class CallInformation { | |||||||
|         members.add(member); |         members.add(member); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Check out whether all the members of the call left it or not except a specific user | ||||||
|  |      * | ||||||
|  |      * @return TRUE if all members except specified user ID left the call / FALSE else | ||||||
|  |      */ | ||||||
|  |     public boolean hasAllMembersLeftCallExcept(int userID){ | ||||||
|  |  | ||||||
|  |         for(CallMember member : members) | ||||||
|  |             if(!member.leftCall() && member.getUserID() != userID) | ||||||
|  |                 return false; | ||||||
|  |  | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public void setMembers(ArrayList<CallMember> members) { |     public void setMembers(ArrayList<CallMember> members) { | ||||||
|         this.members = members; |         this.members = members; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public String getCallName() { | ||||||
|  |         return callName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setCallName(String callName) { | ||||||
|  |         this.callName = callName; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -56,4 +56,13 @@ public class CallMember { | |||||||
|     public void setStatus(MemberCallStatus status) { |     public void setStatus(MemberCallStatus status) { | ||||||
|         this.status = status; |         this.status = status; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Check out whether the member left the call or not | ||||||
|  |      * | ||||||
|  |      * @return TRUE if the user is considered as out of the conversation | ||||||
|  |      */ | ||||||
|  |     public boolean leftCall(){ | ||||||
|  |         return status == MemberCallStatus.HANG_UP || status == MemberCallStatus.REJECTED; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | package org.communiquons.android.comunic.client.data.models; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Pending call information object | ||||||
|  |  * | ||||||
|  |  * @author Pierre HUBERT | ||||||
|  |  */ | ||||||
|  | public class NextPendingCallInformation extends CallInformation { | ||||||
|  |  | ||||||
|  |     //Private fields | ||||||
|  |     private boolean hasPendingCall; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     public boolean isHasPendingCall() { | ||||||
|  |         return hasPendingCall; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setHasPendingCall(boolean hasPendingCall) { | ||||||
|  |         this.hasPendingCall = hasPendingCall; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| package org.communiquons.android.comunic.client.data.models; | package org.communiquons.android.comunic.client.data.models; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Notifications count service |  * Notifications count class | ||||||
|  * |  * | ||||||
|  * @author Pierre HUBERT |  * @author Pierre HUBERT | ||||||
|  * Created by pierre on 4/9/18. |  * Created by pierre on 4/9/18. | ||||||
| @@ -13,7 +13,7 @@ public class NotificationsCount { | |||||||
|     private int notificationsCount; |     private int notificationsCount; | ||||||
|     private int conversationsCount; |     private int conversationsCount; | ||||||
|     private int friendsRequestsCount; |     private int friendsRequestsCount; | ||||||
|     private int pendingCalls; |     private int pendingCalls = -1; | ||||||
|  |  | ||||||
|  |  | ||||||
|     //Set and get notifications count |     //Set and get notifications count | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import android.app.NotificationChannel; | |||||||
| import android.app.NotificationManager; | import android.app.NotificationManager; | ||||||
| import android.app.PendingIntent; | import android.app.PendingIntent; | ||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
|  | import android.content.IntentFilter; | ||||||
| import android.os.Build; | import android.os.Build; | ||||||
| import android.support.annotation.Nullable; | import android.support.annotation.Nullable; | ||||||
| import android.support.v4.app.NotificationCompat; | import android.support.v4.app.NotificationCompat; | ||||||
| @@ -15,14 +16,15 @@ import android.util.Log; | |||||||
| import org.communiquons.android.comunic.client.R; | import org.communiquons.android.comunic.client.R; | ||||||
| import org.communiquons.android.comunic.client.data.helpers.AccountHelper; | import org.communiquons.android.comunic.client.data.helpers.AccountHelper; | ||||||
| import org.communiquons.android.comunic.client.data.helpers.CallsHelper; | import org.communiquons.android.comunic.client.data.helpers.CallsHelper; | ||||||
| import org.communiquons.android.comunic.client.data.models.NotificationsCount; |  | ||||||
| import org.communiquons.android.comunic.client.data.helpers.NotificationsHelper; | import org.communiquons.android.comunic.client.data.helpers.NotificationsHelper; | ||||||
|  | import org.communiquons.android.comunic.client.data.models.NotificationsCount; | ||||||
| import org.communiquons.android.comunic.client.data.utils.PreferencesUtils; | import org.communiquons.android.comunic.client.data.utils.PreferencesUtils; | ||||||
| import org.communiquons.android.comunic.client.ui.activities.MainActivity; | import org.communiquons.android.comunic.client.ui.activities.MainActivity; | ||||||
|  | import org.communiquons.android.comunic.client.ui.receivers.PendingCallsBroadcastReceiver; | ||||||
| import java.util.Objects; |  | ||||||
|  |  | ||||||
| import static android.app.NotificationManager.IMPORTANCE_DEFAULT; | import static android.app.NotificationManager.IMPORTANCE_DEFAULT; | ||||||
|  | import static org.communiquons.android.comunic.client.ui.Constants.IntentActions.ACTION_NOTIFY_NEW_CALLS_AVAILABLE; | ||||||
|  | import static org.communiquons.android.comunic.client.ui.Constants.Notifications.MAIN_NOTIFICATION_ID; | ||||||
| import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.GLOBAL_CHANNEL_DESCRIPTION; | import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.GLOBAL_CHANNEL_DESCRIPTION; | ||||||
| import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.GLOBAL_CHANNEL_ID; | import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.GLOBAL_CHANNEL_ID; | ||||||
| import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.GLOBAL_CHANNEL_NAME; | import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.GLOBAL_CHANNEL_NAME; | ||||||
| @@ -54,11 +56,6 @@ public class NotificationsService extends IntentService { | |||||||
|     public static final String BROADCAST_EXTRA_UNREAD_CONVERSATIONS = "UnreadConversations"; |     public static final String BROADCAST_EXTRA_UNREAD_CONVERSATIONS = "UnreadConversations"; | ||||||
|     public static final String BROADCAST_EXTRA_NUMBER_FRIENDSHIP_REQUESTS = "NumberFriendsRequests"; |     public static final String BROADCAST_EXTRA_NUMBER_FRIENDSHIP_REQUESTS = "NumberFriendsRequests"; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Main notification ID |  | ||||||
|      */ |  | ||||||
|     private final static int MAIN_NOTIFICATION_ID = 0; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Keep run status |      * Keep run status | ||||||
|      */ |      */ | ||||||
| @@ -81,6 +78,13 @@ public class NotificationsService extends IntentService { | |||||||
|      */ |      */ | ||||||
|     public NotificationsService(){ |     public NotificationsService(){ | ||||||
|         super("NotificationsService"); |         super("NotificationsService"); | ||||||
|  |  | ||||||
|  |         //Register calls broadcast register | ||||||
|  |         IntentFilter callFilters = new IntentFilter(); | ||||||
|  |         callFilters.addAction(ACTION_NOTIFY_NEW_CALLS_AVAILABLE); | ||||||
|  |         LocalBroadcastManager.getInstance(this) | ||||||
|  |                 .registerReceiver(new PendingCallsBroadcastReceiver(), callFilters); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -161,7 +165,22 @@ public class NotificationsService extends IntentService { | |||||||
|                     .putExtra(BROADCAST_EXTRA_UNREAD_CONVERSATIONS, count.getConversationsCount()) |                     .putExtra(BROADCAST_EXTRA_UNREAD_CONVERSATIONS, count.getConversationsCount()) | ||||||
|                     .putExtra(BROADCAST_EXTRA_NUMBER_FRIENDSHIP_REQUESTS, count.getFriendsRequestsCount()); |                     .putExtra(BROADCAST_EXTRA_NUMBER_FRIENDSHIP_REQUESTS, count.getFriendsRequestsCount()); | ||||||
|  |  | ||||||
|  |             //Send new calls information | ||||||
|             LocalBroadcastManager.getInstance(this).sendBroadcast(pushIntent); |             LocalBroadcastManager.getInstance(this).sendBroadcast(pushIntent); | ||||||
|  |  | ||||||
|  |             //If new calls are available, notify system | ||||||
|  |             if(CallsHelper.IsCallSystemAvailable()){ | ||||||
|  |  | ||||||
|  |                 if(count.hasPendingCalls()) { | ||||||
|  |                     Intent callIntent = new Intent(this, PendingCallsBroadcastReceiver.class); | ||||||
|  |                     callIntent.setAction(ACTION_NOTIFY_NEW_CALLS_AVAILABLE); | ||||||
|  |                     LocalBroadcastManager.getInstance(this).sendBroadcast(callIntent); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                     PendingCallsBroadcastReceiver.RemoveCallNotification(this); | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Log.v(TAG, "Stop service"); |         Log.v(TAG, "Stop service"); | ||||||
| @@ -193,6 +212,7 @@ public class NotificationsService extends IntentService { | |||||||
|         //Get notification manager to push notification |         //Get notification manager to push notification | ||||||
|         NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); |         NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); | ||||||
|         notificationManager.notify(MAIN_NOTIFICATION_ID, mBuilder.build()); |         notificationManager.notify(MAIN_NOTIFICATION_ID, mBuilder.build()); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| package org.communiquons.android.comunic.client.ui; | package org.communiquons.android.comunic.client.ui; | ||||||
|  |  | ||||||
| import android.app.NotificationManager; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * UI constants |  * UI constants | ||||||
|  * |  * | ||||||
| @@ -63,6 +61,19 @@ public final class Constants { | |||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Intents actions | ||||||
|  |      */ | ||||||
|  |     public final class IntentActions { | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Intent used to notify of new available calls | ||||||
|  |          */ | ||||||
|  |         public static final String ACTION_NOTIFY_NEW_CALLS_AVAILABLE = | ||||||
|  |                 "org.communiquons.android.comunic.client.NEW_CALLS_AVAILABLE"; | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Notifications channels |      * Notifications channels | ||||||
|      */ |      */ | ||||||
| @@ -75,6 +86,13 @@ public final class Constants { | |||||||
|         public static final String GLOBAL_CHANNEL_NAME = "MainNotificationChannel"; |         public static final String GLOBAL_CHANNEL_NAME = "MainNotificationChannel"; | ||||||
|         public static final String GLOBAL_CHANNEL_DESCRIPTION = "Global Comunic notifications"; |         public static final String GLOBAL_CHANNEL_DESCRIPTION = "Global Comunic notifications"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Call channel information | ||||||
|  |          */ | ||||||
|  |         public static final String CALL_CHANNEL_ID = "CallChannel"; | ||||||
|  |         public static final String CALL_CHANNEL_NAME = "Call Notification Channel"; | ||||||
|  |         public static final String CALL_CHANNEL_DESCRIPTION = "Channel used to notify incoming calls"; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -87,5 +105,11 @@ public final class Constants { | |||||||
|          */ |          */ | ||||||
|         public static final int MAIN_NOTIFICATION_ID = 0; |         public static final int MAIN_NOTIFICATION_ID = 0; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Call notification ID | ||||||
|  |          */ | ||||||
|  |         public static final int CALL_NOTIFICATION_ID = 1; | ||||||
|  |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,10 +1,11 @@ | |||||||
| package org.communiquons.android.comunic.client.ui.activities; | package org.communiquons.android.comunic.client.ui.activities; | ||||||
|  |  | ||||||
| import android.support.v7.app.AppCompatActivity; |  | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
|  | import android.support.v7.app.AppCompatActivity; | ||||||
| import android.widget.TextView; | import android.widget.TextView; | ||||||
|  |  | ||||||
| import org.communiquons.android.comunic.client.R; | import org.communiquons.android.comunic.client.R; | ||||||
|  | import org.communiquons.android.comunic.client.ui.receivers.PendingCallsBroadcastReceiver; | ||||||
|  |  | ||||||
| import java.util.Objects; | import java.util.Objects; | ||||||
|  |  | ||||||
| @@ -32,4 +33,12 @@ public class CallActivity extends AppCompatActivity { | |||||||
|         ((TextView)findViewById(R.id.call_id)).setText( |         ((TextView)findViewById(R.id.call_id)).setText( | ||||||
|                 "Call " + getIntent().getExtras().getInt(ARGUMENT_CALL_ID)); |                 "Call " + getIntent().getExtras().getInt(ARGUMENT_CALL_ID)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     protected void onResume() { | ||||||
|  |         super.onResume(); | ||||||
|  |  | ||||||
|  |         //Hide call notifications | ||||||
|  |         PendingCallsBroadcastReceiver.RemoveCallNotification(this); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | package org.communiquons.android.comunic.client.ui.asynctasks; | ||||||
|  |  | ||||||
|  | import android.content.Context; | ||||||
|  |  | ||||||
|  | import org.communiquons.android.comunic.client.data.helpers.CallsHelper; | ||||||
|  | import org.communiquons.android.comunic.client.data.models.NextPendingCallInformation; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Get next pending call task | ||||||
|  |  * | ||||||
|  |  * @author Pierre HUBERT | ||||||
|  |  */ | ||||||
|  | public class GetNextPendingCallTask extends SafeAsyncTask<Void, Void, NextPendingCallInformation> { | ||||||
|  |  | ||||||
|  |     public GetNextPendingCallTask(Context context) { | ||||||
|  |         super(context); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     protected NextPendingCallInformation doInBackground(Void... voids) { | ||||||
|  |  | ||||||
|  |         CallsHelper callsHelper =  new CallsHelper(getContext()); | ||||||
|  |         NextPendingCallInformation call = callsHelper.getNextPendingCall(); | ||||||
|  |  | ||||||
|  |         //Load call name if possible | ||||||
|  |         if(call == null || (call.isHasPendingCall() && callsHelper.getCallName(call) == null)) | ||||||
|  |             return null; | ||||||
|  |  | ||||||
|  |         return call; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,160 @@ | |||||||
|  | package org.communiquons.android.comunic.client.ui.receivers; | ||||||
|  |  | ||||||
|  | import android.app.Notification; | ||||||
|  | import android.app.NotificationChannel; | ||||||
|  | import android.app.NotificationManager; | ||||||
|  | import android.app.PendingIntent; | ||||||
|  | import android.content.BroadcastReceiver; | ||||||
|  | import android.content.Context; | ||||||
|  | import android.content.Intent; | ||||||
|  | import android.os.AsyncTask; | ||||||
|  | import android.os.Build; | ||||||
|  | import android.support.annotation.Nullable; | ||||||
|  | import android.support.v4.app.NotificationCompat; | ||||||
|  | import android.support.v4.app.NotificationManagerCompat; | ||||||
|  | import android.util.Log; | ||||||
|  |  | ||||||
|  | import org.communiquons.android.comunic.client.R; | ||||||
|  | import org.communiquons.android.comunic.client.data.models.NextPendingCallInformation; | ||||||
|  | import org.communiquons.android.comunic.client.data.utils.AccountUtils; | ||||||
|  | import org.communiquons.android.comunic.client.ui.Constants; | ||||||
|  | import org.communiquons.android.comunic.client.ui.activities.CallActivity; | ||||||
|  | import org.communiquons.android.comunic.client.ui.asynctasks.GetNextPendingCallTask; | ||||||
|  | import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTask; | ||||||
|  | import org.communiquons.android.comunic.client.ui.utils.UiUtils; | ||||||
|  |  | ||||||
|  | import java.util.Objects; | ||||||
|  |  | ||||||
|  | import static android.app.NotificationManager.IMPORTANCE_HIGH; | ||||||
|  | import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH; | ||||||
|  | import static org.communiquons.android.comunic.client.ui.Constants.Notifications.CALL_NOTIFICATION_ID; | ||||||
|  | import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.CALL_CHANNEL_DESCRIPTION; | ||||||
|  | import static org.communiquons.android.comunic.client.ui.Constants.NotificationsChannels.CALL_CHANNEL_ID; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Receiver for pending calls | ||||||
|  |  * | ||||||
|  |  * This receiver get calls when new calls are reported to be available for the user | ||||||
|  |  * | ||||||
|  |  * @author Pierre HUBERT | ||||||
|  |  */ | ||||||
|  | public class PendingCallsBroadcastReceiver extends BroadcastReceiver { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Debug tag | ||||||
|  |      */ | ||||||
|  |     private static final String TAG = PendingCallsBroadcastReceiver.class.getSimpleName(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * This variable is set to true if another call is being processed | ||||||
|  |      */ | ||||||
|  |     private boolean locked = false; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void onReceive(final Context context, Intent intent) { | ||||||
|  |  | ||||||
|  |         //Check if the intent is valid | ||||||
|  |         if(intent == null | ||||||
|  |                 || !Objects.equals(intent.getAction(), | ||||||
|  |                 Constants.IntentActions.ACTION_NOTIFY_NEW_CALLS_AVAILABLE)) | ||||||
|  |             throw new RuntimeException("Unexpected call of " + TAG); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         //Check if service is currently locked | ||||||
|  |         if(locked) { | ||||||
|  |             Log.e(TAG, "New call skipped because this class is locked"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         locked = true; | ||||||
|  |  | ||||||
|  |         //Get next pending notification | ||||||
|  |         GetNextPendingCallTask task = new GetNextPendingCallTask(context); | ||||||
|  |         task.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener<NextPendingCallInformation>() { | ||||||
|  |             @Override | ||||||
|  |             public void OnPostExecute(NextPendingCallInformation nextPendingCallInformation) { | ||||||
|  |                 locked = false; | ||||||
|  |                 onGotCall(context, nextPendingCallInformation); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Method called when we have got new pending call information | ||||||
|  |      * | ||||||
|  |      * @param context Application context | ||||||
|  |      * @param info Information about the call | ||||||
|  |      */ | ||||||
|  |     private void onGotCall(Context context, @Nullable NextPendingCallInformation info){ | ||||||
|  |  | ||||||
|  |         if(info == null){ | ||||||
|  |             Log.e(TAG, "Could not get information about next pending call!"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         //Check if there is no pending call | ||||||
|  |         if(!info.isHasPendingCall()) { | ||||||
|  |  | ||||||
|  |             //Remove any related notification | ||||||
|  |             RemoveCallNotification(context); | ||||||
|  |  | ||||||
|  |             return; | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         //Check if all notification members left the call | ||||||
|  |         if(info.hasAllMembersLeftCallExcept(AccountUtils.getID(context))) | ||||||
|  |             return; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         //Create notification | ||||||
|  |  | ||||||
|  |         //Accept intent | ||||||
|  |         Intent acceptIntent = new Intent(context, CallActivity.class); | ||||||
|  |         acceptIntent.putExtra(CallActivity.ARGUMENT_CALL_ID, info.getId()); | ||||||
|  |         PendingIntent pendingAcceptIntent | ||||||
|  |                 = PendingIntent.getActivity(context, 0, acceptIntent, 0); | ||||||
|  |  | ||||||
|  |         //Create and show notification | ||||||
|  |         NotificationCompat.Builder builder = | ||||||
|  |                 new NotificationCompat.Builder(context, CALL_CHANNEL_ID) | ||||||
|  |                         .setSmallIcon(R.drawable.ic_call) | ||||||
|  |                         .setContentTitle(info.getCallName()) | ||||||
|  |                         .setContentText(UiUtils.getString(context, R.string.notification_call_content, info.getCallName())) | ||||||
|  |                         .setContentIntent(pendingAcceptIntent) | ||||||
|  |                         .setFullScreenIntent(pendingAcceptIntent, true) | ||||||
|  |                         .setPriority(PRIORITY_HIGH) | ||||||
|  |  | ||||||
|  |                         //Accept action | ||||||
|  |                         .addAction(R.drawable.ic_call, | ||||||
|  |                                 UiUtils.getString(context, R.string.notification_call_accept), pendingAcceptIntent); | ||||||
|  |                         //.addAction(R.drawable.ic_call, R.string.notification_call_reject, null) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         //Create notification channel if required | ||||||
|  |         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ | ||||||
|  |             NotificationChannel channel = new NotificationChannel(CALL_CHANNEL_ID, | ||||||
|  |                     CALL_CHANNEL_DESCRIPTION, IMPORTANCE_HIGH); | ||||||
|  |             channel.setDescription(CALL_CHANNEL_DESCRIPTION); | ||||||
|  |  | ||||||
|  |             NotificationManager notificationManager = context.getSystemService(NotificationManager.class); | ||||||
|  |             notificationManager.createNotificationChannel(channel); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Notification n = builder.build(); | ||||||
|  |         n.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; | ||||||
|  |  | ||||||
|  |         NotificationManagerCompat.from(context).notify(CALL_NOTIFICATION_ID, n); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Remove any visible call notification | ||||||
|  |      * | ||||||
|  |      * @param context The context of the application | ||||||
|  |      */ | ||||||
|  |     public static void RemoveCallNotification(Context context){ | ||||||
|  |         NotificationManagerCompat.from(context).cancel(CALL_NOTIFICATION_ID); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -320,4 +320,8 @@ | |||||||
|     <string name="err_get_group_info">Impossible de récupérer les informations sur le groupe !</string> |     <string name="err_get_group_info">Impossible de récupérer les informations sur le groupe !</string> | ||||||
|     <string name="notice_closed_registration">Accès sur invitation</string> |     <string name="notice_closed_registration">Accès sur invitation</string> | ||||||
|     <string name="err_create_call_for_conversation">Une erreur a survenu lors de la création d\'un appel pour la conversation !</string> |     <string name="err_create_call_for_conversation">Une erreur a survenu lors de la création d\'un appel pour la conversation !</string> | ||||||
|  |     <string name="activity_call_label">Appel</string> | ||||||
|  |     <string name="notification_call_accept">Répondre</string> | ||||||
|  |     <string name="notification_call_reject">Rejeter</string> | ||||||
|  |     <string name="notification_call_content">%s vous appelle.</string> | ||||||
| </resources> | </resources> | ||||||
| @@ -320,4 +320,7 @@ | |||||||
|     <string name="err_get_search_results">Could not get results of your search!</string> |     <string name="err_get_search_results">Could not get results of your search!</string> | ||||||
|     <string name="err_create_call_for_conversation">Could not create a call for the conversation!</string> |     <string name="err_create_call_for_conversation">Could not create a call for the conversation!</string> | ||||||
|     <string name="activity_call_label">Call</string> |     <string name="activity_call_label">Call</string> | ||||||
|  |     <string name="notification_call_accept">Respond</string> | ||||||
|  |     <string name="notification_call_reject">Reject call</string> | ||||||
|  |     <string name="notification_call_content">%s is calling you</string> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user