如何在 JAVA 中将十六进制字符串分隔为单独的位值?

问题描述

使用以下方法成功将字节数组转换为十六进制字符串后:

  private ScanCallback leScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType,ScanResult result) {
            ScanRecord Scanned = result.getScanRecord();
            String address = btAdapter.getAddress();

            byte[] packetData = Scanned.getBytes();
            StringBuilder R = new StringBuilder();
                for(byte hex : packetData){
                    R.append(String.format("%02X",hex));
                }

我现在希望能够将十六进制流的每一位分别读取为数值,以便对我的 BLE 扫描仪应用程序的值执行基本逻辑。

我阅读了很多网站,我最初的想法是在 for 循环中使用数组并读取十六进制字符串的每个字符。但我是 Java 新手,还没有成功做到这一点!

任何关于我如何有效地做到这一点的想法都会很棒。

编辑:

初始输出使用 getBytes() 并给出一个字节数组输出,例如 "[B@" ,后跟一些数字和字母。这个值不是我需要的格式,我需要 62 位十六进制流,由于 for 循环,它现在可以成功打印!

我现在想将 62 位数据包长度的十六进制数据单独分成当前值。不将它们转换回 BYTE 数组。

希望这能更清楚地说明要求

编辑:到目前为止的完整代码

package com.example.joelwasserman.androidbletutorial;


import android.Manifest;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.ParcelUuid;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;

import java.util.List;
import java.util.UUID;
import java.util.Vector;

public class MainActivity extends AppCompatActivity {

    BluetoothManager btManager;
    BluetoothAdapter btAdapter;
    BluetoothLeScanner btScanner;
    Button startScanningButton;
    Button stopScanningButton;
    TextView peripheralTextView;
    private final static int REQUEST_ENABLE_BT = 1;
    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
        peripheralTextView.setMovementMethod(new ScrollingMovementMethod());

        startScanningButton = (Button) findViewById(R.id.StartScanButton);
        startScanningButton.setonClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startScanning();
            }
        });

        stopScanningButton = (Button) findViewById(R.id.StopScanButton);
        stopScanningButton.setonClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                stopScanning();
            }
        });
        stopScanningButton.setVisibility(View.INVISIBLE);

        btManager = (BluetoothManager)getSystemService(Context.BLUetoOTH_SERVICE);
        btAdapter = btManager.getAdapter();
        btScanner = btAdapter.getBluetoothLeScanner();


        if (btAdapter != null && !btAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
        }

        // Make sure we have access coarse location enabled,if not,prompt the user to enable it
        if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("This app needs location access");
            builder.setMessage("Please grant location access so this app can detect peripherals.");
            builder.setPositiveButton(android.R.string.ok,null);
            builder.setondismissListener(new DialogInterface.OndismissListener() {
                @Override
                public void ondismiss(DialogInterface dialog) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_REQUEST_COARSE_LOCATION);
                }
            });
            builder.show();
        }
    }

    // Device scan callback.
    private ScanCallback leScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType,ScanResult result) {
            ScanRecord Scanned = result.getScanRecord();
            String address = btAdapter.getAddress();

            byte[] packetData = Scanned.getBytes();
            
            /*StringBuilder R = new StringBuilder();
                for(byte hex : packetData){
                    R.append(String.format("%02X",hex));
                }*/
            int PacketLength = Scanned.getBytes().length;
//            int x = Integer.parseInt(String.valueOf(packetData));
//            String int_val = Integer.toString(x);

            if(new String("SimpleBLEbroadcaster").equals(result.getDevice().getName()))
                peripheralTextView.append("Device Name: " + result.getDevice().getName() + " RSSi: " + result.getRSSi() +" Packet length: " + PacketLength + " Packet Data: " + "0x" + R  +  "\n");
        }
    };

    @Override
    public void onRequestPermissionsResult(int requestCode,String permissions[],int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    System.out.println("coarse location permission granted");
                } else {
                    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("Functionality limited");
                    builder.setMessage("Since location access has not been granted,this app will not be able to discover beacons when in the background.");
                    builder.setPositiveButton(android.R.string.ok,null);
                    builder.setondismissListener(new DialogInterface.OndismissListener() {

                        @Override
                        public void ondismiss(DialogInterface dialog) {
                        }

                    });
                    builder.show();
                }
                return;
            }
        }
    }

    public void startScanning() {
        System.out.println("start scanning");
        peripheralTextView.setText("");
        startScanningButton.setVisibility(View.INVISIBLE);
        stopScanningButton.setVisibility(View.VISIBLE);
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                btScanner.startScan(leScanCallback);
            }
        });
    }

    public void stopScanning() {
        System.out.println("stopping scanning");
        peripheralTextView.append("Stopped Scanning");
        startScanningButton.setVisibility(View.VISIBLE);
        stopScanningButton.setVisibility(View.INVISIBLE);
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                btScanner.stopScan(leScanCallback);
            }
        });
    }

    public static byte[] hexStringToByteArray(String s) throws IOException {
        char[] buf = new char[2];
        int numRead = -1;
        StringReader in = new StringReader(s);
        byte[] bytes = new byte[s.length() / 2];
        int byteIndex = 0;
        while ((numRead = in.read(buf)) > -1) {
            byte b = (byte) Integer.parseInt(String.valueOf(buf),16);
            bytes[byteIndex++] = b;
        }
        return bytes;
    }
}

解决方法

记住我所说的关于传输与可视化的内容,您可以通过以下方式处理:

    public static byte[] hexStringToByteArray(String s) throws IOException {
        char[] buf = new char[2];
        int numRead = -1;
        StringReader in = new StringReader(s);
        byte[] bytes = new byte[s.length() / 2];
        int byteIndex = 0;
        while ((numRead = in.read(buf)) > -1) {
            byte b = (byte) Integer.parseInt(String.valueOf(buf),16);
            bytes[byteIndex++] = b;
        }
        return bytes;
    }