4
2

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.

DENSOAdvent Calendar 2021

Day 7

Android/iOSで他アプリに簡単な値を送る方法

Posted at

はじめに

AndroidやiOSアプリを開発していて、自分のアプリから他のアプリを開きたい、簡単なコードを送って連携したい、そういうことはないでしょうか?実装していてちょっと苦労したのでメモがわりに残しておこうと思いました

Android

Android-App-Transition.gif

実装

送信側でやること

MainActivity.kt
val sendIntent: Intent = Intent().apply {
                action = Intent.ACTION_SEND
                // 送信先アプリに送りたい文字列
                putExtra(Intent.EXTRA_TEXT, "C9C7BFC1-6397-4681-96CE-9C1BC1BA3745")
                // 送信先アプリのクラスを指定
                setClassName("com.sample.receiveappmessagesample", "com.sample.receiveappmessagesample.MainActivity");
                // 送信するデータの形式
                type = "text/text"
            }
            startActivity(sendIntent)

ちなみにテキスト以外にも画像なども送信できるようです。ちなみに送信に失敗するとActivityNotFoundExceptionが出ます

受信側でやること

MainActivity.kt
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(findViewById(R.id.toolbar))

+       if (intent?.type == "text/text") {
+           // 受信したらデータをToastに表示する
+           Toast.makeText(applicationContext, intent?.getStringExtra(Intent.EXTRA_TEXT), Toast.LENGTH_LONG).show()
+       }
+   }
    // 〜略〜
}

Manifestにも修正が必要かと思いきや、かなり簡単ですね

iOS

iOS-App-Transition.gif

実装

送信側でやること

ボタンタップをトリガーに動くようにしています。iOSの場合はカスタムURLスキーマという形で送信します。iOS10より前のバージョン向けの条件がありますが、iOS10ユーザは現時点でかなり少ないので不要かなと思います

MainController.swift
    @IBAction func touchDownButton(_ sender: Any) {
        // [送信先アプリに送るURL]://?[送信するパラメータ]
        let url = URL(string: "test.scheme://?view_id=B438019A-2E7D-4D79-A077-FC56FEC30DC1")!
        if UIApplication.shared.canOpenURL(url) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(url, options: [:], completionHandler: {
                    (success) in
                    print("Open \(success)")
                })
            }else{
                UIApplication.shared.openURL(url)
            }
        }
    }

iOSの場合、info.plistの編集も必要です。[TARGETS] > [Info] > [Custom iOS Target Properties]にLSApplicationQueriesSchemesを追加し、送信するURLを定義します

send_infop.png

iOSの場合も、送信に失敗すると下記のようなエラーが出ます
-canOpenURL: failed for URL: "test.schemexxx://?view_id=B438019A-2E7D-4D79-A077-FC56FEC30DC1" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"

受信側でやること

受信したら適当にダイアログを表示することにしました

SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    // 〜 略 〜 //
+   func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
+       guard let url = URLContexts.first?.url else {
+           return
+       }
+       let comp = NSURLComponents(url: url, resolvingAgainstBaseURL: false)
+       guard let queryValue = comp?.queryItems?.first?.value else {
+           return
+       }
+
+       let viewController = self.window!.rootViewController as! ViewController
+       viewController.showDialog(id: queryValue)
+   }
    // 〜 略 〜 //   
}

受信側のinfo.plistにも設定が必要です。URL Typesに受信したいURLを定義します

receive_infop.png

最後に

どちらにしても、これらの方法でアプリ間メッセージ送信する場合、セキュアなデータは渡さないのが無難です。カスタムURLスキームの乗っ取りとその対策ということもありますので。

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?