Android Как свернуть экран вызова и переместить свою задачу вперед - Android 10 (2.3.3)

Такое ощущение, что этот вопрос задавали много раз, но ни один из них не соответствует моим потребностям, и ни одно из решений не работает для меня.

У меня есть приложение с классом, расширяющимся до PhoneStateListener, для прослушивания следующих состояний:

  • CALL_STATE_RINGING (здесь я установил глобальную строковую переменную с входящим номером телефона)
  • CALL_STATE_OFFHOOK (здесь я хочу переместить свою задачу / процесс на передний план, чтобы пользователь мог видеть мое приложение с подробностями о вызывающих абонентах на экране, а не на экране входящего вызова)

Мне нужен способ свести к минимуму экран вызова (в область уведомлений). Я знаю, что это можно сделать (есть доказательство), но я не знаю, как это сделать. После сворачивания я смогу переместить свою задачу в передний, который ранее был перенесен на задний.

Мое приложение запускается, пользователь входит в систему и, удерживая нажатой кнопку «Назад», пользователь остается в системе, но приложение перемещается в фоновый режим. Если происходит входящий вызов, я хочу увидеть, существует ли номер телефона вызывающего абонента в моем приложении (приложение хранит информацию о нескольких пользователях), а затем перейти к информации о пользователях после того, как экран вызова будет минимизирован.

Когда я запускаю этот код в состоянии CALL_STATE_OFFHOOK, вызов минимизируется и карта загружается в полноэкранном режиме (Доказательство)

public String IncomingTelephoneNumber;
private class CallStateListener extends PhoneStateListener {

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        switch (state) {
            case TelephonyManager.CALL_STATE_RINGING: {
                IncomingTelephoneNumber = incomingNumber;
                break;
            }
            case TelephonyManager.CALL_STATE_OFFHOOK: {
                Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
                intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
                activity.startActivity(intent);
                break;
            }
        }
    }
}

Получить исходный код карт невозможно. Точно так же я хочу сделать это, но с моим собственным приложением, я пробовал это, но не работает, экран вызова все еще находится перед приложением (или приложение вообще не вызывается). Код не ломается или что-то в этом роде, просто мое приложение не выходит.

public String IncomingTelephoneNumber;
private class CallStateListener extends PhoneStateListener {

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        switch (state) {
            case TelephonyManager.CALL_STATE_RINGING: {
                IncomingTelephoneNumber = incomingNumber;
                break;
            }
            case TelephonyManager.CALL_STATE_OFFHOOK: {
                try {
                    Intent intent = new Intent(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                    intent.setFlags(270532608);//This is the flag which is used from the Launcher, LogCat helped here //flg=0x10200000
                    intent.setClassName(activity.getPackageName(), Splash.class.getCanonicalName());
                    activity.startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }
}

Я пробовал другие способы вернуть приложение на передний план, но не работает.

Я видел заголовок Этот пост, но решения нет.

Я использую Android версии 10, так как это требуется для используемых устройств (планшеты Samsung P-1000, Android 2.3.3 - последняя официальная версия)

Любая помощь приветствуется. Это может быть катастрофа поезда или что-то очень простое, что нужно вызвать. Но я бы хотел, чтобы это было сделано так же, как это делают карты.

РЕДАКТИРОВАТЬ: я нашел решение минимизировать экран вызова (не лучшее решение, но оно работает)

public String IncomingTelephoneNumber;
private class CallStateListener extends PhoneStateListener {

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        switch (state) {
            case TelephonyManager.CALL_STATE_RINGING: {
                IncomingTelephoneNumber = incomingNumber;
                break;
            }
            case TelephonyManager.CALL_STATE_OFFHOOK: {
                try {
                    //This will simulate pressing the Home button
                    //Thus Minimizing the In Call Screen
                    Intent startMain = new Intent(Intent.ACTION_MAIN);
                    startMain.addCategory(Intent.CATEGORY_HOME);
                    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    activity.startActivity(startMain);

                    //This is the part still not working Correctly
                    //Moving my Task/Process to the Front for the user to see
                    //This is Android 10, I still can not find a solution to move task to front
                    Intent intent = new Intent(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setClassName(activity, Splash.class.getCanonicalName());
                    activity.startActivity(intent);
                } catch (Exception e) {
                    Log.v("", "e: " + e.getMessage());
                    e.printStackTrace();
                }
                break;
            }
        }
    }
}

person Pierre    schedule 09.01.2014    source источник
comment
См. Этот пост для краткого объяснения этого stackoverflow.com/a/21215613/1876355   -  person Pierre    schedule 19.01.2014


Ответы (1)


Я нашел решение моей конкретной проблемы. После экспериментов с множеством различных настроек и чтения форумов, это то, что я придумал и работает на Android GingerBread 2.3.3 (версия 10).

Чтобы свернуть звонок и перейти на главный экран, я сделал это

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(startMain);

Я решил не использовать вышеизложенное, а использовать только следующее, которое в основном делает именно то, что мне нужно (решение работает с двумя частями, кодом намерения и кодом в файле манифеста Android)

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

//Here the activity class in Question "JobDetail"
intent.setClassName(activity.getPackageName(), JobDetail.class.getCanonicalName());

//These extras I add and then use them in my
//JobDetail class to show the specific details for the caller
intent.putExtra("JobId", JobId);
intent.putExtra("FromCall", "true");
activity.startActivity(intent);

Часть манифеста

<activity android:name="JobDetail" android:configChanges="orientation|keyboardHidden"
    android:taskAffinity="" android:launchMode="singleInstance"
    android:alwaysRetainTaskState="true" />

Под конкретным классом активности в файле манифеста, который вы хотите вывести на передний план, в моем случае, показывая его поверх InCallScreen, добавьте следующие три свойства / тега

  • android: taskAffinity = "" (я не уверен, что это делает что-нибудь, но оставлю это здесь)
  • android: launchMode = "singleInstance" (я думаю, что это запустит новый экземпляр Activity, но только с этим параметром и Intent выше, я обнаружил, что он перезапускает все приложение и, следовательно, добавляет последнее свойство / тег)
  • android: alwaysRetainTaskState = "true" (это гарантирует, что класс активности открывается напрямую, а не сбрасывается все приложение)

После этого обработайте свои ключи возврата на случай, если класс активности, который вы запускаете, находится глубоко в приложении в другом родительском действии и так далее.

Также обнаружено, что использование moveTaskToBack(true); для минимизации вашего приложения не работает в Gingerbread. Я не знаю всех технических деталей, стоящих за этим, но это говорит мне о том, что рассматриваемое приложение перемещается прямо в конец стека, и поэтому обнаружение, что выдвижение вашей задачи на передний план - непростое приключение. Скорее используйте следующий вызов намерения (имитирует нажатие кнопки «Домой» light-hide ваше приложение пользователем).

@Override
public void onBackPressed() {
    //moveTaskToBack(true);
    Intent startMain = new Intent(Intent.ACTION_MAIN);
    startMain.addCategory(Intent.CATEGORY_HOME);
    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(startMain);
    //Show toast to notify the user that your application is still running in the background
    return;
}

Я надеюсь, что это поможет кому-то также столкнуться с той же проблемой, что и я, со старым оборудованием и старым программным обеспечением.

person Pierre    schedule 10.01.2014
comment
Также см. Этот пост здесь для краткого объяснения stackoverflow.com/a/21215613/1876355 - person Pierre; 19.01.2014