如何在 JAVA 中将十六进制字符串分成单独的位值?
How do I seperate a hex string into seperated Bit values in 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;
}
使用以下方法将字节数组成功转换为十六进制字符串后:
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;
}