h5啟動原生APP總結

許久沒有寫博客了,最近有個H5啟動APP原生頁面的需求,中間遇上一些坑,看了些網上的實現方案,特意來總結下

一、需要判斷客戶端的平臺以及是否在微信瀏覽器中訪問

1、客戶端判斷

在啟動APP時,Android和IOS系統處理的方式是不一樣的,Android這邊由于開放,可以在瀏覽器中通過<a>標簽以及meta標簽的方式,讓瀏覽器app獲取手機打開應用的權限進而啟動APP。

而在IOS這邊,IOS9以后的系統,則可以在APP開發過程中加入配置和邏輯代碼編寫,系統在瀏覽器即將訪問到某個域名前就把這個域名對應的APP打開,這個有點閃,封閉還是有封閉的好處。

所以首先要在客戶端判斷,是Android系統還是IOS系統,判斷代碼如下

復制代碼
function isInIos(){var userAgentInfo = navigator.userAgent ,Agents = ["iPhone" , "iPad", "iPod"];for(var v = 0; v < Agents.length; v++) {if (userAgentInfo.indexOf(Agents[v]) > 0) {return true;}}return false;
}        
復制代碼

2、是否在微信內置瀏覽器中

無論是在哪個平臺的客戶端Android/IOS,在微信的平臺上訪問都有一個問題,那就是無法啟動客戶端,這是微信為了安全性考慮的限制,android這邊屏蔽schema協議,除非公司是微信的伙伴加入了白名單才能

使用,IOS系統可以去訪問app對應appstore的下載頁,但是微信經常屏蔽appstore的這個網址,進而訪問不到。比較方便的做法就是在微信瀏覽器中,無論是IOS還是android都去應用寶的下載(IOS 這邊最后會到

appstore中)頁面打開。我這邊的需求是提示用戶點擊“...”用默認瀏覽器打開。

判斷是否是在微信中,代碼如下:

function isInWx(){var agent = window.navigator.userAgent.toLowerCase();return agent.match(/MicroMessenger/i) == 'micromessenger';
}

?

?

二、原理

首先無論是andorid還是IOS端,在瀏覽器中通過JS都是無法判斷該手機是否裝有某APP的,即使這個瀏覽器有權限讀取手機應用列表,也沒有一個固定的對外API讓咱們進行查詢。而H5啟動APP本質上是通過

URL scheme打開APP,一個APP可以設置一個或多個打開自己的URL scheme,瀏覽器去訪問某一個APP的URL scheme,然后若系統安裝有這個APP,則會請求權限去打開這個APP。其實也算是瀏覽器app

打開另一個app,iOS就可以使用?UIApplication 的 canOpenUrl 方法來檢測URL scheme 是否能打開對應的APP,而android也是類似的方式。當然如果JS跳轉URL scheme沒有反應,也意味著這個手機沒有

裝這個app。

?

三、android平臺

首先編輯AndroidManifest.xml,主要是增加第二個<intent-filter>

復制代碼
<activity android:name=".activity.LoadingActivity"android:label="${APP_NAME}"android:screenOrientation="portrait"android:theme="@style/FirstActivityTheme"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><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:host="android"android:scheme="wushang" /></intent-filter>
</activity>
復制代碼

比如此處wushang就是scheme,這個最好是app的唯一標識符,要不然在H5喚醒時,會出現一個選擇框,選擇啟動哪一個APP。而host表示啟動該頁面,其實這個更應該用com.android.sky這樣的包名來替代更好。

這樣的情況完整的URL就是wushang://android?data=sky,后面是參數傳遞。在Activity中可以用如下代碼獲取參數

public void onCreate(Bundle savedInstanceState) {             Uri uridata = this.getIntent().getData();             String mydata = uridata.getQueryParameter("data");            
}

之后在進行字符串截取還是什么鬼的都隨意啦。

?

接下來來談談前端代碼,這里有兩種情況

1、頁面在刷新進入時,請求權限喚起APP

這個比較簡單,就只用在頁面的頂部head中加入meta標簽即可

<meta http-equiv="refresh" content="0;url=wushang://android?data=sky">

這個標注當頁面刷新即去訪問這個鏈接,進而啟動APP。但是存在一個問題,如果是蘋果系統的Safari瀏覽器的話,訪問有這個meta的頭,會給出錯誤提示,所以這個頭部可以在后端進行頁面渲染時通過客戶端的

總類在加上去。

2、通過點擊事件喚起APP

最簡單的辦法當然是直接使用a標簽,如下

<a href="wushang://android">open Android app</a>

但是在實際使用時,是需要對客戶端的平臺類型還有是否在微信內置瀏覽器中進行判斷的,所以這樣的做法肯定是不行的。

接下來談談在開發過程中,遇到的一個問題,記錄下。因為這邊移動端使用的工具庫庫是zepto,采用的點擊事件是tap,但是在用tap進行處理是經常要點很多下,才能喚起APP

<script type="text/javascript">$('#go').tap(function(){window.location.href = "wushang://android";});
</script>

具體原因不知,可能是tap事件采用的是輕點觸碰。然后摸索了下,才用click事件,或者直接在a標簽上標注處理函數就沒有這問題

復制代碼
<a id="go" >open Android app
</a>
<a href="javascript:startApp()">open
</a>
<script src="../res/lib/zepto.min.js"></script>
<script src="../res/lib/public.js"></script>
<script>$('#go').click(function () {if(publicFun.isIos()){alert('it is IOS')}else{window.location.href = "wushang://android";}});function startApp(){if(publicFun.isIos()){alert('it is IOS')}else{window.location.href = "wushang://android";}}
</script>
復制代碼

所以決定以后遇到這類問題,就用這兩種方式了。下面是實際的處理函數

復制代碼
 window.startApp = function(){     //啟動APPif(publicFun.isInWx()){     //微信中alert("請在瀏覽器中打開");}else{      //非微信中if(publicFun.isIos()){    //IOS系統,直接去itunes中,既可以下載也可以打開window.location.href = "https://itunes.apple.com/cn/app/[name]/id[id]";}else{      //android系統,通過定時器的方式,判斷是否安裝有APPvar hasApp = true , t = 1000;setTimeout(function () {  //沒有安裝APP則跳轉至應用寶下載,延時時間設置為2秒if(!hasApp) window.location.href = "http://a.app.qq.com/o/simple.jsp?pkgname=[name]";} , 2000);var t1 = Date.now();window.location.href = "wushang://android";setTimeout(function () {    //t的時間就是出發APP啟動的時間,若APP啟動了,再次返回頁面時t2這行代碼執行,hasApp即為true。反之若APP沒有啟動即為falsevar t2 = Date.now();hasApp = !(!t1 || t2 - t1 < t + 150);} , t);}}}?
復制代碼

其實有個非常簡單的辦法,就是直接跳轉應用寶。無論是在android還是IOS,以及微信非微信。應用寶的下載頁面都有下載和打開兩個功能(如果是在IOS平臺,它是通過連接app store的方式)

?

四、IOS平臺

針對ios9及以上的打不開問題,實際上ios9提供了更好的解決方案————通用鏈接。

這是iOS9推出的一項功能,如果你的應用支持Universal Links(通用鏈接),那么就能夠方便的通過傳統的HTTP鏈接來啟動APP(如果iOS設備上已經安裝了你的app,不需要額外做任何判斷等),或者打開網頁(iOS設備上沒有安裝你的app)。或許可以更簡單點來說明,在iOS9之前,對于從各種從瀏覽器,Safari、UIWebView或者 WKWebView中喚醒APP的需求,我們通常只能使用scheme。

以上來自網上關于通用鏈接的介紹,對于前端簡單點講就是你訪問一個http的url,如果這個url帶有你提交給開發平臺的配置文件中匹配規則的內容,ios系統會去嘗試打開你的app,如果打不開,系統就會在瀏覽器中轉向你要訪問的鏈接。很好的一個屬性,因為通過這個屬性在ios9上我們能夠繞過微信的攔截從而打開app。

所以上面的點擊事件,僅僅是去訪問app store,因為若app已安裝,在瀏覽器訪問時,就已經去到APP中了。

這些都是IOS配置上的東西,就不多寫了。至于傳參,以及頁面定向,其實也就是相當于在UIWebView中獲取當前連接的URL,然后進行字符串拆分以及校驗,即可判斷去哪個頁,以及獲取參數值。

?

轉載于:https://www.cnblogs.com/mtl-key/p/7126760.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371753.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371753.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371753.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql導入創建表空間_oracle創建表空間 用戶 數據庫導入和導出(轉)

已經安裝orcale 9i 和pl/sql(6.0)OracleJobSchedulerORCL、OracleOraDb10g_home1iSQL*PlusOracleOraDb10g_home1TNSListenerOracleServiceORCL第一個是oem控制臺服務進程第二個是定時器和isql*plus的服務進程第三個是監聽器的服務進程最后是數據庫服務進程1. pl/sql客戶機安裝后…

什么時候使用Apache Camel?

Apache Camel是JVM / Java環境中我最喜歡的開源框架之一。 它可以輕松集成使用多種協議和技術的不同應用程序。 本文介紹了何時使用Apache Camel以及何時使用其他替代方法。 問題&#xff1a;企業應用程序集成&#xff08;EAI&#xff09; 由于新產品和新應用&#xff0c;幾乎…

念整數

念整數&#xff08;5分&#xff09;題目內容&#xff1a; 你的程序要讀入一個整數&#xff0c;范圍是[-100000,100000]。然后&#xff0c;用漢語拼音將這個整數的每一位輸出出來。 如輸入1234&#xff0c;則輸出&#xff1a; yi er san si注意&#xff0c;每個字的拼音之間有一…

python 比較運算符放在列表中_在Python3中將運算符放在列表中

我想把操作符作為一個列表&#xff0c;然后從列表中調用一個元素作為操作符。在如果我沒有在運算符周圍加引號&#xff0c;那么列表中逗號的語法錯誤&#xff1a;File "p22.py", line 24cat [,-,*]^SyntaxError: invalid syntax如果我把引語放在周圍&#xff0c;那么…

軟工個人總結

目錄 一、個人提升二、寫下屬于自己的人月神話三、對下一屆、后來人、自己的建議四、我的團隊——Clover五、關于代碼質量六、學過軟件工程&#xff1f;七、自我介紹八、個性發揮一、個人提升 1. 開學初的目標 希望通過團隊合作領會團隊合作的內在精神&#xff0c;希望在分工完…

Tomcat上下文JUnit @Rule

創建測試上下文的JUnit Rule的初稿。 這可以用Spring上下文規則可用于 這個帖子 創建集成測試一個完整的Spring上下文。 import org.apache.commons.dbcp.BasicDataSource; import org.apache.log4j.Logger; import org.junit.rules.TestRule; import org.junit.runner.Descrip…

排序算法之(7)——堆排序

【堆排序的思路】 堆排序主要是利用了堆的性質。對于大頂堆&#xff1a;堆中的每一個節點的值都不小于它的孩子節點的值&#xff0c;具體可參考我的還有一篇博客http://blog.csdn.net/adminabcd/article/details/46880591&#xff0c;那么大頂堆的堆頂元素就是當前堆中全部元素…

HTML基礎:基本標簽簡介(3)

html中有很多標簽&#xff0c;下面介紹最基本的幾個標簽。 1、meta 是head標簽中的一個輔助性標簽。 有2個重要屬性&#xff1a; &#xff08;1&#xff09;name 可以優化頁面被搜索到的可能性。name中可以指定屬性&#xff0c;content是屬性值。 <html><head><…

java 字符碼_Java字符編碼

編碼原理介紹(中文編碼雜談)&#xff1a;int -> byte可以直接使用強制類型轉換: byte b (byte) aInt;這個操作是直接截取int中最低一個字節&#xff0c;如果int大于255&#xff0c;則值就會變得面目全非了byte -> int這里有兩種情況&#xff0c;一種是要求保持值不變&am…

重新登錄:重新登錄

嗨&#xff0c;我再次回到日志中來&#xff0c;這是任何應用程序設計和開發的固有部分。 我是堅強的基礎知識的忠實擁護者&#xff0c;在我的拙見中&#xff0c;日志記錄是任何企業級應用程序中經常被忽略但基本的關鍵要素之一。 我已經寫在此之前這里 。 為了理解當前文章&…

eclipse 下使用git clone

方法一&#xff1a;eclipse安裝好git插件后&#xff0c;直接import-git-project from git- clone url-輸入github的網址等就可以了方法二&#xff1a;使用git軟件&#xff0c;到指定的目錄&#xff0c;右擊git bash here&#xff0c;git clone 加帶有網址的文件.git,如&#xf…

linux -unrar解壓縮

解壓縮命令unrar的使用&#xff1a; $unrar --help用法: unrar <command>-<switch 1> -<switchN> <archive><files...><listfiles...><path_to_extract\><命令>e 解壓文件到當前目錄l[t,b] 列出壓縮文檔信…

終極JPA查詢和技巧列表–第3部分

在閱讀第三部分之前&#xff0c;請記住本系列的第一部分和第二部分 JPA&#xff1a;通過查詢創建對象 JPA允許我們在查詢內創建對象&#xff0c;并帶有所需的值&#xff1a; package com.model;public class PersonDogAmountReport {private int dogAmount;private Person pe…

分治1--二分查找

分治1--二分查找 一、心得 二、題目和分析 三、代碼和結果 1 #include <iostream>2 using namespace std;3 int a[10]{1,2,4,5,7,8,9,10,13,20};4 5 6 //非遞歸 7 int find(int i){8 int l0,r9;9 int mid(lr)/2; 10 while(l<r){ 11 mid(lr)/2; 12…

隱式意圖啟動一個Activity

隱式意圖是通過指定一組動作或者屬性實現&#xff0c;主要用于跨應用使用。 1.創建一個意圖對象 Intent intent new Intent();2.設置意圖過濾器 intent.setAction("android.intent.action.testActivity"); //對應于action intent.addCategory("android.intent.…

Spring自定義命名空間

Spring自定義命名空間提供了一種很好的方式來簡化用于描述Spring應用程序上下文的bean定義的xml文件。 這是一個相當古老的概念&#xff0c;最初是在Spring 2.0中引入的&#xff0c;但值得不時地進行審查。 考慮一種情況&#xff0c;必須為沒有自定義名稱空間的Spring MVC應用程…

java二叉樹代碼_JAVA語言實現二叉樹生成的代碼教程

本文主要向大家介紹了JAVA語言實現二叉樹生成的代碼教程&#xff0c;通過具體的內容向大家展示&#xff0c;希望對大家學習JAVA語言有所幫助。給定某二叉樹三序遍歷中的兩個&#xff0c;我們即可以通過生成該二叉樹&#xff0c;并遍歷的方法&#xff0c;求出剩下的一序&#xf…

一個回到頂部的錨點

一般網站的右下角都會有一個回到頂部的錨點&#xff0c;但是在沒有學bootstrap的時候&#xff0c;我還是會想著用定位來做這個東西&#xff0c;但是現在用bootstrap來做的&#xff0c;所以將它記錄下來。 <!DOCTYPE html><html> <head><title>附加導航…

jquery jgrid filterToolBar beforeSearch 修改postData

beforeSearch: function() { var posted_data $("#mygrid").jqGrid(getGridParam,postData); posted_data ["testp"]"helloTest"; }轉載于:https://www.cnblogs.com/qiumingcheng/p/7141671.html

預告片:裸指關節SOA

我正在研究這個想法&#xff0c;但我不知道它是否對你們有吸引力。 我想就您是否需要進一步探討提出您的意見。 達成協議&#xff1a;我遇到過一些團隊&#xff0c;他們在使用SOA技術時由于其工具的復雜性而陷入泥潭。 我只在Java中看到過這種情況&#xff0c;但是我從一些C&am…