微信掃一掃揭秘

ManieRoland 8年前發布 | 22K 次閱讀 安卓開發 Android開發 移動開發

要探索二維碼的秘密之前,我們首先需要簡單了解下什么是二維碼。

什么是二維碼

二維條碼/二維碼(2-dimensional bar code)是用某種特定的幾何圖形按一定規律在平面(二維方向上)分布的黑白相間的圖形記錄數據符號信息的;在代碼編制上巧妙地利用構成計算機內部邏輯基礎的“0”、“1”比特流的概念,使用若干個與二進制相對應的幾何形體來表示文字數值信息,通過圖象輸入設備或光電掃描設備自動識讀以實現信息自動處理。

其實簡單的說二維碼就是一段簡單的字符串圖形化的展示,它可能是一個url,一段文字,或者是一首唐詩也不錯哦

為什么要使用二維碼

二維碼的誕生可以說是真正的促進這移動互聯網的發展。

  • 信息獲取(名片、地圖、WIFI密碼、資料)
  • 網站跳轉(跳轉到微博、手機網站、網站)
  • 廣告推送(用戶掃碼,直接瀏覽商家推送的視頻、音頻廣告)
  • 手機電商(用戶掃碼、手機直接購物下單)
  • 防偽溯源(用戶掃碼、即可查看生產地;同時后臺可以獲取最終消費地)
  • 優惠促銷(用戶掃碼,下載電子優惠券,抽獎)
  • 會員管理(用戶手機上獲取電子會員信息、VIP服務)
  • 手機支付(掃描商品二維碼,通過銀行或第三方支付提供的手機端通道完成支付)

在不同的領域,不同的行業二維碼都可以用來簡化原來的工作流程,那么我們為什么不來試試二維碼呢?

二維碼的生成

通過對上面的了解相信大家對二維碼已經有了一定的了解,那么二維碼是怎么生成的呢?

維碼一共有40個尺寸。官方叫版本Version。Version 1是21 x 21的矩陣,Version 2是 25 x

25的矩陣,Version 3是29的尺寸,每增加一個version,就會增加4的尺寸,公式是:(V-1)

4 + 21(V是版本號) 最高Version

40,(40-1)

4+21 = 177,所以最高是177 x 177 的正方形。

二維碼的基本結構如下:

二維碼一般由定位點圖案、功能性數據、數據碼和糾錯碼組成,生成的算法是固定的有需要的同學可以了解

二維碼的生成原理

二維碼生成原理解析

如今,基本上各個語言都有了比較好的二維碼生成與解碼的開源項目,有需要的同學可以自行google,本次我們呢不做具體介紹,因為不是重點啊 。

微信二維碼揭秘

微信的二維碼有哪些

在平時的使用中我們可以發現微信在很多的場景中都有二維碼的使用在,名片,聯系人,支付等尤為明顯,可以說二維碼已經成為微信不可或缺的設計呢功能了。

那么微信的二維碼到底有哪些是呢?

以二維碼掃描結果和功能區分

  1. http(s)://www. * .com http鏈接
  2. weixin://qr/××× 微信二維碼
  3. http://weixin.qq.com/r/××× 微信二維碼名片
  4. https://login.weixin.qq.com/l/××× 網頁登陸二維碼
  5. https://login.wechatapp.com/l/××× 國際部網頁登陸二維碼
  6. weixin://wxpay/bizpayurl/××× 微信支付
  7. http://weixin.qq.com/g/××× 微信群二維碼

其實在上面的二維碼例子中大體上可以分為兩類,1,4,5未一類,其他的為一類。第一類主要是普通類型和涉及登錄相關的邏輯,第二類中的邏輯就是我們本次要談論的邏輯。

第二類流程如下:

實現微信二維碼邏輯

由上面的介紹我們很清楚的知道,我們想要實現上面的功能我們生成的二維碼肯定是一個url,然后對本本地是否安裝有app的判斷也是在服務端實現的(其實就是個js而已,不要怕),當然在客戶端也需要對自己的代碼做相應的配置。

客戶端配置

由于本人系Android開發工程師,對ios的了解也不是太多,所以本次配置主要是對android端而言的。

首先在manifest文件中配置掃描后需要跳轉activity的intent-filter

還需要制定對應的host、pathPrefix、scheme

至于host、pathPrefix、scheme是什么,大家可以自己去google下,其實只要了解Url的組成原理就ok了。

<activity android:name=".otherTest.scan.FromUrlActicity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <category android:name="android.intent.category.DEFAULT" />
            <data
                android:host="www"
                android:pathPrefix="/com/test"
                android:scheme="flyou" />
        </intent-filter>
    </activity>

上面的host和 pathPrefix是可以省略的,不過還是推薦大家都寫上。

這樣客戶端的配置就完成了。

服務端解析

首先根據瀏覽器的userAgent判斷來自哪個終端,如果是PC則直接跳轉到下載頁,如果是Android或者Ios則判斷本地判斷本地app書否存在如果存在則根據定義的scheme打開相應頁面并傳遞數據,如果不存在該app則跳轉到下載頁面。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>我是一個測試頁面</title>
<meta name="viewport" content="width=320.1, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta content="telephone=no" name="format-detection" />
<meta name="apple-mobile-web-app-capable" content="yes" />

<script>
/*獲取自定義數據*/
function getQueryString(name) {  
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");  
    var r = window.location.search.substr(1).match(reg);  
    if (r != null) return unescape(r[2]);  
    return null;  
}  
var userId=getQueryString("userId");
var u = navigator.userAgent || '';
 /*首先判斷是否是pc,若是pc訪問則跳轉到http://flyou.ren/ */
var isPC = !/(iphone|ios|android|mini|mobile|mobi|Nokia|Symbian|iPod|iPad|Windows\s+Phone|MQQBrowser|wp7|wp8|UCBrowser7|UCWEB|360\s+Aphone\s+Browser)/i.test(u);
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android終端或者uc瀏覽器
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios終端
if (isPC) { location.; }
else if (isAndroid) {
    var the_;//獲得下載鏈接或在app下載頁
    location.href="flyou://www/com/test?userId="+userId;//打開某手機上的某個app應用,并傳遞參數
    setTimeout(function(){
        window.location=the_href;//如果超時就跳轉到app下載頁,或者直接下載
    },2000);
}
else{
    //服務端可以根據ios 先關邏輯做相應的判斷
    alert('寶寶暫時還不持支持IOS操作系統,寶寶會努力的')
}

</script>


</head>

</html>

服務端返回數據處理

在對應的Acticity里處理傳遞回來的參數,并做相應的處理,如微信名片二維碼的功能,返回給相應頁面用戶id,當然這個用戶的userId可以是經過加密的(別我問我怎么加密,你們這么加密我也不想知道)。

public class FromUrlActicity extends AppCompatActivity {

private TextView tvUserid;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_qrcode_acticity);
    tvUserid = (TextView) findViewById(R.id.userid);
    Uri uriData = this.getIntent().getData();
    String userId = uriData.getQueryParameter("userId");

    tvUserid.setText("我是來自服務器的UserId:"+userId);

    }
}

掃描二維碼

自己活著使用第三方工具生成二維碼如下

二維碼對應字符串:http:\henu.flyou.ren/scan?userId=553274238

在手機上使用瀏覽器掃一掃掃描二維碼即可進入如下界面,并獲得服務端傳來的參數,完成相應的邏輯

當然,二維碼可以向服務器傳遞多個數據,服務器也可以向客戶端返回多個數據,分別定義獲取即可。明白了上述的流程想要實現微信的上述流程也是很容易的。

后記

當然,二維碼的功能并不僅僅局限于上面的邏輯,二維碼可以應用在多個行業和領域,那么快快發動你的才智來發現新的大陸吧。

 

來自:http://flyou.ren/2016/09/13/微信掃一掃揭秘/

 

 本文由用戶 ManieRoland 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!