はじめに
AndroidやiOSアプリを開発していて、自分のアプリから他のアプリを開きたい、簡単なコードを送って連携したい、そういうことはないでしょうか?実装していてちょっと苦労したのでメモがわりに残しておこうと思いました
Android
実装
送信側でやること
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
が出ます
受信側でやること
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の場合はカスタムURLスキーマという形で送信します。iOS10より前のバージョン向けの条件がありますが、iOS10ユーザは現時点でかなり少ないので不要かなと思います
@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を定義します
iOSの場合も、送信に失敗すると下記のようなエラーが出ます
-canOpenURL: failed for URL: "test.schemexxx://?view_id=B438019A-2E7D-4D79-A077-FC56FEC30DC1" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"
受信側でやること
受信したら適当にダイアログを表示することにしました
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を定義します
最後に
どちらにしても、これらの方法でアプリ間メッセージ送信する場合、セキュアなデータは渡さないのが無難です。カスタムURLスキームの乗っ取りとその対策ということもありますので。