深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
动态申请权限,写在第一个Activity里就好
private val REQUEST_CODE_PERMISSIONS = 10//数字随意
private val REQUIRED_PERMISSIONS = arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE)//要申请更多的权限都在这里拼接
//查询权限是否获取成功
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
}
//获取权限弹窗操作完成回调
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (allPermissionsGranted()) {
selectFile()//去选择文件
} else {
Toast.makeText(this, "需要授予权限才能使用该功能", Toast.LENGTH_SHORT).show()//给用户提示
}
}
}
让用户自行选择文件
直接用intent唤起系统相册即可
private fun selectFile() {
val i = Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
someActivityResultLauncher.launch(i)//Android 10以上的写法,targetAPI在31以上才这么写
} else {
startActivityForResult(i, REQUEST_SELECT_FILE)//Android 10以下的写法
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_SELECT_FILE -> {
if (resultCode == Activity.RESULT_OK && data != null && data.data != null) {
toCrop(data.data!!)//选完文件以后跳转到裁剪界面
}
}
}
}
var someActivityResultLauncher = registerForActivityResult(
StartActivityForResult(), ActivityResultCallback { result ->
if (result.resultCode == Activity.RESULT_OK
&& result.data != null && result.data!!.data != null) {
toCrop(result.data!!.data!!)//选完文件以后跳转到裁剪界面
}
})
/**
* 跳转裁剪页面
*/
private fun toCrop(data: Uri) {
val filePathColumn = arrayOf(MediaStore.Video.Media.DATA)
try {
val cursor: Cursor? = contentResolver.query(data,
filePathColumn, null, null, null)
if (cursor != null) {
cursor.moveToFirst()
val columnIndex: Int = cursor.getColumnIndex(filePathColumn[0])
val videoPath: String = cursor.getString(columnIndex)
cursor.close()
val intent = Intent(this, VideoCropPreActivity::class.java)
intent.putExtra("src", videoPath)//在裁剪界面接收这个参数即可
startActivity(intent)
}
} catch (e: Exception) {
Log.e(TAG, "读取文件出错", e)
Toast.makeText(this, resources.getString(R.string.readVideoFileError), Toast.LENGTH_LONG).show()
}
}
注意,如果使用模拟器测试会触发一个闪退bug
模拟器镜像的谷歌相册是老版本,会抛出异常java.lang.IllegalArgumentException: Invalid column latitude
这个是谷歌相册老版本的bug,更新相册或者使用别的相册APP选择图片即可解决。谷歌的锅我们不帮他修,不管这个问题。实机不会出现这个问题,我用Pixel 3 XL在Android 12实测过不会报错。
解决无法在控制台直接运行ffmpeg
从Android 10开始,不允许直接运行data/data/packagename/
目录下的二进制文件。旧的写法正是把ffmpeg放到这里运行的,所以到了Android 10需要改变写法。
如果你直接用老的写法的话,会报文件不存在或者权限被拒绝,因为安卓10以上根本不会把你Assert里的二进制文件放到这个目录里。那么解决的思路就很简单了,我们把ffmpeg伪装成别的文件,骗系统把我们放进去不就可以了吗?
把ffmpeg放到jni的目录里
说干就干,伪装成so库文件。先把ffmpeg
改名成ffmpeg.so
,然后放进jniLibs
里面去,你想支持哪些架构就放到哪些架构的目录里,反正这玩意不挑架构。
修改manifest
修改manifest
,在application
标签里加入这个参数
android:extractNativeLibs="true"
修改运行指令的目录
在原本的代码中搜索data/data
,找到这一段
"/data/data/" + context.getPackageName() + "/ffmpeg"
把它改成
context.getApplicationInfo().nativeLibraryDir + "/ffmpeg.so"
有两处,都改掉以后就大功告成了~
性能优化
原本的轮子是有裁剪画面的功能的,但是我没有这个需求,所以要在最后的ffmpeg指令中把裁剪的指令干掉。因为不需要重新编码,直接复制视频流和音频流最快,所以加个-c copy
测试时发现一个小bug,如果文件名中有空格,会当成指令的分隔符,所以我们添加引号把文件名包起来,解决这个问题。
**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
![](https://img-blog.csdnimg.cn/direct/743b668910224b259a5ffe804fa6d0db.png)
![img](https://img-blog.csdnimg.cn/img_convert/635a85b0a5cae76e654e8c5b3e008858.png)
![img](https://img-blog.csdnimg.cn/img_convert/3bd52a1b08a7fabd6ef35aa1039b3ad1.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**
以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**