Bytes("ISO8859-1"),"GBK")的实质

本文提供了一个Java程序示例,展示了如何进行不同字符集之间的转换,包括ISO-8859-1、GBK和UTF-16等。通过具体代码演示了字符串在不同编码间的相互转换过程,并对转换后的字节序列进行了详细的解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.io.UnsupportedEncodingException;  


public class main {  
    public static void main(String[] args) throws UnsupportedEncodingException{  
        byte [] b= new byte[]{(byte) 0xcc,(byte) 0xe1,(byte) 0xbd,(byte) 0xbb};  
        String s = new String(b,"ISO8859-1");  
        System.out.println(s);  
        print(s.getBytes("ISO8859-1"));  
        print(s.getBytes("GBK"));  
        print(s.getBytes("UTF-16"));  
        System.out.println(new String(s.getBytes("ISO8859-1"),"gbk"));  

        String ss = "中文";  
        print(ss.getBytes("UTF-16"));  
        print(ss.getBytes("ISO8859-1"));  
    }  

    static void print(byte [] b){  
        for(byte _b : b){  
            String s = Integer.toHexString(_b&0xff);  
            if(s.length()==1){  
                s = "0"+s;  
            }  
            System.out.print(s + " ");  
        }  
        System.out.println();  
    }  
}  

package com.wrs.project.serialportdemo; import android.app.Activity; import android.graphics.Color; import android.graphics.Typeface; import android.os.Bundle; import android.util.Log; import android.view.Window; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.wrs.project.module.serialport.Device; import com.wrs.project.module.serialport.SerialPortFinder; import com.wrs.project.module.serialport.SerialPortManager; import com.wrs.project.module.serialport.listener.OnSerialPortListener; import java.io.ByteArrayOutputStream; import java.io.File; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; public class BluetoothActivity extends Activity implements OnSerialPortListener { private static final String TAG = "BluetoothMusic"; // 协议类型常量 private static final byte TYPE_CONNECTION_STATUS = 0x55; // 新增连接状态协议 private static final byte TYPE_CURRENT_TIME = 0x56; private static final byte TYPE_TOTAL_TIME = 0x57; private static final byte TYPE_LYRIC = 0x58; private static final byte TYPE_SONG_INFO = 0x59; private static final byte TYPE_ALBUM = 0x5A; // 协议头部和尾部常量 private static final byte HEADER_STATUS = (byte) 0xAA; // 连接状态头部 private static final byte HEADER1 = (byte) 0xA9; // 对应0X56 private static final byte HEADER2 = (byte) 0xA8; // 对应0X57 private static final byte HEADER3 = (byte) 0xA7; // 对应0X58 private static final byte HEADER4 = (byte) 0xA6; // 对应0X59 private static final byte HEADER5 = (byte) 0xA5; // 对应0X5A private static final byte FOOTER = (byte) 0xEF; // 字符编码设置(支持中文显示) private static final String[] CHARSETS_TO_TRY = {"GBK", "UTF-8", "GB2312", "ISO-8859-1"}; private Button btBack, btPrev, btNext, btPP; private TextView tvCurrentTime, tvTotalTime, tvLyric, tvSongInfo, tvAlbum, tvConnectionStatus; private TextView tvTitle, tvStatusTitle, tvTimeTitle, tvLyricsTitle, tvAlbumTitle; private SerialPortManager serialPortManager; private boolean isConnected = false; // 数据缓冲区 private final ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream(); // 蓝牙控制命令 private static final String CMD_BACK = "AA5504EF"; private static final String CMD_PREV = "AA5501EF"; private static final String CMD_NEXT = "AA5502EF"; private static final String CMD_PLAY_PAUSE = "AA5500EF"; private static final String CMD_INIT = "AA5503EF"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(android.R.style.Theme_NoTitleBar); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_bluetooth); initViews(); initSerialPort(); setupButtonListeners(); } private void initViews() { // 初始化标题视图 tvTitle = findViewById(R.id.tv_title); tvTitle.setText("蓝牙音乐播放器"); tvTitle.setTextSize(24); tvTitle.setTextColor(Color.parseColor("#4A90E2")); tvTitle.setTypeface(null, Typeface.BOLD); tvStatusTitle = findViewById(R.id.tv_status_title); tvStatusTitle.setText("连接状态:"); tvTimeTitle = findViewById(R.id.tv_time_title); tvTimeTitle.setText("播放进度:"); tvLyricsTitle = findViewById(R.id.tv_lyrics_title); tvLyricsTitle.setText("歌词:"); tvAlbumTitle = findViewById(R.id.tv_album_title); tvAlbumTitle.setText("专辑:"); // 初始化信息视图 tvConnectionStatus = findViewById(R.id.tv_connection_status); tvConnectionStatus.setText("未连接"); tvConnectionStatus.setTextColor(Color.RED); tvCurrentTime = findViewById(R.id.tv_current_time); tvCurrentTime.setText("00:00"); tvCurrentTime.setTextSize(18); tvTotalTime = findViewById(R.id.tv_total_time); tvTotalTime.setText("00:00"); tvTotalTime.setTextSize(18); tvLyric = findViewById(R.id.tv_lyric); tvLyric.setText("等待歌词..."); tvLyric.setTextSize(20); tvLyric.setTextColor(Color.parseColor("#333333")); tvSongInfo = findViewById(R.id.tv_song_info); tvSongInfo.setText("未播放"); tvSongInfo.setTextSize(22); tvSongInfo.setTextColor(Color.BLACK); tvSongInfo.setTypeface(null, Typeface.BOLD); tvAlbum = findViewById(R.id.tv_album); tvAlbum.setText("未知专辑"); tvAlbum.setTextSize(18); tvAlbum.setTextColor(Color.parseColor("#666666")); // 初始化按钮 btBack = findViewById(R.id.bt_back); btPrev = findViewById(R.id.bt_prev); btNext = findViewById(R.id.bt_next); btPP = findViewById(R.id.bt_pp); // 设置按钮样式 int buttonColor = Color.parseColor("#4A90E2"); btBack.setBackgroundColor(buttonColor); btPrev.setBackgroundColor(buttonColor); btNext.setBackgroundColor(buttonColor); btPP.setBackgroundColor(buttonColor); btBack.setTextColor(Color.WHITE); btPrev.setTextColor(Color.WHITE); btNext.setTextColor(Color.WHITE); btPP.setTextColor(Color.WHITE); } private void initSerialPort() { serialPortManager = new SerialPortManager(); SerialPortFinder serialPortFinder = new SerialPortFinder(); List<Device> devices = serialPortFinder.getDevices(); if (devices != null && devices.size() > 1) { Device device = devices.get(1); try { serialPortManager.openSerialPort(device.getFile(), 1500000, 3, 0, 3, 0); serialPortManager.setOnSerialPortListener(this); sendCommand(CMD_INIT); // 发送初始化命令 showToast("串口初始化成功"); tvConnectionStatus.setText("初始化中..."); tvConnectionStatus.setTextColor(Color.parseColor("#FFA500")); // 添加状态查询定时器 // startStatusQuery(); } catch (Exception e) { Log.e(TAG, "串口打开失败", e); showToast("串口初始化失败"); } } else { showToast("未找到可用串口设备"); } } // 添加状态查询定时器 // private void startStatusQuery() { // new Thread(() -> { // while (!Thread.interrupted()) { // try { // Thread.sleep(3000); // 每3秒查询一次状态 // if (serialPortManager != null && serialPortManager.isOpened()) { // sendCommand(CMD_INIT); // } // } catch (InterruptedException e) { // Thread.currentThread().interrupt(); // } // } // }).start(); // } private void setupButtonListeners() { btBack.setOnClickListener(v -> handleButtonClick(CMD_BACK, "退出蓝牙模式")); btPrev.setOnClickListener(v -> handleButtonClick(CMD_PREV, "上一曲")); btNext.setOnClickListener(v -> handleButtonClick(CMD_NEXT, "下一曲")); btPP.setOnClickListener(v -> handleButtonClick(CMD_PLAY_PAUSE, "播放/暂停")); } private void handleButtonClick(String command, String actionName) { if (sendCommand(command)) { if (CMD_BACK.equals(command)) { finish(); // 退出命令特殊处理 } showToast(actionName); } } private boolean sendCommand(String hexCommand) { if (serialPortManager == null || !serialPortManager.isOpened()) { showToast("串口未就绪"); return false; } try { byte[] data = ByteUtils.hexStrToByteArray(hexCommand); serialPortManager.sendBytes(data); Log.i(TAG, "发送命令: " + hexCommand); return true; } catch (Exception e) { Log.e(TAG, "命令发送失败: " + hexCommand, e); return false; } } @Override public void onDataReceived(byte[] bytes) { // 将新数据添加到缓冲区 dataBuffer.write(bytes, 0, bytes.length); // 处理缓冲区中的所有完整数据包 processDataBuffer(); } private void processDataBuffer() { byte[] bufferData = dataBuffer.toByteArray(); int startIndex = 0; while (startIndex < bufferData.length) { // 查找可能的协议起始位置 int packetStart = findPacketStart(bufferData, startIndex); if (packetStart == -1) { // 没有找到有效数据包,清空缓冲区 dataBuffer.reset(); return; } // 查找数据包结束位置 (0xEF) int packetEnd = -1; for (int i = packetStart; i < bufferData.length; i++) { if (bufferData[i] == FOOTER) { packetEnd = i; break; } } if (packetEnd == -1) { // 没有找到完整的数据包,保留剩余数据 byte[] remaining = Arrays.copyOfRange(bufferData, packetStart, bufferData.length); dataBuffer.reset(); dataBuffer.write(remaining, 0, remaining.length); return; } // 提取完整数据包 byte[] packet = Arrays.copyOfRange(bufferData, packetStart, packetEnd + 1); // 打印原始数据包用于调试 Log.d(TAG, "原始数据包: " + ByteUtils.bytesToHexString(packet)); // 处理数据包 processBluetoothPacket(packet); // 移动起始位置到下一个包 startIndex = packetEnd + 1; } // 所有数据已处理,清空缓冲区 dataBuffer.reset(); } private int findPacketStart(byte[] data, int startIndex) { for (int i = startIndex; i < data.length - 1; i++) { byte type = data[i]; byte header = data[i + 1]; // 新增连接状态协议检测 (0x55 0xAA) if (type == TYPE_CONNECTION_STATUS && header == HEADER_STATUS) { return i; } if ((type == TYPE_CURRENT_TIME && header == HEADER1) || (type == TYPE_TOTAL_TIME && header == HEADER2) || (type == TYPE_LYRIC && header == HEADER3) || (type == TYPE_SONG_INFO && header == HEADER4) || (type == TYPE_ALBUM && header == HEADER5)) { return i; } } return -1; } private void processBluetoothPacket(byte[] packet) { if (packet.length < 3) { Log.w(TAG, "无效数据包:长度不足"); return; } byte type = packet[0]; // packet[1] 是头部标识,已通过findPacketStart验证 // 提取有效数据(去掉类型、头部和尾部) byte[] data = Arrays.copyOfRange(packet, 2, packet.length - 1); // 处理连接状态协议 (新增) if (type == TYPE_CONNECTION_STATUS) { // 详细解析信息 StringBuilder analysis = new StringBuilder(); analysis.append("连接状态协议解析:\n"); analysis.append("类型: 0x").append(String.format("%02X", type)).append("\n"); analysis.append("头部: 0x").append(String.format("%02X", packet[1])).append("\n"); analysis.append("状态字节: "); if (data.length >= 6) { byte statusByte = data[0]; analysis.append("0x").append(String.format("%02X", statusByte)).append("\n"); String statusText; int color; switch (statusByte) { case (byte) 0x7A: statusText = "已连接"; color = Color.GREEN; break; case (byte) 0x7C: statusText = "未连接"; color = Color.RED; break; case (byte) 0x30: // 处理0x30状态 statusText = "蓝牙连接中"; color = Color.parseColor("#FFA500"); break; default: statusText = "未知状态: 0x" + String.format("%02X", statusByte); color = Color.parseColor("#FFA500"); } analysis.append("状态解释: ").append(statusText); Log.i(TAG, analysis.toString()); // addDebugLog(analysis.toString()); runOnUiThread(() -> { tvConnectionStatus.setText(statusText); tvConnectionStatus.setTextColor(color); }); } else { analysis.append("数据长度不足"); Log.w(TAG, analysis.toString()); // addDebugLog(analysis.toString()); } return; } // 将字节数据转换为字符串,尝试多种编码(解决中文乱码问题) String dataString = decodeDataWithMultipleEncodings(data); // 如果解码失败,使用十六进制表示 if (dataString == null) { dataString = "无法解码: " + ByteUtils.bytesToHexString(data); } String finalDataString = dataString; runOnUiThread(() -> { switch (type) { case TYPE_CURRENT_TIME: tvCurrentTime.setText(formatTime(finalDataString)); break; case TYPE_TOTAL_TIME: tvTotalTime.setText(formatTime(finalDataString)); break; case TYPE_LYRIC: tvLyric.setText(finalDataString); // 歌词高亮效果 tvLyric.setTextColor(Color.parseColor("#E91E63")); tvLyric.postDelayed(() -> tvLyric.setTextColor(Color.parseColor("#333333")), 500); break; case TYPE_SONG_INFO: tvSongInfo.setText(finalDataString); break; case TYPE_ALBUM: tvAlbum.setText(finalDataString); break; default: Log.w(TAG, "未知数据类型: " + type); } }); } // 尝试多种编码方式解码数据(解决中文乱码问题) private String decodeDataWithMultipleEncodings(byte[] data) { if (data == null || data.length == 0) return ""; // 优先尝试UTF-8 String result = tryDecode(data, StandardCharsets.UTF_8); if (isValidString(result)) return result; // 尝试GBK result = tryDecode(data, Charset.forName("GBK")); if (isValidString(result)) return result; // 尝试GB2312 result = tryDecode(data, Charset.forName("GB2312")); if (isValidString(result)) return result; // 尝试ISO-8859-1 result = tryDecode(data, StandardCharsets.ISO_8859_1); if (isValidString(result)) return result; // 所有尝试失败 Log.w(TAG, "所有编码尝试失败,使用原始十六进制"); return null; } private String tryDecode(byte[] data, Charset charset) { try { return new String(data, charset); } catch (Exception e) { Log.w(TAG, "解码失败: " + charset.name(), e); return null; } } private boolean isValidString(String str) { if (str == null) return false; // 检查是否包含过多无效字符( 或?) int invalidCount = 0; for (char c : str.toCharArray()) { if (c == ' ' || c == '?') { invalidCount++; } } // 如果无效字符超过总字符数的20%,则认为解码失败 return (invalidCount * 1.0 / str.length()) < 0.2; } // 格式化时间显示 (假设时间格式为秒数或MM:SS) private String formatTime(String time) { try { if (time.contains(":")) { return time; // 已经是MM:SS格式 } int seconds = Integer.parseInt(time); int minutes = seconds / 60; int remainingSeconds = seconds % 60; return String.format("%02d:%02d", minutes, remainingSeconds); } catch (NumberFormatException e) { return time; // 无法解析则返回原始字符串 } } @Override protected void onDestroy() { super.onDestroy(); if (serialPortManager != null) { serialPortManager.closeSerialPort(); } } // 辅助方法 private void showToast(String message) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); } // 以下接口方法根据需要实现 @Override public void onSuccess(File device) {} @Override public void onFail(File device, Status status) {} @Override public void onClose(File device) {} @Override public void onDataSent(byte[] bytes) {} } 分析下这段代码,当前时间和总时间改成: 当前时间:分:数据转为十进制/1000/60, 秒:数据转为十进制后/1000%60 总时间:分:数据转为十进制/1000/60, 秒:数据转为十进制后/1000%60
最新发布
07-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值