h5啟動原生APP總結

来源:http://www.cnblogs.com/skyHF/archive/2017/06/23/7061600.html
-Advertisement-
Play Games

許久沒有寫博客了,最近有個H5啟動APP原生頁面的需求,中間遇上一些坑,看了些網上的實現方案,特意來總結下 一、需要判斷客戶端的平臺以及是否在微信瀏覽器中訪問 1、客戶端判斷 在啟動APP時,Android和IOS系統處理的方式是不一樣的,Android這邊由於開放,可以在瀏覽器中通過<a>標簽以及 ...


許久沒有寫博客了,最近有個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(){     //啟動APP
     if(publicFun.isInWx()){     //微信中
        alert("請在瀏覽器中打開");
     }else{      //非微信中
        if(publicFun.isIos()){    //IOS系統,直接去itunes中,既可以下載也可以打開
            window.location.href = "https://itunes.apple.com/cn/app/[name]/id[id]";
        }else{      //android系統,通過定時器的方式,判斷是否安裝有APP
            var 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沒有啟動即為false
              var 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,然後進行字元串拆分以及校驗,即可判斷去哪個頁,以及獲取參數值。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這個對象,不是那個對象,第三哦! 對象之間會存在繼承,所以,來說一下他們之間存在的三種三種繼承方式: 1、冒用繼承 這就是第一種繼承方式。 【註意】冒用繼承缺點:不能使用原型上的方法和屬性 優點:可以傳遞參數; 2、原型繼承 這種繼承方式就是將新建的父類對象賦給子類構造函數的原型。 【註意】原型鏈繼 ...
  • 之前在寫頁面的時候用的都是單行文字溢出隱藏,今天遇到了多行文字溢出隱藏,溢出部分用省略號。我通過查閱一些資料整理了一下,拿出來與大家分享一下。 單行文本的溢出隱藏 對於單行文本溢出 隱藏,text-overflow: ellipsis 就能完美的解決,不過在使用他時,一定要結合 overflow: ...
  • 如何垂直居中一個浮動元素 // 方法一:已知元素的高寬 #div1{ width:200px; height:200px; position: absolute; /*父元素需要相對定位*/ top: 50%; left: 50%; margin-top:-100px ; /*二分之一的height ...
  • html +css 靜態頁面 js 動態 交互 原理: js就是修改樣式, 比如彈出一個對話框. 彈出的過程就是這個框由disable 變成display:enable. 又或者當滑鼠指向的時候換一個顏色,就是一個修改樣式的工具. 編寫JS的流程 佈局:HTML+CSS 事件:確定用戶做哪些操作(產... ...
  • windows系統中,本地向自身發送數據包沒有經過真實的網路介面,而是通過環路(loopback interface)介面發送,所以使用基於只能從真實網路介面中抓數據的winpcap是無法抓取本地數據包,需要使用npcap,npcap是基於winpcap 4.1.3開發的,api相容WinPcap, ...
  • jQuery Validate jQuery Validate 插件為表單提供了強大的驗證功能,讓客戶端表單驗證變得更簡單,同時提供了大量的定製選項,滿足應用程式各種需求。 1.首先,如果我們沒有jquery.validata.js那就需要下載了。 點擊神賜下載鏈接 2.創建運行環境,也就是引入我們 ...
  • 前提:調用微信jssdk分享功能,通過微信開發者工具調試,調用正常,無任何報錯信息。 問題:調用成功,且開發者工具正常顯示,但是通過真機調試,分享出去後,自定義內容失效,為微信自動獲取的預設內容!截止發稿日:IOS端一切正常(可能IOS端規則還沒有變),Android端分享操作正常,自定義內容失效。 ...
  • 很多時候多會被正則表達式搞的暈頭轉向,最近抽出時間對正則表達式進行了系統的學習,整理如下: 正則表達式的創建 兩種方法,一種是直接寫,由包含在斜杠之間的模式組成;另一種是調用RegExp對象的構造函數。 兩種方法的創建代碼如下: 可以看出,調用RegExp構造函數創建正則表達式時,第一個參數可以是字 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...