Xamarin Android: получение информации о состоянии одного приложения из другого

У меня есть два приложения Xamarin для Android - назовем их «Archy» и «Mehitabel».

Archy имеет некоторую постоянную информацию о состоянии (которая, скажем, для аргументации, находится в базе данных SQLite).

Если с Mehitabel что-то происходит, ей нужно знать часть этой государственной информации.

Чтобы совершить этот подвиг, я попросил Мехитабель отправить намерение Арчи. У Арчи есть широковещательный приемник, который слышит это, собирает необходимое состояние и отправляет другое намерение обратно в Mehitabel.

Вот код от Archy:

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new [] { "com.example.Archy.SendStateToMehitabel"})]
public class StateQueryReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        var msg = new Intent("com.example.Mehitabel.StateFromArchy");
        msg.PutExtra("ImportantStateInfo", GetSomeState());
        context.SendBroadcast(msg);
    }
}

А вот код от Mehitabel:

    private async Task AskArchyForState()
    {
        var filter = new IntentFilter("com.example.Mehitabel.StateFromArchy");
        var csrc = new TaskCompletionSource<bool>();
        var rcvr = new ActionBroadcastReceiver((context, intent) =>
        {
            State = intent.GetStringExtra("ImportantStateInfo");
            csrc.TrySetResult(State != null);
        });
        RegisterReceiver(rcvr, filter);

        var msg = new Intent("com.example.Archy.SendStateToMehitabel");
        SendBroadcast(msg);

        var task = await Task.WhenAny(csrc.Task, Task.Delay(Timeout));

        UnregisterReceiver(rcvr);
        if (task != csrc.Task)
            bomb("Archy has not answered state query after {0}ms", Timeout);
        if (!csrc.Task.IsCompletedSuccessfully || csrc.Task.Result == false)
            bomb("failed to get all necessary state from Archy");
    }

Все это отлично работает, при условии, что Archy действительно запущен (т. Е. Показан в списке «недавних»). Если Archy не запущен, код получателя Archy никогда не выполняется, а время ожидания Mehitabel истекает.

Я надеюсь, что мне не хватает чего-то простого (например, флага в одном из атрибутов получателя или какой-то секретный соус в намерении com.example.Archy.SendStateToMehitabel).

Вы можете сказать мне, что мне здесь не хватает?

Нужно ли мне использовать совершенно другой подход (например, иметь Mehitabel StartActivityForResult () как действие в Archy или использовать службу, которая запускается при загрузке и работает все время)?

0
0
111
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Основываясь на моем исследовании, я думаю, что вы могли бы открыть Archy до того, как вам понадобятся данные в Mehitabel. Это демонстрация открытия приложения в коде.

 Intent launchIntent = PackageManager.GetLaunchIntentForPackage("NewTestApp.NewTestApp");
            if (launchIntent != null)
            {
                StartActivity(launchIntent);

            }

Примечание. NewTestApp.NewTestApp - это имя пакета Archy.

Я заставил это работать, но с некоторыми оговорками: 1) Это работает лучше, когда я пишу имя своего пакета правильно. 2) Archy запускается дольше, чем ожидалось - от отправки намерения запуска до ответа на мою трансляцию прошло более 25 секунд. 3) Мне пришлось добавить цикл повтора к коду Mehitabel в моем исходном вопросе, чтобы иметь дело с (2), поскольку широковещательные сообщения, отправленные до того, как Archy будет готов, теряются.

Douglas Henke 19.12.2018 22:17

Оказывается, использование StartActivityForResult() - более простой способ сделать это. Подробнее см. мой ответ на связанный вопрос.

Douglas Henke 26.12.2018 22:55

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