赞
踩
例如:项目场景:现场每个环节需要用到NFC芯片来读写数据,网上找了很多都没有符合要求的,只能根据芯片的类型来找对应的解决方案,然后整合到一起,下面我会着重讲一下每一步怎么操作。
简单的描述一下这个过程,可能不准确,大家理解即可。
NFC芯片的类型: ISO15693
此类芯片我们按要求写入到指定的块区域,读取也是一样。具体请查询有关ISO15693协议文档,这里不做赘述。
1、第一步先去uniapp官网下载demo,然后根据以下代码自行修改,关于什么appkey配置什么的自行研究。地址:https://nativesupport.dcloud.net.cn/AppDocs/
使用Android Studio打开下载好的uniapp文件,选择以下的模块打开。
2、
package io.dcloud.uniplugin; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import com.alibaba.fastjson.JSONObject; import io.dcloud.feature.uniapp.annotation.UniJSMethod; import io.dcloud.feature.uniapp.bridge.UniJSCallback; import io.dcloud.feature.uniapp.common.UniModule; public class TestModule extends UniModule { //定义一个标签,用于uniapp调API之前,指定哪个标签 String TAG = "TestModule"; public static int REQUEST_CODE = 1000; //这个是重点,你需要返回到当前uniapp请求的JS的回调里面,声明全局变量,下面第三个方法会用到 private UniJSCallback mCallback; //这个就是安卓原生里面的写入接口 @UniJSMethod(uiThread = true) public void writeFunc(JSONObject options, UniJSCallback callback) { //上面传入的options,就是uniapp JS方法传入的参数 this.mCallback = callback; Log.e(TAG, "writeFunc--"+options); if(callback != null) { if(mUniSDKInstance != null && mUniSDKInstance.getContext() instanceof Activity) { //跳转到写标签的Activity里面,这样才能操作NFC读写芯片 Intent intent = new Intent(mUniSDKInstance.getContext(), NativePage2Activity.class); Bundle bundle = new Bundle(); //这里是需要向跳转的Activity里面传你需要处理的数据 bundle.putString("参数1","xxx"); intent.putExtras(bundle); ((Activity)mUniSDKInstance.getContext()).startActivityForResult(intent, REQUEST_CODE); } } } //这个就是安卓原生里面的读取接口 @UniJSMethod (uiThread = false) public void readFunc(JSONObject options, UniJSCallback callback){ //上面传入的options,就是uniapp JS方法传入的参数 this.mCallback = callback; Log.e(TAG, "readFunc--"+options); if(callback != null) { if(mUniSDKInstance != null && mUniSDKInstance.getContext() instanceof Activity) { //跳转到读标签的Activity里面,这样才能操作NFC读写芯片 Intent intent = new Intent(mUniSDKInstance.getContext(), NativePageActivity.class); Bundle bundle = new Bundle(); //这里是需要向跳转的Activity里面传你需要处理的数据 bundle.putString("参数1","xxx"); intent.putExtras(bundle); ((Activity)mUniSDKInstance.getContext()).startActivityForResult(intent, REQUEST_CODE); } } } //这个方法就是接收上面读写API调转Activity后读写成功并返回的方法 //接收到返回数据后,将数据通过mCallback,返回给uniapp @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == REQUEST_CODE && data.hasExtra("respond")) { String string = data.getStringExtra("respond"); Log.e("TestModule", "原生页面返回----"+string); mCallback.invoke(string); } else { super.onActivityResult(requestCode, resultCode, data); } } //这是自带的,可忽略 @UniJSMethod (uiThread = true) public void gotoNativePage(){ if(mUniSDKInstance != null && mUniSDKInstance.getContext() instanceof Activity) { Intent intent = new Intent(mUniSDKInstance.getContext(), NativePageActivity.class); ((Activity)mUniSDKInstance.getContext()).startActivityForResult(intent, REQUEST_CODE); } } }
3、写入Activity
package io.dcloud.uniplugin; import android.app.Activity; import android.app.PendingIntent; import android.content.Intent; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.NfcV; import android.os.Bundle; import android.util.Log; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.alibaba.fastjson.JSONObject; import java.io.IOException; public class NativePage2Activity extends Activity { String TAG = "TestModule"; public NfcV nfcV; public NfcVUtil util; private NfcAdapter mNfcAdapter; private PendingIntent mPendingIntent; private TextView mContent; String data = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); Bundle bundle = this.getIntent().getExtras(); mContent = findViewById(R.id.content); mContent.setText(bundle.getString("参数1")); } @Override protected void onStart() { super.onStart(); mNfcAdapter = NfcAdapter.getDefaultAdapter(this); // 用于感应到NFC时启动该Activity // 这里建议将处理NFC的子类的launchMode设置成singleTop模式,这样感应到标签时就会回调onNewIntent,而不会重复打开页面 mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), 0); } /** * 获得焦点,按钮可以点击 */ @Override public void onResume() { super.onResume(); // 设置当该页面处于前台时,NFC标签会直接交给该页面处理 if (mNfcAdapter != null) { mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); } } /** * 暂停Activity,界面获取焦点,按钮可以点击 */ @Override public void onPause() { super.onPause(); // 当页面不可见时,NFC标签不交给当前页面处理 if (mNfcAdapter != null) { mNfcAdapter.disableForegroundDispatch(this); } } @Override public void onNewIntent(Intent intent) { Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if (detectedTag != null) { byte[] aa = detectedTag.getId(); String str = ByteArrayToHexString(aa); String UID = flipHexStr(str); // Toast.makeText(this, "RFID已经连接", // Toast.LENGTH_LONG).show(); try { nfcV = NfcV.get(detectedTag); if (nfcV != null) { nfcV.connect();//建立连接 util = new NfcVUtil(nfcV);//创建工具类,操作连接 } data = ""; write(); } catch (Exception e) { e.printStackTrace(); } } } public void write() { if (!isEnable()) { return; } try { String info = mContent.getText().toString(); info.replaceAll("[^a-zA-Z0-9]", ""); //为a-f的8长度的字符串,转换成byte数组长度为4 //第一个参数为块索引,第二个参数为4长度的byte数组。如数据不够,需要补位 if (info.length() == 0) { Toast.makeText(this, "字符不能为空", Toast.LENGTH_LONG).show(); return; } if (info.length() > 50) { Toast.makeText(this, "超出限制50字符", Toast.LENGTH_LONG).show(); return; } //这里代表,在每次写入之前都要清空,这里暂定50个字符,大家自行调整 for (int i = 2; i <= 14; i++) { if (i != 14) { util.writeBlock(i, util.hexStringToBytes("00000000")); } else { util.writeBlock(i, util.hexStringToBytes("0000")); } } boolean flag = false; int len = info.length() / 4; if (info.length() > 4 * len) { len = len + 1; flag = true; } boolean b = false; String substring = ""; for (int i = 0; i < len; i++) { if (i == len - 1 && flag) { substring = info.substring(i * 4); } else { substring = info.substring(i * 4, (i + 1) * 4); } b = util.writeBlock((2 + i), util.hexStringToBytes(stringToHex(substring))); } if (b) { Toast.makeText(this, "写入成功", Toast.LENGTH_LONG).show(); } else { Toast.makeText(this, "写入失败", Toast.LENGTH_LONG).show(); } } catch (IOException e) { e.printStackTrace(); } } public static String stringToHex(String input) { StringBuilder hexString = new StringBuilder(); for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); hexString.append(Integer.toHexString((int) c)); } return hexString.toString(); } public static String flipHexStr(String s) { StringBuilder result = new StringBuilder(); for (int i = 0; i <= s.length() - 2; i = i + 2) { result.append(new StringBuilder(s.substring(i, i + 2)).reverse()); } return result.reverse().toString(); } public String ByteArrayToHexString(byte[] inarray) { int i, j, in; String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; String out = ""; for (j = inarray.length - 1; j >= 0; j--) { in = (int) inarray[j] & 0xff; i = (in >> 4) & 0x0f; out += hex[i]; i = in & 0x0f; out += hex[i]; } return out; } public boolean isEnable() { if (util == null) { //请先连接RFID卡 return false; } if (nfcV == null) { //请先连接RFID卡 return false; } if (!nfcV.isConnected()) { //接连中断,请重新连接 return false; } return true; } }
这是写入弹出的页面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView" android:layout_marginTop="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@drawable/icon_scan" /> <TextView android:id="@+id/content" android:textSize="16dp" android:gravity="center_horizontal" android:textStyle="bold" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:layout_marginTop="5dp" android:id="@+id/content2" android:textSize="15dp" android:hint="靠近标签自动写入数据" android:gravity="center_horizontal" android:textColorHint="#95A1AA" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="30dp" /> </LinearLayout>
页面大概是这样的,图片自行更换,这里就不贴出。
4、读取Activity
package io.dcloud.uniplugin; import android.app.Activity; import android.app.PendingIntent; import android.content.Intent; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.NfcV; import android.os.Bundle; import android.os.Looper; import android.util.Log; import android.widget.Toast; import com.alibaba.fastjson.JSONObject; import java.io.IOException; public class NativePageActivity extends Activity { String TAG = "TestModule"; public NfcV nfcV; public NfcVUtil util; private NfcAdapter mNfcAdapter; private PendingIntent mPendingIntent; String data = ""; String xxx= ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Bundle bundle = this.getIntent().getExtras(); xxx= bundle.getString("参数1"); } @Override protected void onStart() { super.onStart(); mNfcAdapter = NfcAdapter.getDefaultAdapter(this); // 用于感应到NFC时启动该Activity // 这里建议将处理NFC的子类的launchMode设置成singleTop模式,这样感应到标签时就会回调onNewIntent,而不会重复打开页面 mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), 0); } /** * 获得焦点,按钮可以点击 */ @Override public void onResume() { super.onResume(); // 设置当该页面处于前台时,NFC标签会直接交给该页面处理 if (mNfcAdapter != null) { mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null); } } /** * 暂停Activity,界面获取焦点,按钮可以点击 */ @Override public void onPause() { super.onPause(); // 当页面不可见时,NFC标签不交给当前页面处理 if (mNfcAdapter != null) { mNfcAdapter.disableForegroundDispatch(this); } } @Override public void onNewIntent(Intent intent) { Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if (detectedTag != null) { byte[] aa = detectedTag.getId(); String str = ByteArrayToHexString(aa); String UID = flipHexStr(str); // Toast.makeText(this, "RFID已经连接", // Toast.LENGTH_SHORT).show(); try { nfcV = NfcV.get(detectedTag); if (nfcV != null) { nfcV.connect();//建立连接 util = new NfcVUtil(nfcV);//创建工具类,操作连接 } data = ""; read(); } catch (Exception e) { e.printStackTrace(); } } } public void read() { if (!isEnable()) { return; } 这里从第2块区域读50个字符,0,1块号主要是芯片定义好的身份信息 int blockText2 = 2; int blockNum2 = 13; try { int i; for (i = blockText2; i <= blockNum2 + blockText2 - 1; ++i) { String readOneBlockStr = util.readOneBlock(i);//读取block在1位置的内容 data = data + readOneBlockStr; } data = data.replaceAll("[^a-zA-Z0-9]", ""); //这里将读取的数据,返回到接口类中 Intent intent = new Intent(); intent.putExtra("respond", data); setResult(TestModule.REQUEST_CODE, intent); finish(); } catch (IOException e) { e.printStackTrace(); } } public static String flipHexStr(String s) { StringBuilder result = new StringBuilder(); for (int i = 0; i <= s.length() - 2; i = i + 2) { result.append(new StringBuilder(s.substring(i, i + 2)).reverse()); } return result.reverse().toString(); } public String ByteArrayToHexString(byte[] inarray) { int i, j, in; String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}; String out = ""; for (j = inarray.length - 1; j >= 0; j--) { in = (int) inarray[j] & 0xff; i = (in >> 4) & 0x0f; out += hex[i]; i = in & 0x0f; out += hex[i]; } return out; } public boolean isEnable() { if (util == null) { //请先连接RFID卡 return false; } if (nfcV == null) { //请先连接RFID卡 return false; } if (!nfcV.isConnected()) { //接连中断,请重新连接 return false; } return true; } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView" android:layout_marginTop="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@drawable/icon_scan" /> <TextView android:layout_marginTop="20dp" android:id="@+id/content" android:textSize="15dp" android:hint="靠近标签自动读取数据" android:gravity="center_horizontal" android:textColorHint="#95A1AA" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="30dp" /> </LinearLayout>
5、NFC工具类,自行导入
package io.dcloud.uniplugin; import android.nfc.tech.NfcV; import java.io.IOException; public class NfcVUtil { private NfcV mNfcV; /**UID数组行式*/ private byte[] ID; private String UID; private String DSFID; private String AFI; /**block的个数*/ private int blockNumber; /**一个block长度*/ private int oneBlockSize; /**信息*/ private byte[] infoRmation; /** * 初始化 * @param mNfcV NfcV对象 * @throws IOException */ public NfcVUtil(NfcV mNfcV) throws IOException{ this.mNfcV = mNfcV; ID = this.mNfcV.getTag().getId(); byte[] uid = new byte[ID.length]; int j = 0; for(int i = ID.length - 1; i >=0; i-- ){ uid[j] = ID[i]; j++; } this.UID = printHexString(uid); getInfoRmation();//获取标签的信息 } public String getUID() { return UID; } /** * 取得标签信息 */ private byte[] getInfoRmation() throws IOException{ byte[] cmd = new byte[10]; cmd[0] = (byte) 0x22; // flag cmd[1] = (byte) 0x2B; // command System.arraycopy(ID, 0, cmd, 2, ID.length); // UID infoRmation = mNfcV.transceive(cmd); blockNumber = infoRmation[12];//可使用的数据块数量,一般为27 oneBlockSize = infoRmation[13];//每个块byte数组的长度,一般为4 AFI = printHexString(new byte[]{infoRmation[11]});//AFI值在某些领域会需要使用 DSFID = printHexString(new byte[]{infoRmation[10]});//DSFID值 return infoRmation; } /** * 写入AFI数据 * @param b * @return * @throws IOException */ public boolean setAFIState(byte b) throws IOException { byte[] cmd = new byte[11]; cmd[0] = (byte) 0x22; // flag cmd[1] = (byte) 0x27; // command System.arraycopy(ID, 0, cmd, 2, ID.length); // UID cmd[10] = b; byte[] res = mNfcV.transceive(cmd); if(res[0] == 0x00){ byte[] cmdNew = new byte[10]; cmdNew[0] = (byte) 0x22; // flag cmdNew[1] = (byte) 0x2B; // command System.arraycopy(ID, 0, cmdNew, 2, ID.length); // UID AFI = printHexString(new byte[]{infoRmation[11]}); DSFID = printHexString(new byte[]{infoRmation[10]}); return true; //千万不要锁定,不可逆 // byte[] cmd2 = new byte[10]; // cmd2[0] = (byte) 0x22; // flag // cmd2[1] = (byte) 0x28; // command // System.arraycopy(ID, 0, cmd2, 2, ID.length); // UID // byte[] res2 = mNfcV.transceive(cmd2); // if(res2[0] == 0x00){ // return true; // } } return false; } /** * 写入DSFID数据 * @param b * @return * @throws IOException */ public boolean setDSFIDState(byte b) throws IOException { byte[] cmd = new byte[11]; cmd[0] = (byte) 0x22; // flag cmd[1] = (byte) 0x29; // command System.arraycopy(ID, 0, cmd, 2, ID.length); // UID cmd[10] = b; byte[] res = mNfcV.transceive(cmd); if(res[0] == 0x00){ byte[] cmdNew = new byte[10]; cmdNew[0] = (byte) 0x22; // flag cmdNew[1] = (byte) 0x2B; // command System.arraycopy(ID, 0, cmdNew, 2, ID.length); // UID AFI = printHexString(new byte[]{infoRmation[11]}); DSFID = printHexString(new byte[]{infoRmation[10]}); return true; //千万不要锁定,不可逆 // byte[] cmd2 = new byte[10]; // cmd2[0] = (byte) 0x22; // flag // cmd2[1] = (byte) 0x2A; // command // System.arraycopy(ID, 0, cmd2, 2, ID.length); // UID // byte[] res2 = mNfcV.transceive(cmd2); // if(res2[0] == 0x00){ // return true; // } } return false; } public String getDSFID() { return DSFID; } public String getAFI() { String temp = String.valueOf(mNfcV.getDsfId()); // return AFI; return temp + AFI; } /** * 读取一个位置在position的block * @param position 要读取的block位置 * @return 返回内容字符串 * @throws IOException */ public String readOneBlock(int position) throws IOException{ byte cmd[] = new byte[12]; cmd[0] = (byte) 0x22; cmd[1] = (byte) 0x23;//0x20 System.arraycopy(ID, 0, cmd, 2, ID.length); // UID cmd[10] = (byte) position; cmd[11] = (byte) 0; byte res[] = mNfcV.transceive(cmd); if(res[0] == 0x00){ byte block[] = new byte[res.length - 1]; System.arraycopy(res, 1, block, 0, res.length - 1); return AToString(block); } return null; } public String AToString(byte block[]){ StringBuffer s = new StringBuffer(); for (int i = 0; i < block.length; i++) { s.append(Character.toString((char)block[i])); } return s.toString(); } /** * String转Hex格式Byte[] * @param hexString * @return */ public byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } /** * 将byte[]转换成16进制字符串 * @param data 要转换成字符串的字节数组 * @return 16进制字符串 */ private String printHexString(byte[] data) { StringBuffer s = new StringBuffer(); for (int i = 0; i < data.length; i++) { String hex = Integer.toHexString(data[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } s.append(hex); } return s.toString(); } //结果大写 private String ByteArrayToHexString(byte[] inarray) { int i, j, in; String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; String out = ""; for (j = inarray.length - 1; j >= 0 ; j--) { in = (int) inarray[j] & 0xff; i = (in >> 4) & 0x0f; out += hex[i]; i = in & 0x0f; out += hex[i]; } return out; } /** * 将数据写入到block, * @param position 要写内容的block位置 * @param data 要写的内容,必须长度为blockOneSize * @return false为写入失败,true为写入成功 * @throws IOException */ public boolean writeBlock(int position, byte[] data) throws IOException{ byte cmd[] = new byte[15]; cmd[0] = (byte) 0x22; cmd[1] = (byte) 0x21; System.arraycopy(ID, 0, cmd, 2, ID.length); // UID //block cmd[10] = (byte) position; //value System.arraycopy(data, 0, cmd, 11, data.length); byte[]rsp = mNfcV.transceive(cmd); if(rsp[0] == 0x00) return true; return false; } }
6、AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.dcloud.uniplugin"> <!-- 添加NFC权限 --> <uses-permission android:name="android.permission.NFC" /> <!-- 要求当前设备必须要有NFC芯片 --> <uses-feature android:name="android.hardware.nfc" android:required="true" /> <application> <activity android:name="io.dcloud.uniplugin.NativePageActivity" android:exported="true" android:label="@string/app_name" android:launchMode="singleTop" android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar.MinWidth"> <intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter> </activity> <activity android:name="io.dcloud.uniplugin.NativePage2Activity" android:exported="true" android:label="@string/app_name2" android:launchMode="singleTop" android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar.MinWidth"> <intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter> </activity> <meta-data android:name="dcloud_appkey" android:value="这里自己去uniapp官网申请" /> </application> </manifest> strings.xml配置 <resources> <string name="app_name">读电子标签</string> <string name="app_name2">写电子标签</string> </resources>
7、build.gradle配置,根据个人SDK版本来配置
apply plugin: 'com.android.library' android { namespace 'io.dcloud.uniplugin' compileSdkVersion 29 defaultConfig { minSdkVersion 16 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } repositories { flatDir { dirs 'libs' } } dependencies { compileOnly fileTree(dir: 'libs', include: ['*.jar']) compileOnly fileTree(dir: '../app/libs', include: ['uniapp-v8-release.aar']) compileOnly 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' compileOnly 'androidx.recyclerview:recyclerview:1.0.0' compileOnly 'androidx.core:core:1.1.0' compileOnly 'androidx.fragment:fragment:1.1.0' compileOnly 'androidx.appcompat:appcompat:1.1.0' compileOnly 'androidx.recyclerview:recyclerview:1.1.0' compileOnly 'com.alibaba:fastjson:1.2.83' compileOnly 'androidx.legacy:legacy-support-v4:1.0.0' compileOnly 'androidx.appcompat:appcompat:1.0.0' implementation 'com.alibaba:fastjson:1.2.83' implementation 'com.facebook.fresco:fresco:1.13.0' implementation 'com.squareup.okhttp3:okhttp:3.2.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0' implementation 'com.google.code.gson:gson:2.8.5' }
7、前端示例,只展示关键代码
<script> let testModule = uni.requireNativePlugin("TestModule") export default { components: {}, methods: { writeFunc() { testModule.writeFunc({ xx:this.formData.xx }, (ret) => { //这里的ret就是前面返回的值,直接取 console.log(ret) }) }, readFunc() { testModule.readFunc({ xx:this.formData.xx }, (ret) => { //这里的ret就是前面返回的值,直接取 console.log(ret) }) } } } </script>
8、原生安卓打包成SDK供uniapp集成使用,将以下打包成功的.aar文件放到uniapp工程里。有两种打包方式,第一种是把安卓原生打包成SDK放到uniapp里面调用(推荐),第二种是把uniapp打包成安卓基座,导入到安卓原生代码里进行打包,比较麻烦一点。
把导包文件放到uniapp此目录里,没有目录可以创建,不知道原理的可以去研究研究
1、各位朋友,请聚焦在具体的调用原生安卓逻辑上面,关于怎么打包可自行去搜索相关文章,这里就不过多描述(主要是步骤太多太麻烦了)
2、在此基础上还可以延伸至其他领域,比如刷工牌登录系统、门禁、物料标签等等
3、如果有不明白的地方可留言,我空余时间会尽自己所能给大家解答,谢谢大家!
来自一个被编程耽搁的健身教练编写于公元2024年5月14日
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。