create-react-native-module 记一下接入商汤银行卡 SDK Android 接入流程
创建库 借助create-react-native-module ,简单步骤如下:
1 2 3 4 5 6 7 npm install -g react-native-cli yarn npm install -g create-react-native-module  create-react-native-module  MyFancyLibrary  npm install
 
经过如上步骤,我们就得到一个模板,然后,我们只需要在我们的主项目,如下步骤,就可以引入改库
1 2 3 dependencies: {    "react-native-my-fancy-library" :  "../react-native-my-fancy-library"   } 
 
最后,yarn install 即可,由于auto-linking  的原因,我们不再需要其他操作.
关于 auto-linking 简单的配置简单列举如下:
react-native.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 module .exports  = {   dependency : {     platforms : {       android : null ,      },   }, };module .exports  = {   dependencies : {     "some-unsupported-package" : {       platforms : {         android : null ,        },     },   }, };module .exports  = {   dependencies : {     "jshare-react-native" : {       platforms : {         android : {           packageInstance : "new JSharePackage(false, false)" ,         },       },     },   }, };
 
autoLink 链接推荐 -auto-linking 的相关介绍 
错误 可能会莫名其妙的一个错误,不知道原因
error: Error: Unable to resolve module warnOnce from node_modules\react-native-my-fancy-library\node_mo dules\react-native\Libraries\react-native\react-native-implementation.js: warnOnce could not be fou nd within the project.
https://github.com/facebook/react-native/issues/24065 
metro.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const  blacklist = require ("metro-config/src/defaults/blacklist" );module .exports  = {      resolver : {     blacklistRE : blacklist ([       /node_modules\/.*\/node_modules\/react-native\/.*/ ,     ]),   },      transformer : {     getTransformOptions : async  () => ({       transform : {         experimentalImportSupport : false ,         inlineRequires : false ,       },     }),   }, };
 
集成 sdk Android studio 打开库项目,gradle 完成后. 步骤如下:
android 目录下 新建 libs,添加 ocr-fullCards-online-release.aar 文件 
 
arr 是一个特殊的 android 二进制代码包,里面 存放 java,xml ..也就是跟我们项目代码一样的文件.
RN 工程 android 目录下的 build.gradle 配置如下: 
 
1 2 3 4 5 6 7 8 allprojects  {     repositories  {         ....         flatDir  {           dirs "$rootDir/../node_modules/react-native-my-fancy-library/libs"          }     } }
 
库项目 build.gradle 配置如下: 
 
1 2 3 4 5 6 7 8 9 10 11   dependencies  {                    implementation 'com.facebook.react:react-native:+'        implementation 'androidx.appcompat:appcompat:1.0.0'        implementation 'com.google.android.material:material:1.0.0'        implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'       implementation fileTree (dir: 'libs' , include : ['*.aar' ]) }
 
复制 SDK 提供的代码,选取 一些必要的功能,迁移到我们的库中. 
 
迁移过程遇到的错误,我们可以根据 android studio 的提示进行解决,
需要注意的点
要注意引入的 Activity,以及在 manifests.xml 文件配置 
迁移 androidManifests 文件时,要注意 AndroidX 包下组件存在问题(包名要正确) 
 
一切直到 android studio 不提示报错,我们就可以进行 androidX 的迁移
迁移 androidX 
 
为了紧跟时代,我们的库必修声明为支持 androidX,local.properties 配置如下
配置如下:
1 2 android.useAndroidX =true android.enableJetifier =true 
 
步骤无非就是 更改包名 ….. 更改 xml 中的包名
旧库映射
https://developer.android.com/jetpack/androidx/migrate/artifact-mappings 
android 支持迁移到 androidX
编写桥接代码 MyFancyLibraryModule.java 文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 package  com.reactlibrary;public  class  MyFancyLibraryModule  extends  ReactContextBaseJavaModule  {     private  static  final  int  REQUEST_CODE_RESULT  =  1 ;     private  static  final  int  REQUEST_CODE_SCAN  =  2 ;     private  Promise mScanBankCardPromise;     private  boolean  mRequestScreenLandscape;     private  final  ReactApplicationContext reactContext;     private  final  ActivityEventListener  mActivityEventListener  =  new  BaseActivityEventListener () {         @Override          public  void  onActivityResult (Activity activity, int  requestCode, int  resultCode, Intent data)  {             if  (requestCode == REQUEST_CODE_RESULT) {                 return ;             }             switch  (resultCode) {                 case  RESULT_CANCELED:                     Toast.makeText(getCurrentActivity(), R.string.canceled, Toast.LENGTH_LONG).show();                     mScanBankCardPromise.reject("RESULT_CANCELED" ,"扫描取消" );                     break ;                 case  ActivityUtils.RESULT_CODE_NO_PERMISSIONS:                 case  ActivityUtils.RESULT_CODE_CAMERA_ERROR:                     Toast.makeText(getCurrentActivity(), R.string.error_camera, Toast.LENGTH_LONG).show();                     mScanBankCardPromise.reject("RESULT_CODE_CAMERA_ERROR" ,"相机发生错误" );                     break ;                 case  ActivityUtils.RESULT_CODE_LICENSE_FILE_NOT_FOUND:                     Toast.makeText(getCurrentActivity(), R.string.license_file_not_found, Toast.LENGTH_LONG).show();                     mScanBankCardPromise.reject("RESULT_CODE_LICENSE_FILE_NOT_FOUND" ,"授权文件未发现" );                     break ;                                 case  Activity.RESULT_OK:                                          HashMap map=new  HashMap ();                     final  String  EXTRA_CARD_NUMBER  =  "extra_card_number" ;                     final  String  EXTRA_BANK_NAME  =  "extra_bank_name" ;                     final  String  EXTRA_BANK_ID  =  "extra_bank_id" ;                     final  String  EXTRA_CARD_NAME  =  "extra_card_name" ;                     final  String  EXTRA_CARD_TYPE  =  "extra_card_type" ;                     final  String  EXTRA_CARD_RESULT_IMAGE  =  "extra_card_result_image" ;                                          map.put(EXTRA_CARD_NUMBER,data.getStringExtra(EXTRA_CARD_NUMBER));                     map.put(EXTRA_BANK_NAME,data.getStringExtra(EXTRA_BANK_NAME));                     map.put(EXTRA_BANK_ID,data.getStringExtra(EXTRA_BANK_ID));                     map.put(EXTRA_CARD_TYPE,data.getStringExtra(EXTRA_CARD_TYPE));                     map.put(EXTRA_CARD_NAME,data.getStringExtra(EXTRA_CARD_NAME));                     map.put(EXTRA_CARD_RESULT_IMAGE,data.getStringExtra(EXTRA_CARD_RESULT_IMAGE));                     mScanBankCardPromise.resolve(map);                     break ;                 default :                     break ;             }         }     };     public  MyFancyLibraryModule (ReactApplicationContext reactContext)  {         super (reactContext);         this .reactContext = reactContext;                  reactContext.addActivityEventListener(mActivityEventListener);     }     @Override      public  String getName ()  {         return  "MyFancyLibrary" ;       }          @ReactMethod      public   void   registerSenseTime (String appId, String key) {         AppSecret.setKeyAndSecret(appId,key);     }          @ReactMethod  void  scanCard (String orientation, Promise promise) {                  if (orientation.equals("horizontal" )){             mScanBankCardPromise=promise;             checkPermissionToDetect(BankCardActivity.CARD_ORIENTATION_HORIZONTAL);         }         if (orientation.equals("vertical" )){             checkPermissionToDetect(BankCardActivity.CARD_ORIENTATION_VERTICAL);         }     }     private  void  checkPermissionToDetect (int  cardOrientation)  {                if  (Build.VERSION.SDK_INT >= 23 ) {             List<String> permissions = null ;             if  (ContextCompat.checkSelfPermission(reactContext,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {                 permissions = new  ArrayList <>();                 permissions.add(Manifest.permission.CAMERA);             }             if  (ContextCompat.checkSelfPermission(reactContext,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {                 if  (permissions == null ) {                     permissions = new  ArrayList <>();                 }                 permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);             }             if  (permissions != null ) {                 String[] permissionArray = new  String [permissions.size()];                 permissions.toArray(permissionArray);                                                   ActivityCompat.requestPermissions(getCurrentActivity(),permissionArray, cardOrientation);             } else  {                                startDetectActivity(cardOrientation);             }         } else  {             startDetectActivity(cardOrientation);         }     }     private  void  startDetectActivity (int  cardOrientation)  {         Intent  intent  =  new  Intent (getCurrentActivity(),                 this .mRequestScreenLandscape ? LandscapeScanActivity.class : PortraitScanActivity.class);         intent.putExtra(BankCardActivity.EXTRA_CARD_ORIENTATION, cardOrientation);                      getCurrentActivity().startActivityForResult(intent, REQUEST_CODE_SCAN);     } }
 
至此,我们就完成了 android 模块的集成,只等 JS 端调用 即可,代码如下:
1 2 3 4 import  MyFancyLibrary  from  "react-native-my-fancy-library" ;MyFancyLibrary .scanCard ("horizontal" )   .then ((res ) =>  {})   .catch ((e ) =>  {});