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

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

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

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

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

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

Когда я запускаю этот код в состоянии 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;
            }
        }
    }
}

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

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 Tablets, 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;
            }
        }
    }
}

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, но только с этой опцией и намерением выше, я обнаружил, что он перезапускает все приложение и поэтому добавляет последнее свойство / тег)
  • 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;
}

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

Другие вопросы по тегам