适配前台程序员必不可少的工作之一,且可能要花大量的时间精力。何为前台程序员,是面向用户的一端,包括前端、移动端、PC等等。何为适配,适配就是当我们的开发环境、运行环境等发生变化的时候,程序依然能稳健运行。而适配中最难为程序员的就是Android了,除了开发环境、运行环境等因素之外,因为Android开源的原因,还要适配各大厂商。。而适配条件之多,经常让Android程序员为之头疼。来看看相机、相册相关的适配历程:更换头像的小例子来讲解一下。
点击头像,然后弹窗,给出不同的选项,执行不同的操作。mBinding.llImg.setOnClickListener {
TakeImageDialog {
when (it) {
TakeImageDialog.ALBUM -> {
openAlbum()
}
TakeImageDialog.CAMERA -> {
checkPermission()
}
}
}.show(supportFragmentManager, "TakeImageDialog")
}参数变量://相机拍照保存的位置
private lateinit var photoUri: Uri
companion object {
private const val REQUEST_CODE_PERMISSIONS = 1000 //权限
private const val REQUEST_CODE_ALBUM = 1001 //相册
private const val REQUEST_CODE_CAMERA = 1002 //相机
}private fun openAlbum() {
val intent = Intent()
intent.type = "image/*"
intent.action = "android.intent.action.GET_CONTENT"
intent.addCategory("android.intent.category.OPENABLE")
startActivityForResult(intent, REQUEST_CODE_ALBUM)
}startActivityForResult启动方式,来看看onActivityResult回调override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {
REQUEST_CODE_ALBUM -> {
doCrop(data?.data!!)
}
...
}
}
}requestCode是REQUEST_CODE_ALBUM的情况下:doCrop(data?.data!!)data?.data!!即是选择图片返回的Uri,可以直接使用,这里进行了下一步操作,剪裁private fun doCrop(sourceUri: Uri) {
Intrinsics.checkParameterIsNotNull(sourceUri, "资源为空")
UCrop.of(sourceUri, getDestinationUri())//当前资源,保存目标位置
.withAspectRatio(1f, 1f)//宽高比
.withMaxResultSize(500, 500)//宽高
.start(this)
}getDestinationUri()是当前资源裁剪后保存的目标位置private fun getDestinationUri(): Uri {
val fileName = String.format("fr_crop_%s.jpg", System.currentTimeMillis())
val cropFile = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName)
return Uri.fromFile(cropFile)
}UCrop的回调同样也在onActivityResult中override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {
REQUEST_CODE_ALBUM -> {
doCrop(data?.data!!)
}
UCrop.REQUEST_CROP -> {
val resultUri: Uri = UCrop.getOutput(data!!)!!
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(resultUri))
// todo
}
UCrop.RESULT_ERROR -> {
val error: Throwable = UCrop.getError(data!!)!!
ToastUtil.show("图片剪裁失败" + error.message)
}
}
}
}UCrop.getOutput(data!!)!!,即是返回的Uri,可以直接操作,也可以转成bitmap。ok,到这里打开相册就介绍完了。接下来看重点,打开相机。author:yechaoa
权限,这个在某些手机上是必须的,比如华为。<uses-permission android:name="android.permission.CAMERA" />private fun checkPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CODE_PERMISSIONS)
}
}override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
ToastUtil.show("拒绝会导致无法使用相机")
}
}
}openCamera方法就是打开相机了。private fun openCamera() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
photoUri = getDestinationUri()
photoUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri
FileProvider.getUriForFile(this, "$packageName.fileProvider", File(photoUri.path!!))
} else {
getDestinationUri()
}
//android11以后强制分区存储,外部资源无法访问,所以添加一个输出保存位置,然后取值操作
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
startActivityForResult(intent, REQUEST_CODE_CAMERA)
}FileProvider.getUriForFile(this, "$packageName.fileProvider", File(photoUri.path!!))fileProvider的方式共享文件。intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)android 11以后强制分区存储,外部资源无法访问,所以添加一个输出保存位置photoUri,然后取值操作override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode) {
REQUEST_CODE_ALBUM -> {
doCrop(data?.data!!)
}
REQUEST_CODE_CAMERA -> {
//从保存的位置取值
doCrop(photoUri)
}
UCrop.REQUEST_CROP -> {
val resultUri: Uri = UCrop.getOutput(data!!)!!
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(resultUri))
// todo
}
UCrop.RESULT_ERROR -> {
val error: Throwable = UCrop.getError(data!!)!!
ToastUtil.show("图片剪裁失败" + error.message)
}
}
}data取值了,而是从我们保存的位置里取值。后面剪裁跟相册都是一样的流程了。Android 10或许还能过度一下,但是Android 11以后就是强制执行分区存储了。应用可以在不需要读写权限的情况下,访问自己的分区,执行读写操作,卸载之后分区文件也相应删除,所以就不能有把缓存文件放到竞品的文件夹下这种操作了,还是乖乖的吧。在Android 10以下,还是要读写权限的,还是可以胡作非为的。获取自己的分区地址:
getExternalFilesDir(Environment.DIRECTORY_PICTURES)file:///storage/emulated/0/Android/data/包名/files/Picturesfile开头是沙盒文件,content开头是共享文件。那假如我有访问其他文件的需求呢,比如相册、音乐,那还是需要读写权限的,且得通过MediaStore API来进行访问了,具体可以查看文档。最后写作不易,如果对你有用,点个赞呗 ^ _ ^使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我有这个代码File.open(file_name,'r'){|file|file.read}但是Rubocop发出警告:Offenses:Style/SymbolProc:Pass&:readasargumenttoopeninsteadofablock.你是怎么做到的? 最佳答案 我刚刚创建了一个名为“t.txt”的文件,其中包含“Hello,World\n”。我们可以按如下方式阅读。File.open('t.txt','r',&:read)#=>"Hello,World\n"顺便说一下,由于第二个参数的默认值是'r',所以这样
因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实
我正在为个人笔记创建一个日志应用程序,并且在我的Rakefile中包含以下内容:task:newdoentry_name="Entries/#{Time.now.to_s.gsub(/[-\:]+/,'.').gsub(/.0500+/,'')}.md"`touch#{entry_name}``echo"#$(date)">>#{entry_name}`end我想包括的最后一部分是Vim文本编辑器的打开,但我不知道如何打开它,就像我直接从bash终端调用它一样。我试过:vim#{entry_name}但不幸的是,我认为它们都将其作为后台进程打开。我一直在引用“6WaystoRunShe