Xamarin Android:从一个应用程序获取另一个应用程序的状态信息
Xamarin Android: get one app's state information from another
我有两个 Xamarin Android 应用程序——我们称它们为 "Archy" 和 "Mehitabel"。
Archy 有一些持久状态信息(为了论证,我们假设它在 SQLite 数据库中)。
如果 Mehitabel 发生了某件事,她需要知道一些状态信息。
为了完成这项壮举,我让 Mehitabel 向 Archy 发送了一个意图。 Archy 有一个广播接收器可以听到它,收集必要的状态,并将不同的意图发回给 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 实际上是 运行(即显示在 "recent" 列表中)。如果 Archy 不是 运行,Archy 的接收器代码永远不会执行并且 Mehitabel 超时。
我希望我遗漏了一些简单的东西(比如接收器属性之一中的标志,或者 com.example.Archy.SendStateToMehitabel 意图中的一些秘诀)。
你能告诉我这里缺少什么吗?
我是否需要使用完全不同的方法(比如在 Archy 中使用 Mehitabel StartActivityForResult() activity,或者使用启动时启动并一直运行的服务)?
根据我的研究,我认为您可以在需要 Mehitabel 中的数据之前打开 Archy。这是关于在代码中打开应用程序的演示。
Intent launchIntent = PackageManager.GetLaunchIntentForPackage("NewTestApp.NewTestApp");
if (launchIntent != null)
{
StartActivity(launchIntent);
}
注:NewTestApp.NewTestApp是Archy的包名。
我有两个 Xamarin Android 应用程序——我们称它们为 "Archy" 和 "Mehitabel"。
Archy 有一些持久状态信息(为了论证,我们假设它在 SQLite 数据库中)。
如果 Mehitabel 发生了某件事,她需要知道一些状态信息。
为了完成这项壮举,我让 Mehitabel 向 Archy 发送了一个意图。 Archy 有一个广播接收器可以听到它,收集必要的状态,并将不同的意图发回给 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 实际上是 运行(即显示在 "recent" 列表中)。如果 Archy 不是 运行,Archy 的接收器代码永远不会执行并且 Mehitabel 超时。
我希望我遗漏了一些简单的东西(比如接收器属性之一中的标志,或者 com.example.Archy.SendStateToMehitabel 意图中的一些秘诀)。
你能告诉我这里缺少什么吗?
我是否需要使用完全不同的方法(比如在 Archy 中使用 Mehitabel StartActivityForResult() activity,或者使用启动时启动并一直运行的服务)?
根据我的研究,我认为您可以在需要 Mehitabel 中的数据之前打开 Archy。这是关于在代码中打开应用程序的演示。
Intent launchIntent = PackageManager.GetLaunchIntentForPackage("NewTestApp.NewTestApp");
if (launchIntent != null)
{
StartActivity(launchIntent);
}
注:NewTestApp.NewTestApp是Archy的包名。