Показывать AlertDialog как системное оверлейное окно из Сервиса - PullRequest
14 голосов
/ 28 сентября 2010

У меня проблема с отображением AlertDialog из службы.Я могу отобразить окно пользовательского макета с помощью Toast или WindowManager (TYPE_SYSTEM_ALERT или TYPE_SYSTEM_OVERLAY).Но я не хочу использовать пользовательский макет, я предпочитаю использовать хороший графический интерфейс AlertDialog напрямую.

Сценарий:

  • Запуск службы.Активная активность отсутствует.
  • В случае какого-либо внешнего события Сервис отправляет уведомление
  • Когда пользователь нажимает Уведомление, сервис информируется через PendingIntent и должен отображаться AlertDialog (созданный с помощью AlertDialog.Builder(this))

Ошибка:

ERROR/AndroidRuntime(1063): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

Поиск ответа привел меня к впечатлению, что я пытаюсь что-то, что в настоящее время невозможно (Android 2.2).Или, может быть, это так.

Ответы [ 2 ]

25 голосов
/ 12 октября 2010

Решение, соответствующее описанному сценарию, найдено.

  • Новая операция была создана и запущена из службы.Однако это активность с полупрозрачным фоном.Такая активность не имеет строки super.setContentView() в onCreate().Что более важно, для обеспечения прозрачности

    @ android: style / Theme.Translucent

вводится под тегом Theme для этого действия в графическом интерфейсе AndroidManifest.xml.Итак, новая строка, добавленная в манифест xml:

android:theme="@android:style/Theme.Translucent"

  • В onCreate() происходит фактическое отображение AlertDialog

  • Нажатие на кнопки AlertDialog приводит к закрытию диалога и активности и отправке намерения (или с использованием некоторых других средств) для доставки результата в Сервис.

  • Убедитесь, что вы определили setOnDismissListener) для диалога (реализация должна вызывать finish () для активности).Если вы этого не сделаете, нажмите клавишу «Назад», чтобы отменить диалог, но оставит вас в текущем действии, которое прозрачно и выглядит для пользователя как будто что-то действительно не так.

6 голосов
/ 11 ноября 2012

Спасибо за ваше решение.Я столкнулся с той же проблемой и работал с вашей помощью.

Я поставил этот ответ, чтобы поделиться своим способом передачи результата обратно в сервис.

Я не создал никакого дополнительного класса пользовательских намерений и решил проблему передачи результатов только с помощью Intent.putExtra() методов с некоторыми хитростями.

В службе используйте этот код для запуска DialogActivity, который отображает диалоговое окно с предупреждением в onCreate().

Intent intent = new Intent(this.getApplicationContext(), DialogActivity.class); 
intent.putExtra(DialogActivity.CLASS_KEY, this.getClass().getCanonicalName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

А в DialogActivity завершите его следующим образом:

private void returnOk(boolean ok) {
    Intent srcIntent = this.getIntent();
    Intent tgtIntent = new Intent();
    String className = srcIntent.getExtras().getString(CLASS_KEY);
    Log.d("DialogActivity", "Service Class Name: " + className);
    ComponentName cn = new ComponentName(this.getApplicationContext(), className);
    tgtIntent.setComponent(cn);
    tgtIntent.putExtra(RESULT_KEY, ok ? RESULT_OK : RESULT_CANCEL);
    this.startService(tgtIntent);
    this.finish();
}

Наконец, в службе переопределите метод onStartCommand() и получите результат из намерения.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    int ret = super.onStartCommand(intent, flags, startId);
    Bundle extras = intent.getExtras();
    if (extras != null) {
        int result = extras.getInt(DialogActivity.RESULT_KEY, -1);
        if (result >= 0) {
            if (result == DialogActivity.RESULT_OK) {
                // Your logic here...
            }
        } else {
            // Your other start logic here...
        }
    }
    return ret;
}

Я не уверен, является ли этот способ хорошим решением, по крайней мере, он работает для меня.Надеюсь, это будет полезно для кого-то, как я.

Полный источник можно найти здесь:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...