Edited at

Androidアプリ→ブラウザ起動→WEBサイトでログイン処理→URLスキームでアプリを再起動、そして指定したActivityに戻ってくる方法

More than 3 years have passed since last update.

 Androidアプリからブラウザを起動してWEBサイトに飛んで、ログイン処理などをした後、またアプリに戻ってくる方法のメモです。アプリ側はいろんなactivityからブラウザを起動できて、最後に元のactivityに戻ってくることを想定します。


AndroidManifest.xmlの設定


AndroidManifest.xml

<activity android:name=".MainActivity" android:launchMode="singleTask">

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myappmain" android:host="callback" android:path="/param" />
</intent-filter>
</activity>
<activity android:name=".SubActivity" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myappsub" android:host="callback" android:path="/param" />
</intent-filter>
</activity>


  • activityが複数、MainActivityとSubActivityがあると仮定します。

  • intent-filterandroid.intent.category.BROWSABLEを入れてアプリをブラウザから起動できるようにします。


  • activity毎に違うscheme名を付けておきます。


  • 最初にブラウザを開いたactivityに戻ってきたいので、android:launchMode="singleTask"を入れます。これを入れないと同名のactivityが二重に開いてしまいます。singleTaskの設定を入れた場合はactivityにonNewIntentを入れます(後述)。



MainActivityでブラウザを起動


MainActivity.java

//ランダム文字列(code)を作成して保存

CodeGenerator codeGenerator = new codeGenerator();
String code = codeGenerator.getRandomCode();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("CODE",code);
editor.apply();//またはeditor.commit()

//ブラウザ起動 codeとschemeをパラメータに入れておく
Uri uri = Uri.parse("https://hoge.jp/login/?code=" + code + "&scheme=myappmain");
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);



  • 上で作成しているcodeはワンタイムパスワードの役割です。ブラウザを起動する度に毎回ランダム文字列を作成してcodeに入れて渡します。このcodeはSharedPreferenceなどアプリ内にも保存しておきます。

  • scheme名は、MainActivityからブラウザを起動して、またここに戻ってきたいので、AndroidManifestに設定したmyappmainを入れます。


WEBサイト側の設定


  • /login/index.phpでcodeとschemeを受け取ります。idとパスワードを入れてログイン処理などをします(詳細は省略)。成功したらcomplete.phpに遷移してURLスキームでアプリに戻ってきます。complete.phpにはcodeとschemeを引き続き渡します。


complete.php

<?php

//前のページからもらう
$code = $_POST["code"];
$scheme = $_POST["scheme"];
?>

//<head>部分
<script type="text/javascript">
window.onload = function(){
//標準ブラウザ用URLスキーム
location.href="<?=$scheme?>://callback/param?code=<?=$code?>"

/*
必要ならこの辺にiPhone用、Chromeブラウザ用にURLスキームを用意する
*/

}
</script>

//<body>部分
//location.hrefが効かなかった時のために、ボタンを残しておく
<form method="get" action="<?=$scheme?>://callback/param?code=<?=$code?>">
<input type="submit" value="自動的にログインしない場合はこちら" />
</form>



  • scheme名で戻りたいactivityを指定できます。他のアプリとscheme名が重ならないような名前にする必要があります。

  • Chromeブラウザ用のURLスキームを用意するなら、location.hrefを
    "intent://callback/param?code=<?=$code?>#Intent;scheme=<?=$scheme?>;package=パッケージ名;end";
    にします。


  • location.hrefでURLスキームを指定して、アプリを再起動します。location.href効かない場合のためにbody内にボタンを残しておきます(ボタンを残さないで、ページを強制的に閉じても問題ないかもしれない)。


MainActivityに戻ってくる


MainActivity.java

//アプリに戻ってきた時にonResumeが呼ばれるので、そこでcodeなどを取得します

@Override
public void onResume(){
super.onResume();

Intent intent = getIntent();
String action = intent.getAction();

if (Intent.ACTION_VIEW.equals(action)) {
Uri uri = intent.getData();
if (uri != null) {

String param1 = uri.getQueryParameter("code");

String code = sharedPreferences.getString("CODE","ERROR");

//さっき送り出したcodeと合っていれば任意の処理を入れます
if(param1.equals(code)){

/*
アプリ側の任意の処理
アクセストークンなどを保存するとか
*/

}
}
}
}

//AndroidManifestのactivityのlaunchModeをsingleTaskにした場合は、onNewIntentを入れてgetIntent()できるようにします
@Override
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
setIntent(intent);
}



  • アプリに戻ってくると、onResumeが動きます。ここでgetIntent()でcodeなどを受けます。AndroidManifestにandroid:launchMode="singleTask"を設定している場合はonNewIntentを書き加えておきます。これ入れないとデータが受け取れない模様。

  • ブラウザ起動時に送り出したcodeと、返ってきたcodeが同じだったら、アプリ内の任意の処理をします。処理後は場合によりますが、sharedPreferencesのcodeをremove(削除)します。


SubActivityの場合


  • scheme名をAndroidManifestで指定したmyappsubにすると、SubActivityに戻ってこられます。


参考

▼AndroidアプリをURLから起動(まこちの技術情報覚え書き)

http://wavetalker.blog134.fc2.com/blog-entry-72.html