1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ContextからStartActivityする際の注意

Posted at

以前KudanARライブラリを使用したKudanARアプリをリリースしました。
Xamarin.FormsでKudan ARを試してみる

そのアプリのテスト環境として使用していたAndroid8.0では発生しなかったが、Android9.0だと発生するエラーがありました。
少し調査したので軽くまとめたいと思います。

先に結論

Contextの実体にはApplication ContextActivity Contextがあります。
実体を把握した上で使用しよう。

現象

まずは、下記が確認できたエラーメッセージの内容です。

Android.Util.AndroidRuntimeException: 'Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?'

どうやら下記のStartActivity実行時にエラーが発生していることがわかりました。

// Androidバージョンによってはエラーが発生する書き方
var context = Android.App.Application.Context;
using (var intent = new Android.Content.Intent(context, typeof(MarkerARActivity)))
{
    context.StartActivity(intent);
}

原因

Contextと一言に言っても、実体が異なる場合があることを把握しないまま使用したことが原因です。

なぜアプリリリース前に気づけなかった?

KudanARライブラリを使用すると、エミュレータで動作確認ができなくなる仕様があります。
また、私が持っている一番新しいAndroidバージョンは8.0です。
よって、他のAndroidバージョンでの挙動を確認できなかったため、リリース後に気づいた次第です。
言い訳終了。

エラー対処方法

Xamarinのテンプレートソリューションから、空のActivityを呼び出すだけのアプリを作成し、動作を確認しました。
対処方法にはいくつかあるようです。

  • context = Android.App.Application.Context;を使う場合
    • Contextの実体はApplication
    • Intentにフラグを追加して対応
      • intent.SetFlags(ActivityFlags.NewTask);
  • context = (Context)Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;を使う場合
    • Contextの実体はActivity
    • NuGetからPlugin.CurrentActivityをインストールする必要あり
    • Intentへのフラグ追加は必要なし
  • context = MainActivity.Context;を使う場合
    • Contextの実体はActivity
    • public static Context Context { get; private set; }のような適当な静的プロパティをMainActivityに用意する必要あり(OnCreateでthisの代入を行っておく)
    • Intentへのフラグ追加は必要なし

下記の記事が参考になりました。
Androidの勉強:Contextについて

最終的な実装

フラグ設定処理を追加して行数を増やすのは避けたかったので、対処方法の2番目に挙げた方法で実装しました。

// 正常に動作する書き方
var context = (Context)Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;
using (var intent = new Android.Content.Intent(context, typeof(MarkerARActivity)))
{
    context.StartActivity(intent);
}

まとめ

Contextの実体にはApplication ContextActivity Contextがあるので、実体を把握した上で使用しよう。
Contextの取得には、Plugin.CurrentActivityを使用するのが安定。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?