mirror of
				https://github.com/pierre42100/ComunicAndroid
				synced 2025-11-04 11:34:06 +00:00 
			
		
		
		
	Can respond to incoming calls.
This commit is contained in:
		@@ -74,16 +74,30 @@
 | 
			
		||||
        <!-- Call activity -->
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".ui.activities.CallActivity"
 | 
			
		||||
            android:label="@string/activity_call_label"/>
 | 
			
		||||
            android:label="@string/activity_call_label" />
 | 
			
		||||
 | 
			
		||||
        <!-- Incoming call activity -->
 | 
			
		||||
        <activity android:name=".ui.activities.IncomingCallActivity" />
 | 
			
		||||
 | 
			
		||||
        <!-- New calls available receiver -->
 | 
			
		||||
        <receiver android:name=".ui.receivers.PendingCallsBroadcastReceiver" android:exported="false">
 | 
			
		||||
        <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>
 | 
			
		||||
 | 
			
		||||
        <!-- Reject new call receiver -->
 | 
			
		||||
        <receiver
 | 
			
		||||
            android:name=".ui.receivers.RejectCallReceiver"
 | 
			
		||||
            android:exported="false">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="org.communiquons.android.comunic.client.REJECT_INCOMING_CALL" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </receiver>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    </application>
 | 
			
		||||
 | 
			
		||||
</manifest>
 | 
			
		||||
@@ -9,6 +9,7 @@ import org.communiquons.android.comunic.client.data.models.APIRequest;
 | 
			
		||||
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.CallMember;
 | 
			
		||||
import org.communiquons.android.comunic.client.data.models.CallResponse;
 | 
			
		||||
import org.communiquons.android.comunic.client.data.models.CallsConfiguration;
 | 
			
		||||
import org.communiquons.android.comunic.client.data.models.NextPendingCallInformation;
 | 
			
		||||
import org.json.JSONArray;
 | 
			
		||||
@@ -171,6 +172,26 @@ public class CallsHelper extends BaseHelper {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Respond to a call request
 | 
			
		||||
     *
 | 
			
		||||
     * @param response The response to the call
 | 
			
		||||
     * @return TRUE for a success / FALSE else
 | 
			
		||||
     */
 | 
			
		||||
    public boolean respondToCall(@NonNull CallResponse response){
 | 
			
		||||
 | 
			
		||||
        APIRequest request = new APIRequest(getContext(), "calls/respond");
 | 
			
		||||
        request.addInt("call_id", response.getCallID());
 | 
			
		||||
        request.addBoolean("accept", response.isAccept());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            return request.exec().getJSONObject().has("success");
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Turn a {@link JSONObject} object into a {@link CallsConfiguration} object.
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
package org.communiquons.android.comunic.client.data.models;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Response of a user to a call
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
public class CallResponse {
 | 
			
		||||
 | 
			
		||||
    //Private fields
 | 
			
		||||
    private int callID;
 | 
			
		||||
    private boolean accept;
 | 
			
		||||
 | 
			
		||||
    public CallResponse(int callID, boolean accept) {
 | 
			
		||||
        this.callID = callID;
 | 
			
		||||
        this.accept = accept;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getCallID() {
 | 
			
		||||
        return callID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setCallID(int callID) {
 | 
			
		||||
        this.callID = callID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isAccept() {
 | 
			
		||||
        return accept;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAccept(boolean accept) {
 | 
			
		||||
        this.accept = accept;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -72,6 +72,13 @@ public final class Constants {
 | 
			
		||||
        public static final String ACTION_NOTIFY_NEW_CALLS_AVAILABLE =
 | 
			
		||||
                "org.communiquons.android.comunic.client.NEW_CALLS_AVAILABLE";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Intent used to reject incoming call
 | 
			
		||||
         */
 | 
			
		||||
        public static final String ACTION_REJECT_INCOMING_CALL =
 | 
			
		||||
                "org.communiquons.android.comunic.client.REJECT_INCOMING_CALL";
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
package org.communiquons.android.comunic.client.ui.activities;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.support.annotation.CallSuper;
 | 
			
		||||
import android.support.annotation.NonNull;
 | 
			
		||||
import android.support.annotation.Nullable;
 | 
			
		||||
import android.support.v7.app.ActionBar;
 | 
			
		||||
import android.support.v7.app.AppCompatActivity;
 | 
			
		||||
 | 
			
		||||
@@ -20,6 +20,12 @@ public abstract class BaseActivity extends AppCompatActivity {
 | 
			
		||||
     */
 | 
			
		||||
    private SafeAsyncTasksManager mSafeAsyncTasksManager = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Current active class
 | 
			
		||||
     */
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private static String mActiveActivityName = null;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
@@ -36,6 +42,22 @@ public abstract class BaseActivity extends AppCompatActivity {
 | 
			
		||||
        mSafeAsyncTasksManager.unsetAllTasks();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onStart() {
 | 
			
		||||
        super.onStart();
 | 
			
		||||
 | 
			
		||||
        mActiveActivityName = getClass().getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onStop() {
 | 
			
		||||
        super.onStop();
 | 
			
		||||
 | 
			
		||||
        if(getClass().getSimpleName().equals(mActiveActivityName))
 | 
			
		||||
            mActiveActivityName = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ActionBar getSupportActionBar() {
 | 
			
		||||
@@ -51,4 +73,14 @@ public abstract class BaseActivity extends AppCompatActivity {
 | 
			
		||||
    public SafeAsyncTasksManager getTasksManager() {
 | 
			
		||||
        return mSafeAsyncTasksManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check out whether an activity is the active activity or not
 | 
			
		||||
     *
 | 
			
		||||
     * @param activity The activity to check
 | 
			
		||||
     * @return True if the activity is the active one / false else
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean IsActiveActivity(Class<? extends BaseActivity> activity){
 | 
			
		||||
        return activity.getSimpleName().equals(mActiveActivityName);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
package org.communiquons.android.comunic.client.ui.activities;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.support.v7.app.AppCompatActivity;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
 | 
			
		||||
import org.communiquons.android.comunic.client.R;
 | 
			
		||||
@@ -14,7 +13,7 @@ import java.util.Objects;
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
public class CallActivity extends AppCompatActivity {
 | 
			
		||||
public class CallActivity extends BaseActivity {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Mandatory argument that includes call id
 | 
			
		||||
@@ -29,9 +28,6 @@ public class CallActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
        //Hide call bar
 | 
			
		||||
        Objects.requireNonNull(getSupportActionBar()).hide();
 | 
			
		||||
 | 
			
		||||
        ((TextView)findViewById(R.id.call_id)).setText(
 | 
			
		||||
                "Call " + getIntent().getExtras().getInt(ARGUMENT_CALL_ID));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -40,5 +36,8 @@ public class CallActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
        //Hide call notifications
 | 
			
		||||
        PendingCallsBroadcastReceiver.RemoveCallNotification(this);
 | 
			
		||||
 | 
			
		||||
        ((TextView)findViewById(R.id.call_id)).setText(
 | 
			
		||||
                "Call " + getIntent().getExtras().getInt(ARGUMENT_CALL_ID));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,159 @@
 | 
			
		||||
package org.communiquons.android.comunic.client.ui.activities;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.AsyncTask;
 | 
			
		||||
import android.support.annotation.Nullable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
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.asynctasks.GetNextPendingCallTask;
 | 
			
		||||
import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTask;
 | 
			
		||||
import org.communiquons.android.comunic.client.ui.receivers.PendingCallsBroadcastReceiver;
 | 
			
		||||
import org.communiquons.android.comunic.client.ui.receivers.RejectCallReceiver;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Incoming call activity
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
public class IncomingCallActivity extends BaseActivity implements SafeAsyncTask.OnPostExecuteListener<NextPendingCallInformation>, View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    private NextPendingCallInformation mNextPendingCallInformation;
 | 
			
		||||
 | 
			
		||||
    private RefreshThread mRefreshThread = null;
 | 
			
		||||
 | 
			
		||||
    private Button mAcceptButton;
 | 
			
		||||
    private Button mRejectButton;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_incoming_call);
 | 
			
		||||
 | 
			
		||||
        getSupportActionBar().hide();
 | 
			
		||||
 | 
			
		||||
        PendingCallsBroadcastReceiver.RemoveCallNotification(this);
 | 
			
		||||
 | 
			
		||||
        mAcceptButton = findViewById(R.id.accept_button);
 | 
			
		||||
        mRejectButton = findViewById(R.id.reject_button);
 | 
			
		||||
 | 
			
		||||
        if(IsActiveActivity(IncomingCallActivity.class))
 | 
			
		||||
            finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onStart() {
 | 
			
		||||
        super.onStart();
 | 
			
		||||
 | 
			
		||||
        mRefreshThread = new RefreshThread();
 | 
			
		||||
        mRefreshThread.start();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onStop() {
 | 
			
		||||
        super.onStop();
 | 
			
		||||
 | 
			
		||||
        mRefreshThread.interrupt();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getNextPendingCall() {
 | 
			
		||||
        //Get next pending call
 | 
			
		||||
        GetNextPendingCallTask getNextPendingCallTask = new GetNextPendingCallTask(getApplicationContext());
 | 
			
		||||
        getNextPendingCallTask.setOnPostExecuteListener(this);
 | 
			
		||||
        getNextPendingCallTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
 | 
			
		||||
        getTasksManager().addTask(getNextPendingCallTask);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void OnPostExecute(@Nullable NextPendingCallInformation nextPendingCallInformation) {
 | 
			
		||||
 | 
			
		||||
        if(nextPendingCallInformation == null){
 | 
			
		||||
            Toast.makeText(this, R.string.err_get_next_pending_call_info, Toast.LENGTH_SHORT).show();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!nextPendingCallInformation.isHasPendingCall()
 | 
			
		||||
                || nextPendingCallInformation.hasAllMembersLeftCallExcept(AccountUtils.getID(this)))
 | 
			
		||||
            finish();
 | 
			
		||||
 | 
			
		||||
        this.mNextPendingCallInformation = nextPendingCallInformation;
 | 
			
		||||
 | 
			
		||||
        ((TextView)findViewById(R.id.call_title)).setText(nextPendingCallInformation.getCallName());
 | 
			
		||||
        mAcceptButton.setOnClickListener(this);
 | 
			
		||||
        mRejectButton.setOnClickListener(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
        //Accept call
 | 
			
		||||
        if(v.equals(mAcceptButton)){
 | 
			
		||||
            Intent intent = new Intent(this, CallActivity.class);
 | 
			
		||||
            intent.putExtra(CallActivity.ARGUMENT_CALL_ID, mNextPendingCallInformation.getId());
 | 
			
		||||
            startActivity(intent);
 | 
			
		||||
            finish();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //Reject calls
 | 
			
		||||
        if(v.equals(mRejectButton)){
 | 
			
		||||
            Intent intent = new Intent(this, RejectCallReceiver.class);
 | 
			
		||||
            intent.setAction(Constants.IntentActions.ACTION_REJECT_INCOMING_CALL);
 | 
			
		||||
            intent.putExtra(RejectCallReceiver.ARGUMENT_CALL_ID, mNextPendingCallInformation.getId());
 | 
			
		||||
            sendBroadcast(intent);
 | 
			
		||||
            finish();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Class used to refresh call information
 | 
			
		||||
     */
 | 
			
		||||
    private class RefreshThread extends Thread {
 | 
			
		||||
 | 
			
		||||
        private boolean stop = false;
 | 
			
		||||
        private final Object o = new Object();
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void run() {
 | 
			
		||||
            super.run();
 | 
			
		||||
 | 
			
		||||
            while(!stop){
 | 
			
		||||
 | 
			
		||||
                //Execute task
 | 
			
		||||
                runOnUiThread(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        getNextPendingCall();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                synchronized (o) {
 | 
			
		||||
 | 
			
		||||
                    //Looping
 | 
			
		||||
                    try {
 | 
			
		||||
                        o.wait(2000);
 | 
			
		||||
                    } catch (InterruptedException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                        interrupt();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void interrupt(){
 | 
			
		||||
            stop = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
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.CallResponse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Respond to call task
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
public class RespondToCallTask extends SafeAsyncTask<CallResponse, Void, Boolean> {
 | 
			
		||||
 | 
			
		||||
    public RespondToCallTask(Context context) {
 | 
			
		||||
        super(context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Boolean doInBackground(CallResponse... callResponses) {
 | 
			
		||||
        return new CallsHelper(getContext()).respondToCall(callResponses[0]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -18,7 +18,9 @@ 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.BaseActivity;
 | 
			
		||||
import org.communiquons.android.comunic.client.ui.activities.CallActivity;
 | 
			
		||||
import org.communiquons.android.comunic.client.ui.activities.IncomingCallActivity;
 | 
			
		||||
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;
 | 
			
		||||
@@ -50,6 +52,11 @@ public class PendingCallsBroadcastReceiver extends BroadcastReceiver {
 | 
			
		||||
     */
 | 
			
		||||
    private boolean locked = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The ID of the last shown notification
 | 
			
		||||
     */
 | 
			
		||||
    private static int mLastNotificationCallID = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onReceive(final Context context, Intent intent) {
 | 
			
		||||
@@ -61,6 +68,12 @@ public class PendingCallsBroadcastReceiver extends BroadcastReceiver {
 | 
			
		||||
            throw new RuntimeException("Unexpected call of " + TAG);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //Check if user is already calling
 | 
			
		||||
        if(CheckIfUseless(context, null)) {
 | 
			
		||||
            Log.v(TAG, "Reported that a new call is available but skipped because considered as useless.");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Check if service is currently locked
 | 
			
		||||
        if(locked) {
 | 
			
		||||
            Log.e(TAG, "New call skipped because this class is locked");
 | 
			
		||||
@@ -93,29 +106,20 @@ public class PendingCallsBroadcastReceiver extends BroadcastReceiver {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Check if there is no pending call
 | 
			
		||||
        if(!info.isHasPendingCall()) {
 | 
			
		||||
 | 
			
		||||
            //Remove any related notification
 | 
			
		||||
            RemoveCallNotification(context);
 | 
			
		||||
 | 
			
		||||
        //Check if it is useless to continue
 | 
			
		||||
        if(CheckIfUseless(context, info)) {
 | 
			
		||||
            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);
 | 
			
		||||
        //Full screen call request intent
 | 
			
		||||
        Intent fullScreenCallRequestIntent = new Intent(context, IncomingCallActivity.class);
 | 
			
		||||
        PendingIntent pendingFullScreenRequestIntent = PendingIntent.getActivity(context,
 | 
			
		||||
                0, fullScreenCallRequestIntent, 0);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //Create and show notification
 | 
			
		||||
        NotificationCompat.Builder builder =
 | 
			
		||||
@@ -123,14 +127,9 @@ public class PendingCallsBroadcastReceiver extends BroadcastReceiver {
 | 
			
		||||
                        .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)
 | 
			
		||||
                        //.setContentIntent(pendingAcceptIntent)
 | 
			
		||||
                        .setFullScreenIntent(pendingFullScreenRequestIntent, true)
 | 
			
		||||
                        .setPriority(PRIORITY_HIGH);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //Create notification channel if required
 | 
			
		||||
@@ -146,7 +145,28 @@ public class PendingCallsBroadcastReceiver extends BroadcastReceiver {
 | 
			
		||||
        Notification n = builder.build();
 | 
			
		||||
        n.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
 | 
			
		||||
 | 
			
		||||
        NotificationManagerCompat.from(context).notify(CALL_NOTIFICATION_ID, n);
 | 
			
		||||
        mLastNotificationCallID = info.getId();
 | 
			
		||||
        NotificationManagerCompat.from(context).notify(GetNotificationID(mLastNotificationCallID), n);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if calling this receiver is useless for now
 | 
			
		||||
     *
 | 
			
		||||
     * @param context Context of application
 | 
			
		||||
     * @param call Optional information about a pending call
 | 
			
		||||
     * @return TRUE if useless / FALSE else
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean CheckIfUseless(Context context, @Nullable NextPendingCallInformation call){
 | 
			
		||||
        boolean useless = BaseActivity.IsActiveActivity(IncomingCallActivity.class)
 | 
			
		||||
                || BaseActivity.IsActiveActivity(CallActivity.class)
 | 
			
		||||
                || (call != null && (
 | 
			
		||||
                        !call.isHasPendingCall()
 | 
			
		||||
                        || call.hasAllMembersLeftCallExcept(AccountUtils.getID(context))));
 | 
			
		||||
 | 
			
		||||
        if(useless)
 | 
			
		||||
            RemoveCallNotification(context);
 | 
			
		||||
 | 
			
		||||
        return useless;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -155,6 +175,15 @@ public class PendingCallsBroadcastReceiver extends BroadcastReceiver {
 | 
			
		||||
     * @param context The context of the application
 | 
			
		||||
     */
 | 
			
		||||
    public static void RemoveCallNotification(Context context){
 | 
			
		||||
        NotificationManagerCompat.from(context).cancel(CALL_NOTIFICATION_ID);
 | 
			
		||||
        NotificationManagerCompat.from(context).cancel(GetNotificationID(mLastNotificationCallID));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the ID of a notification for a call
 | 
			
		||||
     *
 | 
			
		||||
     * @param callID The ID of the target call
 | 
			
		||||
     */
 | 
			
		||||
    private static int GetNotificationID(int callID){
 | 
			
		||||
        return CALL_NOTIFICATION_ID*1000 + callID;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
package org.communiquons.android.comunic.client.ui.receivers;
 | 
			
		||||
 | 
			
		||||
import android.content.BroadcastReceiver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.AsyncTask;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
import org.communiquons.android.comunic.client.data.models.CallResponse;
 | 
			
		||||
import org.communiquons.android.comunic.client.ui.asynctasks.RespondToCallTask;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import static org.communiquons.android.comunic.client.ui.Constants.IntentActions.ACTION_REJECT_INCOMING_CALL;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This broadcast receiver is used to reject incoming calls
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
public class RejectCallReceiver extends BroadcastReceiver {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Debug tag
 | 
			
		||||
     */
 | 
			
		||||
    private static final String TAG = RejectCallReceiver.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Mandatory argument that includes call id
 | 
			
		||||
     */
 | 
			
		||||
    public static final String ARGUMENT_CALL_ID = "call_id";
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onReceive(Context context, Intent intent) {
 | 
			
		||||
 | 
			
		||||
        if(intent == null || !ACTION_REJECT_INCOMING_CALL.equals(intent.getAction()))
 | 
			
		||||
            throw new RuntimeException(TAG + " was incorrectly triggered!");
 | 
			
		||||
 | 
			
		||||
        int callID = Objects.requireNonNull(intent.getExtras()).getInt(ARGUMENT_CALL_ID);
 | 
			
		||||
 | 
			
		||||
        //Send the response back to the server
 | 
			
		||||
        Log.v(TAG, "Reject call " + callID);
 | 
			
		||||
        RespondToCallTask respondToCallTask = new RespondToCallTask(context);
 | 
			
		||||
        respondToCallTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new CallResponse(
 | 
			
		||||
                callID,
 | 
			
		||||
                false
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								app/src/main/res/layout/activity_incoming_call.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								app/src/main/res/layout/activity_incoming_call.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".ui.activities.IncomingCallActivity">
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/call_title"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginStart="8dp"
 | 
			
		||||
        android:layout_marginTop="8dp"
 | 
			
		||||
        android:layout_marginEnd="8dp"
 | 
			
		||||
        android:layout_marginBottom="8dp"
 | 
			
		||||
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
 | 
			
		||||
        app:layout_constraintBottom_toTopOf="@+id/linearLayout3"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
        tools:text="Call title" />
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:id="@+id/linearLayout3"
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginStart="8dp"
 | 
			
		||||
        android:layout_marginEnd="8dp"
 | 
			
		||||
        android:layout_marginBottom="8dp"
 | 
			
		||||
        android:orientation="horizontal"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent">
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
            android:id="@+id/reject_button"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:backgroundTint="@color/holo_red_dark"
 | 
			
		||||
            android:textColor="@android:color/white"
 | 
			
		||||
            android:text="@string/button_reject_call"
 | 
			
		||||
            tools:ignore="ButtonStyle" />
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
            android:id="@+id/accept_button"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:backgroundTint="@color/holo_green_dark"
 | 
			
		||||
            android:textColor="@android:color/white"
 | 
			
		||||
            android:text="@string/button_accept_call"
 | 
			
		||||
            tools:ignore="ButtonStyle" />
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/textView14"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginStart="8dp"
 | 
			
		||||
        android:layout_marginTop="7dp"
 | 
			
		||||
        android:layout_marginEnd="8dp"
 | 
			
		||||
        android:layout_marginBottom="8dp"
 | 
			
		||||
        android:text="@string/title_incoming_call"
 | 
			
		||||
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
 | 
			
		||||
        app:layout_constraintBottom_toTopOf="@+id/call_title"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
 | 
			
		||||
</android.support.constraint.ConstraintLayout>
 | 
			
		||||
@@ -325,4 +325,8 @@
 | 
			
		||||
    <string name="notification_call_reject">Rejeter</string>
 | 
			
		||||
    <string name="notification_call_content">%s vous appelle.</string>
 | 
			
		||||
    <string name="action_accelerate_notifications_refresh">Accélérer le rafraîchissement des notifications</string>
 | 
			
		||||
    <string name="button_reject_call">Rejeter</string>
 | 
			
		||||
    <string name="button_accept_call">Répondre</string>
 | 
			
		||||
    <string name="title_incoming_call">Appel entrant</string>
 | 
			
		||||
    <string name="err_get_next_pending_call_info">Impossible de récupérer les informations de l\'appel en cours !</string>
 | 
			
		||||
</resources>
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
    <color name="darker_gray">#aaa</color>
 | 
			
		||||
    <color name="darker_darker_gray">#5b5b5b</color>
 | 
			
		||||
    <color name="dark_blue">#303f9f</color>
 | 
			
		||||
    <color name="holo_red_dark">#ffcc0000</color>
 | 
			
		||||
    <color name="holo_red_dark">#cc0000</color>
 | 
			
		||||
 | 
			
		||||
    <color name="default_drawable_color">#000000</color>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -324,4 +324,8 @@
 | 
			
		||||
    <string name="notification_call_reject">Reject call</string>
 | 
			
		||||
    <string name="notification_call_content">%s is calling you</string>
 | 
			
		||||
    <string name="action_accelerate_notifications_refresh">Accelerate notifications refresh</string>
 | 
			
		||||
    <string name="button_reject_call">Reject call</string>
 | 
			
		||||
    <string name="button_accept_call">Accept call</string>
 | 
			
		||||
    <string name="title_incoming_call">Incoming call</string>
 | 
			
		||||
    <string name="err_get_next_pending_call_info">Could not get pending call information!</string>
 | 
			
		||||
</resources>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user