android 蓝牙通讯

权限:


    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
//不需要进行动态授权

代码:



	ListView list_divice;

    List<String> list_infos= new ArrayList<String>();
    BluetoothAdapter btAdapt;
    BlueToothDeviceAdapter<String> myAdapter;

	//初始化
	list_divice= (ListView) this.findViewById(R.id.lvDevices);
    myAdapter= new BlueToothDeviceAdapter(this, list_infos);
    list_divice.setAdapter(adtDevices);
   	list_divice.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        if (btAdapt.getState() != BluetoothAdapter.STATE_ON) {// 如果蓝牙还没开启
                            Toast.makeText(context, "请开启蓝牙", 1000).show();
                            return;
                        }

                        if (btAdapt.isDiscovering())
                            btAdapt.cancelDiscovery();
                        String str = lstDevices.get(position);
                        if (str == null | str.equals(""))
                            return;
                        String[] values = str.split("\\|");
                        String address = values[1];
                        Log.e(Common.TAG, values[1]);
                        try {
                            Intent intMain = new Intent(context, BlueToothDeviceActivity.class);
                            Bundle bd = new Bundle();
                            bd.putString("NAME", values[0]);
                            bd.putString("MAC", values[1]);
                            intMain.putExtras(bd);
                            context.startActivity(intMain);
                        } catch (Exception e) {
                            Log.d("Common.TAG", "Error connected to: " + address);
                            e.printStackTrace();
                        }
                    });

        btAdapt = BluetoothAdapter.getDefaultAdapter();
        if (btAdapt == null) {
            Toast.makeText(getBaseContext(), "您的机器上没有发现蓝牙适配器,本程序将不能运行!", Toast.LENGTH_SHORT).show();
            this.finish();
        }
 // 注册Receiver来获取蓝牙设备相关的结果
        IntentFilter intent = new IntentFilter();
        intent.addAction(BluetoothDevice.ACTION_FOUND); // 用BroadcastReceiver来取得搜索结果
        intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(searchDevices, intent);

        addPairedDevice();


private BroadcastReceiver searchDevices = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(BluetoothDevice.ACTION_FOUND)) { //found device
                BluetoothDevice device = intent
                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String str = device.getName() + "|" + device.getAddress();

                if (lstDevices.indexOf(str) == -1)// 防止重复添加
                    lstDevices.add(str); // 获取设备名称和mac地址
                adtDevices.notifyDataSetChanged();

            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
                btnDis.setText("正在扫描");
                btnDis.setTextColor(Color.RED);
            } else if (action
                    .equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                btnDis.setText("扫描设备");
                btnDis.setTextColor(Color.BLACK);
                Toast.makeText(getBaseContext(), "扫描完成,点击列表中的设备来尝试连接", Toast.LENGTH_SHORT).show();
            }
        }
    };

    private void addPairedDevice() // 增加配对设备
    {
        Set<BluetoothDevice> pairedDevices = btAdapt.getBondedDevices();
        if (pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                String str = device.getName() + "|" + device.getAddress();
                lstDevices.add(str);
                adtDevices.notifyDataSetChanged();
            }
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        android.os.Process.killProcess(android.os.Process.myPid());
    }


// 按钮点击事件:
if (v == btnDis)// 搜索设备
            {
                if (btAdapt.getState() != BluetoothAdapter.STATE_ON) {// 如果蓝牙还没开启
                    Toast.makeText(getBaseContext(), "请先开启蓝牙", Toast.LENGTH_SHORT).show();
                    return;
                }

                if (!btAdapt.isDiscovering()) {
                    lstDevices.clear();
                    addPairedDevice();
                    btAdapt.startDiscovery();
                }

2、showdetail.activity


public class showDetail extends Activity {
public static String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    private InputStream mmInStream;
    private OutputStream mmOutStream;
    ScrollView svResult;
    private static final String TAG="showDetail";
    Button btnExit, btnAll;
    Button btn02, btn03, btn04, btn05, btn06, btn07, btn08, btn09, btn10,
            btn11;
    TextView tvTitle, tvLog,tv_shousuo,tv_shuzhang,tv_maibo;

    BluetoothAdapter btAdapt = null;
    BluetoothSocket btSocket = null;

    Boolean bConnect = false;
    String strName = null;
    String strAddress = null;
    int nNeed = 0;
    byte[] bRecv = new byte[1024];
    int nRecved = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.detail);

        svResult = (ScrollView) findViewById(R.id.svResult);

        btnExit = (Button) this.findViewById(R.id.btnExit);
        btnExit.setOnClickListener(new ClickEvent());
        btnAll = (Button) this.findViewById(R.id.btnAll);
        btnAll.setOnClickListener(new ClickEvent());

        btn02 = (Button) this.findViewById(R.id.btn02);
        btn02.setOnClickListener(new ClickEvent());
        btn02.setId(0);
        btn03 = (Button) this.findViewById(R.id.btn03);
        btn03.setOnClickListener(new ClickEvent());
        btn03.setId(0);
        btn04 = (Button) this.findViewById(R.id.btn04);
        btn04.setOnClickListener(new ClickEvent());
        btn04.setId(0);
        btn05 = (Button) this.findViewById(R.id.btn05);
        btn05.setOnClickListener(new ClickEvent());
        btn05.setId(0);
        btn06 = (Button) this.findViewById(R.id.btn06);
        btn06.setOnClickListener(new ClickEvent());
        btn06.setId(0);
        btn07 = (Button) this.findViewById(R.id.btn07);
        btn07.setOnClickListener(new ClickEvent());
        btn07.setId(0);
        btn08 = (Button) this.findViewById(R.id.btn08);
        btn08.setOnClickListener(new ClickEvent());
        btn08.setId(0);
        btn09 = (Button) this.findViewById(R.id.btn09);
        btn09.setOnClickListener(new ClickEvent());
        btn09.setId(0);
        btn10 = (Button) this.findViewById(R.id.btn10);
        btn10.setOnClickListener(new ClickEvent());
        btn10.setId(0);
        btn11 = (Button) this.findViewById(R.id.btn11);
        btn11.setOnClickListener(new ClickEvent());
        btn11.setId(0);


        tvTitle = (TextView) this.findViewById(R.id.tvTitle);
        tvLog = (TextView) this.findViewById(R.id.tvLog);
        tv_maibo=findViewById(R.id.tv_maibo);
        tv_shousuo=findViewById(R.id.tv_shousuo);
        tv_shuzhang=findViewById(R.id.tv_shuzhang);
        Bundle bunde = this.getIntent().getExtras();
        strName = bunde.getString("NAME");
        strAddress = bunde.getString("MAC");
        tvTitle.setText(strName);
        tvLog.append(strName + "......\n");

        btAdapt = BluetoothAdapter.getDefaultAdapter();
        if (btAdapt == null) {
            tvLog.append("本机无蓝牙,连接失败\n");
            finish();
            return;
        }

        if (btAdapt.getState() != BluetoothAdapter.STATE_ON) {
            tvLog.append("本机蓝牙状态不正常,连接失败\n");
            finish();
            return;
        }

        IntentFilter intent = new IntentFilter();
        intent.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        intent.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);

        registerReceiver(connectDevices, intent);

        setButtonEnable(false);
        mHandler.sendEmptyMessageDelayed(Common.MESSAGE_CONNECT, 1000);
    }

    @SuppressLint("ResourceType")
    public void setButtonColor(Button btn, Boolean bOn) {
        if (bOn) {
            btn.setTextColor(Color.GREEN);
            btn.setId(1);
        } else {
            btn.setTextColor(Color.BLACK);
            btn.setId(0);
        }
    }

    public void setButtonEnable(Boolean bOn) {
        if (bOn) {
            btn02.setEnabled(true);
            btn03.setEnabled(true);
            btn04.setEnabled(true);
            btn05.setEnabled(true);
            btn06.setEnabled(true);
            btn07.setEnabled(true);
            btn08.setEnabled(true);
            btn09.setEnabled(true);
            btn10.setEnabled(true);
            btn11.setEnabled(true);
            btnAll.setEnabled(true);
        } else {
            btn02.setEnabled(false);
            btn03.setEnabled(false);
            btn04.setEnabled(false);
            btn05.setEnabled(false);
            btn06.setEnabled(false);
            btn07.setEnabled(false);
            btn08.setEnabled(false);
            btn09.setEnabled(false);
            btn10.setEnabled(false);
            btn11.setEnabled(false);
            btnAll.setEnabled(false);
        }
    }

    // Hander
    public final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Common.MESSAGE_CONNECT:
                    new Thread(new Runnable() {
                        public void run() {
                            InputStream tmpIn;
                            OutputStream tmpOut;
                            try {

                                UUID uuid = UUID.fromString(SPP_UUID);
                                BluetoothDevice btDev = btAdapt
                                        .getRemoteDevice(strAddress);
                                btSocket = btDev
                                        .createRfcommSocketToServiceRecord(uuid);
                                btSocket.connect();
                                tmpIn = btSocket.getInputStream();
                                tmpOut = btSocket.getOutputStream();
                            } catch (Exception e) {
                                Log.d(Common.TAG, "Error connected to: "
                                        + strAddress);
                                bConnect = false;
                                mmInStream = null;
                                mmOutStream = null;
                                btSocket = null;
                                e.printStackTrace();
                                mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_LOST);
                                return;
                            }
                            mmInStream = tmpIn;
                            mmOutStream = tmpOut;
                            mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_SUCCEED);
                        }

                    }).start();
                    break;
                case Common.MESSAGE_CONNECT_SUCCEED:
                    addLog("连接成功");
                    setButtonEnable(true);
                    bConnect = true;
                    new Thread(new Runnable() {
                        public void run() {
                            byte[] bufRecv = new byte[1024];
                            int nRecv = 0;
                            while (bConnect) {
                                try {
                                    /**1、start,防止数据流分多次被读出**/
                                    if(mmInStream.available()>0 == false){
                                        continue;
                                    }else{
                                        Thread.sleep(200);
                                    }
                                    /**1、end**/

                                    nRecv = mmInStream.read(bufRecv);
//                                    if (nRecv < 1) {
//                                        Thread.sleep(100);
//                                        continue;
//                                    }
//                                    System.arraycopy(bufRecv, 0, bRecv, nRecved, nRecv);



//                                    System.arraycopy(bufRecv, 0, bRecv, 0, nRecv);
//                                    nRecved += nRecv;
//                                    if(nRecved < nNeed)
//                                    {
//                                        Thread.sleep(100);
//                                        continue;
//                                    }
//                                    mHandler.obtainMessage(Common.MESSAGE_RECV, nNeed, -1, null).sendToTarget();

                                    byte[] content=new byte[nRecv];
                                    System.arraycopy(bufRecv,0,content,0,nRecv);

//                                    A0 00 00 68 4B 45 00 F8 A0 00 00 68 4B 45 00 F8

                                    String contentString=bytesToString(content);
                                    Message msg=new Message();
                                    msg.what=Common.MESSAGE_RECV;
                                    msg.obj=contentString;
                                    mHandler.sendMessage(msg);

                                } catch (Exception e) {
                                    Log.e(Common.TAG, "Recv thread:" + e.getMessage());
                                    mHandler.sendEmptyMessage(Common.MESSAGE_EXCEPTION_RECV);
                                    break;
                                }
                            }
                            Log.e(Common.TAG, "Exit while");
                        }
                    }).start();
                    break;
                case Common.MESSAGE_EXCEPTION_RECV:
                    mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_SUCCEED);
                    Log.e("TAG", "handleMessag已重新连接 " );
                    break;
                case Common.MESSAGE_CONNECT_LOST:
                    addLog("连接异常,请退出本界面后重新连接");
                    try {
                        if (mmInStream != null)
                            mmInStream.close();
                        if (mmOutStream != null)
                            mmOutStream.close();
                        if (btSocket != null)
                            btSocket.close();
                    } catch (IOException e) {
                        Log.e(Common.TAG, "Close Error");
                        e.printStackTrace();
                    } finally {
                        mmInStream = null;
                        mmOutStream = null;
                        btSocket = null;
                        bConnect = false;
                        setButtonEnable(false);
                    }
                    break;
                case Common.MESSAGE_WRITE:

                    break;
                case Common.MESSAGE_READ:

                    break;
                case Common.MESSAGE_RECV:
                    Log.e(TAG, "MESSAGE_RECV: " );
                    String content= (String) msg.obj;
                    Log.e(TAG, "handleMessage content: "+content );
//                    size=48,包含空格

                    setNumber(content);


//                    Boolean bOn = false;
//                    String strRecv = bytesToString(bRecv, msg.arg1);
//                    addLog("接收数据: " + strRecv);
//                    if (msg.arg1 == 9) {
//                        if (strRecv.indexOf("OK+Set:") != 0) {
//                            addLog("接收数据错误" + String.valueOf(strRecv.indexOf("OK+Set:")));
//                            return;
//                        }
//                        if (strRecv.charAt(strRecv.length() - 1) == '1') {
//                            bOn = true;
//                        }
//                        switch (strRecv.charAt(strRecv.length() - 2)) {
//                            case '2':
//                                setButtonColor(btn02, bOn);
//                                break;
//                            case '3':
//                                setButtonColor(btn03, bOn);
//                                break;
//                            case '4':
//                                setButtonColor(btn04, bOn);
//                                break;
//                            case '5':
//                                setButtonColor(btn05, bOn);
//                                break;
//                            case '6':
//                                setButtonColor(btn06, bOn);
//                                break;
//                            case '7':
//                                setButtonColor(btn07, bOn);
//                                break;
//                            case '8':
//                                setButtonColor(btn08, bOn);
//                                break;
//                            case '9':
//                                setButtonColor(btn09, bOn);
//                                break;
//                            case 'A':
//                                setButtonColor(btn10, bOn);
//                                break;
//                            case 'B':
//                                setButtonColor(btn11, bOn);
//                                break;
//                        }
//                    } else // nLength == 17
//                    {
//                        if (strRecv.indexOf("OK+PIO:") != 0) {
//                            addLog("接收数据错误" + String.valueOf(strRecv.indexOf("OK+PIO:")));
//                            return;
//                        }
//                        for (int i = 7; i < 17; i++) {
//                            bOn = false;
//                            if (strRecv.charAt(i) == '1') {
//                                bOn = true;
//                            }
//                            switch (i) {
//                                case 7:
//                                    setButtonColor(btn02, bOn);
//                                    break;
//                                case 8:
//                                    setButtonColor(btn03, bOn);
//                                    break;
//                                case 9:
//                                    setButtonColor(btn04, bOn);
//                                    break;
//                                case 10:
//                                    setButtonColor(btn05, bOn);
//                                    break;
//                                case 11:
//                                    setButtonColor(btn06, bOn);
//                                    break;
//                                case 12:
//                                    setButtonColor(btn07, bOn);
//                                    break;
//                                case 13:
//                                    setButtonColor(btn08, bOn);
//                                    break;
//                                case 14:
//                                    setButtonColor(btn09, bOn);
//                                    break;
//                                case 15:
//                                    setButtonColor(btn10, bOn);
//                                    break;
//                                case 16:
//                                    setButtonColor(btn11, bOn);
//                                    break;
//                            }
//                        }
//                    }
                    break;
                case Common.MESSAGE_TOAST:
                    Toast.makeText(getApplicationContext(),
                            msg.getData().getString(Common.TOAST),
                            Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

    public void setNumber(String content){
//        A0 00 00 68 4B 45 00 F8 A0 00 00 68 4B 45 00 F8
//        收缩压: 104mmHg(对应 00 68); (68为16进制,转10进制为104)
//        舒张压: 78mmHg (对应 4B);     (4B为16进制,转10进制为75)
//        脉搏:69bpm。   (对应 45);     (45为16进制,转10进制为69)
        String shousuo=content.substring(9,11);
        int shousuoInt=Integer.valueOf(shousuo,16);
        tv_shousuo.setText(shousuoInt+"mmHg");

        String shuzhang=content.substring(12,14);
        int shuzhangInt=Integer.valueOf(shuzhang,16);
        tv_shuzhang.setText(shuzhangInt+"mmHg");

        String maibo=content.substring(15,17);
        int maiboInt=Integer.valueOf(maibo,16);//16进制转10进制
        tv_maibo.setText(maiboInt+"bpm");

//        addLog("接收数据: " + content);
    }
    private BroadcastReceiver connectDevices = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(Common.TAG, "Receiver:" + action);
            if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {

            }
        }
    };

    @Override
    protected void onDestroy() {
        this.unregisterReceiver(connectDevices);
        Log.e(Common.TAG, "Free detail");
        super.onDestroy();
    }

    /* DEMO版较为简单,在编写您的应用时,请将此函数放到线程中执行,以免UI不响应 */
    public void send(Button btn, String strPio) {
        String strValue = "0";
        if (btn.getId() == 0)
            strValue = "1";
        if (!bConnect)
            return;
        try {
            if (mmOutStream == null)
                return;
            if (strPio.equals("?")) {
                nNeed = 17;
                nRecved = 0;
                mmOutStream.write(("AT+PIO" + strPio).getBytes());
                addLog("发送AT+PIO" + strPio);
            } else {
                nNeed = 9;
                nRecved = 0;
                mmOutStream.write(("AT+PIO" + strPio + strValue).getBytes());
                addLog("发送AT+PIO" + strPio + strValue);
            }
        } catch (Exception e) {
            Toast.makeText(this, "发送指令失败!", Toast.LENGTH_SHORT).show();
            return;
        }
    }

    // 按钮事件
    class ClickEvent implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            if (v == btnExit) {
                closeAndExit();
                return;
            } else if (v == btnAll) {
                // get status
                send(btnAll, "?");
            } else if (v == btn02) {
                send(btn02, "2");
            } else if (v == btn03) {
                send(btn03, "3");
            } else if (v == btn04) {
                send(btn04, "4");
            } else if (v == btn05) {
                send(btn05, "5");
            } else if (v == btn06) {
                send(btn06, "6");
            } else if (v == btn07) {
                send(btn07, "7");
            } else if (v == btn08) {
                send(btn08, "8");
            } else if (v == btn09) {
                send(btn09, "9");
            } else if (v == btn10) {
                send(btn10, "A");
            } else if (v == btn11) {
                send(btn11, "B");
            }
        }

    }

    public void closeAndExit() {
        if (bConnect) {
            bConnect = false;

            try {
                Thread.sleep(100);
                if (mmInStream != null)
                    mmInStream.close();
                if (mmOutStream != null)
                    mmOutStream.close();
                if (btSocket != null)
                    btSocket.close();
            } catch (Exception e) {
                Log.e(Common.TAG, "Close error...");
                e.printStackTrace();
            }
        }
        finish();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            closeAndExit();
            return true;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }

    public static String bytesToString(byte[] b, int length) {
//        Log.e(TAG, "length: "+length );
        StringBuffer result = new StringBuffer("");
        for (int i = 0; i < length; i++) {
            result.append((char) (b[i]));
        }

        return result.toString();
    }

    public void addLog(String str) {
        tvLog.append(str + "\n");
        svResult.post(new Runnable() {
            public void run() {
                svResult.fullScroll(ScrollView.FOCUS_DOWN);
            }
        });
    }

    public static int bytesToInt(byte[] src) {
        return src[3] & 0xFF |
                (src[2] & 0xFF) << 8 |
                (src[1] & 0xFF) << 16 |
                (src[0] & 0xFF) << 24;
    }

    /**
     * 字节数组转化为标准的16进制字符串
     *
     * @param bytes 字节数组数据
     * @return 字符串
     */
    public static String bytesToString(byte[] bytes) {
        final char[] hexArray = "0123456789ABCDEF".toCharArray();
        char[] hexChars = new char[bytes.length * 2];
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            int v = bytes[i] & 0xFF;
            hexChars[i * 2] = hexArray[v >>> 4];
            hexChars[i * 2 + 1] = hexArray[v & 0x0F];

            sb.append(hexChars[i * 2]);
            sb.append(hexChars[i * 2 + 1]);
            sb.append(' ');
        }
        return sb.toString();
    }
    /**
     * 将十六进制byte数组转换层字符串
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {

            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
//            stringBuilder.append("0x" + hv.toUpperCase(Locale.CHINA) + " ");//为了方便显示,采用拼接16进制格式显示
            stringBuilder.append(hv.toUpperCase(Locale.CHINA) + " ");//为了方便显示,采用拼接16进制格式显示

//            if (i == 4 || i == 5 || i == 6 || i == 7) {
//                Log.e("zwc", "111: " +"0x"+hv.toUpperCase(Locale.CHINA) + " " + "  222"+src[i]);
//            }
        }

        return stringBuilder.toString();
    }
 }

3、commo

public class Common {
    public static final int MESSAGE_STATE_CHANGE = 1;
    public static final int MESSAGE_READ = 2;
    public static final int MESSAGE_WRITE = 3;
    public static final int MESSAGE_DEVICE_NAME = 4;
    public static final int MESSAGE_TOAST = 5;

    public static final int MESSAGE_CONNECT = 6;
    public static final int MESSAGE_CONNECT_SUCCEED = 7;
    public static final int MESSAGE_CONNECT_LOST = 8;
    public static final int MESSAGE_RECV = 10;
    public static final int MESSAGE_EXCEPTION_RECV = 11;
    public static final String TOAST = "toast";
    public static final String TAG = "BlueToothTool";
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jian11058

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值