React Native二維碼的生成和掃描

二維碼掃描已經(jīng)是移動app中很常見的功能了,原生端實現(xiàn)掃碼是非常簡單的事精居,Android一般使用ZXing庫來實現(xiàn)悯许,iOS可以使用原生SDK躯砰、ZXing或ZBar的SDK來實現(xiàn)。React Native中要實現(xiàn)二維碼掃描無外乎兩種方式:

  • 原生端封裝掃碼功能組件创倔,RN端render函數(shù)中以標(biāo)簽形式引用
  • 原生端直接實現(xiàn)所有功能嗡害,RN端直接跳轉(zhuǎn)到原生掃碼界面

第一種方式,掃碼相關(guān)的業(yè)務(wù)邏輯處理還是在RN端畦攘,第二種業(yè)務(wù)邏輯一般都在原生端霸妹,處理完畢后跳回RN頁面。既然我們工程主體是以RN為主知押,所以這里只說明第一種實現(xiàn)掃碼的方式叹螟,第二種方式實現(xiàn)也更簡單,熟悉原生開發(fā)的應(yīng)該都知道怎么做台盯。

這里我使用了第三方的react-native-camera來實現(xiàn)掃碼功能罢绽。二維碼的生成則使用了react-native-qrcode-svg。下面是android和iOS掃碼的效果圖:

android.jpg

ios.png

生成二維碼相對更簡單静盅,先來說明下RN中如何生成二維碼有缆。

生成二維碼

之前在github上搜索了下RN生成二維碼的庫,很多人好像用的都是react-native-qrcode温亲。我自己也嘗試了下棚壁,確實可以生成二維碼,但是生成的二維碼無法識別栈虚,無論用微信袖外、支付寶還是任何其它有掃碼功能的app都識別不了,所以這個庫生成的二維碼是有問題的魂务,根本不能用曼验。

經(jīng)過搜索和實踐之后,我發(fā)現(xiàn)react-native-qrcode-svg才是RN端真正有效的二維碼生成庫粘姜。集成也非常簡單鬓照,使用npm install --save或者yarn add命令安裝react-native-qrcode-svgreact-native-svg孤紧,然后react-native link react-native-svg就行了豺裆。

react-native-svgreact-native-qrcode-svg的基礎(chǔ)庫必須安裝,由react-native-community開源,可靠性更高臭猜。集成完畢后用法如下:

<QRCode
    value={"This is a QR code string, string cannot be null"}
    size={140}
/>

需要注意的是value不能是空字符串“”或者null躺酒,否則會報錯。生成二維碼用任何掃碼功能的app掃都是可以識別的蔑歌,包括本demo中的掃碼功能羹应。具體效果可以查看demo,地址在文末次屠。

掃描二維碼

掃描二維碼推薦使用第三方庫react-native-camera园匹,也是react-native-community出品。這里提醒一下劫灶,RN端很多掃碼的第三方庫也是依賴于此庫的偎肃,而且有些已經(jīng)過期不再維護(hù)了,這是RN端最可靠的掃碼庫浑此。

iOS集成
iOS集成非常簡單累颂,按照文檔說明安裝就可以了。步驟如下:

  1. yarn add react-native-camera安裝
  2. react-native link react-native-camera
  3. 用Xcode打開iOS工程凛俱,找到TARGETS——>點擊target在右側(cè)找到Build Phases——>展開Link Binary With Libraries紊馏,刪掉默認(rèn)link進(jìn)來的libRNCamera,點擊+號重新搜索添加一遍蒲犬。上面link react-native-svg的時候也是這個操作步驟朱监。
  4. 在info.plist中添加相機(jī)使用權(quán)限”Privacy - Camera Usage Description“并寫明使用權(quán)限的用處。

Android集成
安卓端集成有點頭大原叮,react-native-camera的文檔中android的配置有點多赫编。不仔細(xì)讀清楚盲目配置容易出錯。下面是我的demo項目中g(shù)radle的配置:

  1. android/build/gradle配置
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven { url "https://jitpack.io" }
        google()
    }
}

ext {
    buildToolsVersion = "26.0.3"
    minSdkVersion = 16
    compileSdkVersion = 26
    targetSdkVersion = 26
    supportLibVersion = "26.1.0"
}

subprojects {
  project.configurations.all {
     resolutionStrategy.eachDependency { details ->
       if (details.requested.group == 'com.android.support'
             && !details.requested.name.contains('multidex') ) {
          details.useVersion "26.1.0"
      }
    }
  }
}
  1. android/gradle/wrapper/gradle-wrapper.properties中修改distributionUrl為:
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
  1. android/app/build.gradle中主要配置如下(從"android {" 這行開始往下):
android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        applicationId "com.qrcode"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            def versionCodes = ["armeabi-v7a":1, "x86":2]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
}

dependencies {
    compile project(':react-native-camera')
    compile project(':react-native-svg')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    compile "com.facebook.react:react-native:+"  // From node_modules
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

gradle配置需要特別注意保持版本的統(tǒng)一奋隶,不然很容易出錯擂送。

  1. 在AndroidManifest文件中添加權(quán)限:
<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.VIBRATE"/>

其實這里只需要CAMERA和VIBRATE(震動)的權(quán)限就可以了,因為我們只用到了react-native-camera掃碼的功能唯欣,錄視頻和讀寫存儲的沒用到嘹吨。

RN端調(diào)用掃碼

新建一個js頁面作為掃碼頁面,在render函數(shù)中渲染RNCamera組件境氢。需要注意的是在demo中我給Android和iOS都分別指定了組件的掃碼類別type蟀拷。因為我們只需要掃二維碼,所以 指定type以免其它類型的碼也被掃出來了萍聊,這個根據(jù)項目需要設(shè)置问芬。

由于android和iOS原生實現(xiàn)方式不一樣,所以在RN中調(diào)用組件時寿桨,type的屬性名不一致此衅,iOS中是barCodeTypes,它是一個數(shù)組,可以指定多個掃碼類型:

<RNCamera
    style={styles.preview}
    type={RNCamera.Constants.Type.back}
    barCodeTypes={[RNCamera.Constants.BarCodeType.qr]}
    flashMode={RNCamera.Constants.FlashMode.auto}
    onBarCodeRead={(e) => this.barcodeReceived(e)}
>

而android中是googleVisionBarcodeType炕柔,用于單個掃碼類型:

<RNCamera
    style={styles.preview}
    type={RNCamera.Constants.Type.back}
    googleVisionBarcodeType={RNCamera.Constants.GoogleVisionBarcodeDetection.BarcodeType.QR_CODE}
    flashMode={RNCamera.Constants.FlashMode.auto}
    onBarCodeRead={(e) => this.barcodeReceived(e)}
>

總結(jié)

至此RN調(diào)用第三方掃碼和生成二維碼就完成了。主要用到以下庫:

  1. react-native-camera
  2. react-native-qrcode-svg
  3. react-native-svg

RN掃碼用react-native-camera媒佣,界面可以自己發(fā)揮定制匕累。生成二維碼用react-native-qrcode-svg和react-native-svg更可靠。

Demo地址:https://github.com/mrarronz/react-native-blog-examples/tree/master/Chapter12-QRCodeScanGenerate/QRCode

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末默伍,一起剝皮案震驚了整個濱河市欢嘿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌也糊,老刑警劉巖炼蹦,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異狸剃,居然都是意外死亡掐隐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門钞馁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虑省,“玉大人,你說我怎么就攤上這事僧凰√骄保” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵训措,是天一觀的道長伪节。 經(jīng)常有香客問我,道長绩鸣,這世上最難降的妖魔是什么怀大? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮呀闻,結(jié)果婚禮上叉寂,老公的妹妹穿的比我還像新娘。我一直安慰自己总珠,他們只是感情好屏鳍,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著局服,像睡著了一般钓瞭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上淫奔,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天山涡,我揣著相機(jī)與錄音,去河邊找鬼。 笑死鸭丛,一個胖子當(dāng)著我的面吹牛竞穷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鳞溉,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼瘾带,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了熟菲?” 一聲冷哼從身側(cè)響起看政,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抄罕,沒想到半個月后允蚣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡呆贿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年嚷兔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片做入。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡谴垫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出母蛛,到底是詐尸還是另有隱情翩剪,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布彩郊,位于F島的核電站前弯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏秫逝。R本人自食惡果不足惜恕出,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望违帆。 院中可真熱鬧浙巫,春花似錦、人聲如沸刷后。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尝胆。三九已至丧裁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間含衔,已是汗流浹背煎娇。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工二庵, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缓呛。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓催享,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哟绊。 傳聞我的和親對象是個殘疾皇子因妙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容