利用URLScheme实现Unity跳转到其他app
策划想让玩家直接在游戏的一个接口跳转到社交app里,并且跳到社交app里特定的界面,比如FB的个人主界面, instragram账号主界面, discord入群邀请链接等等。关于跳转app,安卓和苹果机型需要分开处理。
安卓Andorid:利用package name和url scheme跳转到特定的界面
- 在Unity上是有可以直接调用 Android 方法的,调用 Android 的 getPackageManager ,通过包名打开设备上安装的 apk应用,不需要 Android 端封装接口
- 如果还需要跳转到特定的界面,则需要调用Uri.parse()去解析url scheme
奉上代码:
using (AndroidJavaObject packageManager = activity.Call<AndroidJavaObject>("getPackageManager")) { using (AndroidJavaObject intent = packageManager.Call<AndroidJavaObject>("getLaunchIntentForPackage", packageName)) // 比如facebook的package name是 com.facebook.katana { if (null != intent) { AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent"); AndroidJavaObject intentObject = new AndroidJavaObject("android.content.Intent"); intentObject.Call<AndroidJavaObject>("setAction", intentClass.GetStatic<string>("ACTION_VIEW")); AndroidJavaClass uriClass = new AndroidJavaClass("android.net.Uri"); // 对应的安卓调用函数是Uri.parse() AndroidJavaObject uriObject = uriClass.CallStatic<AndroidJavaObject>("parse", urlScheme); // app特有的url scheme在网上都可以找到 intentObject.Call<AndroidJavaObject>("setData", uriObject); intentObject.Call<AndroidJavaObject>("setPackage", packageName); // 记得要set package他才知道在哪里运行url sheme,否则url会从默认的浏览器里打开 activity.Call("startActivity", intentObject); } } }
如果你所需要跳转的app第一种方法一直失败,那就试试第二种方法,上网搜搜你所要的app是不是封装了打开apk的接口
有些app是比较特殊,比如Youtube,它封装了打开apk的接口,需要调用第三方库 com.google.android.youtube.player.YouTubeIntents
using (AndroidJavaObject packageManager = activity.Call<AndroidJavaObject>("getPackageManager")) { //一般网上找的youtube package是 com.google.android.youtube,但在这里需要调用到更detailed using (AndroidJavaObject intent = packageManager.Call<AndroidJavaObject>("getLaunchIntentForPackage", “com.google.android.youtube.player.YouTubeIntents”) { if (null != intent) { AndroidJavaObject context = activity.Call<AndroidJavaObject>("getApplicationContext"); AndroidJavaObject youtubeIntent = intent.Call<AndroidJavaObject>("createChannelIntent", context, "UCeXlPpsccMCro_RqHT2lYPw"); activity.Call("startActivity", youtubeIntent); } } }
怎么查app的package name?
- 打开google play, https://play.google.com/store
- 查找你要的app
- 进入app的详情界面,网址后面的id就是它的package name。比如IG: https://play.google.com/store/apps/details?id=com.instagram.android
苹果IOS:利用url scheme跳转
Unity官方有一个接口是专门用来跳转网页的Application.OpenURL(webURL),但在苹果里有些app可以通过调用这个接口直接打开自己的app!可能是IOS系统有自动处理url寻找是否有相关的app,我没仔细看这个函数的源代码,如果有清楚原理的大神,欢迎来讨论!!
Unity 调用IOS代码:
using UnityEngine; using System.Runtime.InteropServices; public class ProcessAppURL : MonoBehaviour { [DllImport("__Internal")] private static extern void _OpenFacebookApp(); [DllImport("__Internal")] private static extern void _OpenYoutubebookApp(); public void OpenApp(string packageName, string url) { switch (appName) { case "Facebook": _OpenFacebookApp(); break; case "Youtube": _OpenYoutubebookApp(); break; default: Application.OpenURL(url); // 这里的url就是正常的网址,比如 https://www.instagram.com/xxxxx break; } } }
IOS方法:
//"iOSProcessURL.h" #ifndef iOSProcessURL_h #define iOSProcessURL_h extern void _OpenFacebookApp(); extern void _OpenYoutubebookApp(); #endif //"iOSProcessURL.m" #import <Foundation/Foundation.h> #include "iOSProcessURL.h" @implementation iOSProcessURL void _OpenFacebookApp() { NSURL *url = [NSURL URLWithString:@"fb://profile/xxxxxxxxxx"]; if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; } } void _OpenYoutubebookApp() { NSURL *url = [NSURL URLWithString:@"youtube://www.youtube.com/channel/xxxxxxx"]; if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; } } @end
踩过的坑!!!!
就facebook的一直跳转不成功,url scheme fb, facebook什么都试过了都不行,在网上找了好久终于发现很有可能是fb没有加入url scheme白名单里,网上有两种加url scheme的方法,在这里我又踩了一个坑,我第一次用的是CFBundleURLType, 这个的确是跳转成功了,但是当打包到app store的时候发现审核没通过因为fb不允许用于url types,这下才明白这个字段是用来给其他app来launch我的app所应该用的url scheme,而不是我去调用其他app的。
url的白名单的字段应该是 LSApplicationQueriesSchemes,这个需要改info.plist.
<key>LSApplicationQueriesSchemes</key> <array> <!-- facebook URL Scheme 白名单--> <string>fb</string> <string>facebook</string> <!-- Alipay URL Scheme 白名单--> <string>alipay</string> <string>alipayshare</string> </array>
如果是自己手动打包,可以直接在Xcode上改,但是在现实项目里不可能有人天天手动去改打包后的文件内容。Unity提供了一个API [postprocessbuild] 去修改Xcode项目工程配置以及修改plist文件内容,当unity build结束后, 会自动回调OnPostProcessBuild,如何用可以详情看这个blog:https://www.cnblogs.com/pandawuwyj/p/6904770.html
这次经历让我明白了游戏客户端不仅要写游戏逻辑UI逻辑还要学会安卓苹果开发,还有很长一段路要走啊
Reference:
- https://github.com/youtube/yt-android-player
- https://blog.csdn.net/u014361280/article/details/104535398
- https://www.jianshu.com/p/a1895c766400