114
122

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 5 years have passed since last update.

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

Last updated at Posted at 2015-04-18

 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

114
122
1

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
114
122

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?