因为蓝牙硬件的交互限制,不能走系统的蓝牙文件传输方案,只能通过sendmessage的方式,对需要对文件切片传输,
下面是byte数组的一些可用的处理:
- 首先因为安卓最新的限制,需要对文件读写权限手动申请:
在AndroidManifest清单文件中:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在Activity中:
val PERMISSIONS_STORAGE = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
)
private fun verifyStoragePermissions() {
PERMISSIONSLIST.clear() //清空已经允许的没有通过的权限
//逐个判断是否还有未通过的权限
for (i in PERMISSIONS_STORAGE.indices) {
if (ContextCompat.checkSelfPermission(
this,
PERMISSIONS_STORAGE[i]
) !==
PackageManager.PERMISSION_GRANTED
) {
Log.d("bmc", "PERMISSIONS_STORAGE:" + PERMISSIONS_STORAGE[i])
PERMISSIONSLIST.add(PERMISSIONS_STORAGE[i]) //添加还未授予的权限到mPermissionList中
}
}
//申请权限
if (PERMISSIONSLIST.size > 0) { //有权限没有通过,需要申请
ActivityCompat.requestPermissions(
this, PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
)
} else {
jumpTo(MainActivity::class.java)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
var hasPermissionDismiss = false //有权限没有通过
if (REQUEST_EXTERNAL_STORAGE == requestCode) {
for (i in grantResults.indices) {
if (grantResults[i] == -1) {
hasPermissionDismiss = true
break
}
}
}
if (hasPermissionDismiss) { //如果有没有被允许的权限
showPermissionDialog()
mPermissionDialog.show()
} else {
//权限已经都通过了,可以将程序继续打开了
jumpTo(MainActivity::class.java)
}
}
private fun showPermissionDialog() {
mPermissionDialog = AlertDialog.Builder(this)
.setMessage("已禁用权限,请手动授予")
.setPositiveButton(
"设置"
) { _, _ ->
mPermissionDialog.dismiss()
val packageURI =
Uri.parse("package:${AppUtils.getAppPackageName()}")
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
packageURI
)
startActivity(intent)
}
.setNegativeButton(
"取消"
) { dialog, which -> //关闭页面或者做其他操作
AppUtils.exitApp()
}
.create()
}
2.文件处理
之后就能对通过文件选择器获取文件path了,获取到path后,先检查文件是否存在:
fun readFileToByteArray(size: Int, path: String): ByteArray? {
var file = readFiles(path);
if (!file.exists()) {
Log.e(TAG, "读取失败:" + path + "不存在")
return null;
}
return readFileToByteArray(size, file)
}
将file转换成ByteArray:
fun readFileToByteArray(size: Int, file: File): ByteArray? {
var inputStream = FileInputStream(file);
try {
inputStream = FileInputStream(file);
var inSize = inputStream.channel.size().toInt();//判断FileInputStream中是否有内容
if (inSize == 0) {
Log.d(TAG, "The FileInputStream has no content!");
return null;
}
var buffer = ByteArray(inputStream.available());//in.available() 表示要读取的文件中的数据长度
inputStream.read(buffer); //将文件中的数据读到buffer中
prepareArray(size, buffer)
return buffer;
} catch (e: FileNotFoundException) {
e.printStackTrace();
return null;
} catch (e: IOException) {
e.printStackTrace();
return null;
} finally {
try {
inputStream.close();
} catch (e: IOException) {
return null;
}
//或IoUtils.closeQuietly(in);
}
}
根据大小拆分或者使用
fun prepareArray(size: Int, bytes: ByteArray) {
if (bytes!!.size > size) {
// 长度超过size,拆分
var bytes1 = splitBytes(bytes, size)
for (i in bytes1.indices) {
// 超过size,分批输出流
}
} else {
// 没有超过size,直接输出流
}
}
其中拆分方法为:
fun splitBytes(bytes: ByteArray, size: Int): MutableList<ByteArray> {
var splitLength = size.toDouble();
var arrayLength = ceil(bytes.size / splitLength).toInt();
var result: MutableList<ByteArray> = ArrayList();
var from = 0
var to = 0
for (i in 0 until arrayLength) {
from = (i * splitLength).toInt();
to = (from + splitLength).toInt();
if (to > bytes.size)
to = bytes.size;
result.add(bytes.copyOfRange(from, to))
}
return result;
}
合并方法为
fun byteMergerAll( values: MutableList<ByteArray>): ByteArray? {
var length_byte = 0
for (i in values.indices) {
length_byte += values[i].size
}
val all_byte = ByteArray(length_byte)
var countLength = 0
for (i in values.indices) {
val b = values[i]
System.arraycopy(b, 0, all_byte, countLength, b.size)
countLength += b.size
}
return all_byte
}