当前位置: 首页 > news >正文

Android Kotlin 打开相册选择图片(多选)

1. 核心代码

打开系统相册功能,本代码使用两种方式打开本地相册,startActivityForResult 已经废弃,可以使用新的方式。

package com.example.facedetectordemoimport android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.facedetectordemo.databinding.ActivityMainBinding
import com.example.facedetectordemo.entity.FaceInfo
import android.Manifest;
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Activity
import android.content.ContentUris
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.provider.DocumentsContract
import android.provider.MediaStore
import com.google.android.material.snackbar.Snackbarclass MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingprivate val CHOOSE_PHOTO = 1private val requestPermissionLauncher =registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->if (isGranted) {Log.i("Permission: ", "Granted")} else {Log.i("Permission: ", "Denied")}}private val launcherActivity = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {val data = it.dataif (it.resultCode == Activity.RESULT_OK) {// 判断手机系统版本号if (Build.VERSION.SDK_INT >= 19) {// 4.4及以上系统使用这个方法处理图片if (data != null) {if(data.clipData != null) {handleImageOnKitKat(data.clipData!!.getItemAt(0).uri)} else if(data.data != null) {handleImageOnKitKat(data.data!!)}}}}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)// Example of a call to a native methodbinding.openGallery.setOnClickListener{val intent = Intent("android.intent.action.GET_CONTENT")intent.type = "image/*" // */intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)//startActivityForResult(intent, CHOOSE_PHOTO) // 打开相册, 废弃APIlauncherActivity.launch(intent)}val infos = getFaceInfoList()Log.d("zhouyong", "onCreate: size " + infos.size)requestPermission();}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)when (requestCode) {CHOOSE_PHOTO -> if (resultCode == Activity.RESULT_OK) {// 判断手机系统版本号if (Build.VERSION.SDK_INT >= 19) {// 4.4及以上系统使用这个方法处理图片if (data != null) {if(data.clipData != null) {handleImageOnKitKat(data.clipData!!.getItemAt(0).uri)} else if(data.data != null) {handleImageOnKitKat(data.data!!)}}} else {}}else -> {}}}@TargetApi(19)private fun handleImageOnKitKat(uri: Uri) {var imagePath: String? = null//val uri = data.dataLog.d("TAG", "handleImageOnKitKat: uri is $uri")if (DocumentsContract.isDocumentUri(this, uri)) {// 如果是document类型的Uri,则通过document id处理val docId = DocumentsContract.getDocumentId(uri)if ("com.android.providers.media.documents" == uri!!.authority) {val id = docId.split(":".toRegex()).toTypedArray()[1] // 解析出数字格式的idval selection = MediaStore.Images.Media._ID + "=" + idimagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection)} else if ("com.android.providers.downloads.documents" == uri.authority) {val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(docId))imagePath = getImagePath(contentUri, null)}} else if ("content".equals(uri!!.scheme, ignoreCase = true)) {// 如果是content类型的Uri,则使用普通方式处理imagePath = getImagePath(uri, null)} else if ("file".equals(uri.scheme, ignoreCase = true)) {// 如果是file类型的Uri,直接获取图片路径即可imagePath = uri.path}displayImage(imagePath) // 根据图片路径显示图片}@SuppressLint("Range")private fun getImagePath(uri: Uri?, selection: String?): String? {var path: String? = null// 通过Uri和selection来获取真实的图片路径val cursor = contentResolver.query(uri!!, null, selection, null, null)if (cursor != null) {if (cursor.moveToFirst()) {path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))}cursor.close()}return path}private fun displayImage(imagePath: String?) {if (imagePath != null) {val bitmap = BitmapFactory.decodeFile(imagePath)binding.imageView.setImageBitmap(bitmap)} else {//Toast.makeText(this, "failed to get image", Toast.LENGTH_SHORT).show()}}fun requestPermission() {when {ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED -> {}ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA) -> {requestPermissionLauncher.launch(Manifest.permission.CAMERA)requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)}else -> {requestPermissionLauncher.launch(Manifest.permission.CAMERA)requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)}}}fun View.showSnackbar(view: View,msg: String,length: Int,actionMessage: CharSequence?,action: (View) -> Unit) {val snackbar = Snackbar.make(view, msg, length)if (actionMessage != null) {snackbar.setAction(actionMessage) {action(this)}.show()} else {snackbar.show()}}/*** A native method that is implemented by the 'facedetectordemo' native library,* which is packaged with this application.*/external fun stringFromJNI(): Stringexternal fun getFaceInfoList(): Array<FaceInfo>companion object {// Used to load the 'facedetectordemo' library on application startup.init {System.loadLibrary("facedetectordemo")}}
}

2. main_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/openGallery"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="212dp"android:text="打开相册"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/imageView"app:layout_constraintVertical_bias="1.0" /><ImageViewandroid:id="@+id/imageView"android:layout_width="200dp"android:layout_height="200dp"android:layout_marginTop="96dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"tools:srcCompat="@tools:sample/avatars" /></androidx.constraintlayout.widget.ConstraintLayout>

相关文章:

Android Kotlin 打开相册选择图片(多选)

1. 核心代码 打开系统相册功能&#xff0c;本代码使用两种方式打开本地相册&#xff0c;startActivityForResult 已经废弃&#xff0c;可以使用新的方式。 package com.example.facedetectordemoimport android.content.pm.PackageManager import androidx.appcompat.app.App…...

java学习路径

ProcessOn Mindmap...

[线程与网络] 网络编程与通信原理(四):深入理解传输层UDP与TCP协议

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …...

IEEE编程语言排行榜:深度解析编程语言的四大维度、五大趋势、六大热门与七大挑战

IEEE编程语言排行榜&#xff1a;深度解析编程语言的四大维度、五大趋势、六大热门与七大挑战 在信息技术领域&#xff0c;编程语言排行榜一直是衡量各种编程语言流行度和影响力的重要指标。IEEE&#xff08;电气电子工程师协会&#xff09;作为全球最具影响力的科技专业组织之…...

【C++面试50题】

以下是针对C程序员面试可能遇到的一些问题&#xff0c;涵盖了从基础语法、面向对象、STL、内存管理、模板、异常处理、并发编程等多个方面。 ### 基础概念与语法 1. C与C的主要区别是什么&#xff1f; 2. 什么是构造函数和析构函数&#xff1f;它们何时被调用&#xff1f; 3. 什…...

外汇天眼:ESMA发布针对在投资服务中使用人工智能的公司的指导意见

欧洲证券和市场管理局&#xff08;ESMA&#xff09;&#xff0c;欧盟的金融市场监管机构和监督机构&#xff0c;发布了一份声明&#xff0c;为在向零售客户提供投资服务时使用人工智能技术&#xff08;AI&#xff09;的公司提供初步指导。 尽管人工智能的普及仍处于初期阶段&am…...

【前缀和 记忆化搜索】LeetCode1444. 切披萨的方案数

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 动态规划 记忆化搜索 LeetCode1444. 切披萨的方案数 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; ‘A’ &#xff…...

异常处理1--5.31

try--catch--finally格式&#xff1a; try{ }catch(错误类型){ }finally{ } 执行情况&#xff1a; package javatest5;public class test {public static void main(String[] args) {int num115;int num20;try{System.out.println("商等于&#xff1a;"num1/num…...

AI免费插件 批量条码大师,支持100多种条码类型

没想到在网上看到一款和之前 悟空条码 类似的条码插件&#xff0c;叫批量条码大师&#xff0c;他做的比 悟空条码 功能更强&#xff0c;界面更美观&#xff0c;特分享出来给大家。 本插件采用了BWIPJS条码库&#xff0c;支持110种条码、二维码的生成; 支持批量生成&#xff0c;…...

使用 Django 连接 MySQL 数据库

文章目录 步骤一&#xff1a;安装必要的库和驱动步骤二&#xff1a;配置数据库连接步骤三&#xff1a;执行数据库迁移步骤四&#xff1a;开始使用 MySQL 数据库创建一个模型迁移模型到数据库使用模型进行数据操作创建新记录&#xff1a;查询记录&#xff1a;更新记录&#xff1…...

【谷歌开发者月刊】五月内容汇总,Google I/O 点燃您的创新灵感

五月因 Google I/O 大会的成功举办而备受瞩目&#xff0c;我们在为开发者们带来技术更新的同时&#xff0c;更提供了丰富的学习资源。一起在本期月刊中回顾精彩内容&#xff0c;带着学习热情继续探索技术的更新与发展吧&#xff01; 本月看点 精彩看点多多&#xff0c;请上下滑…...

wpf 实现长时间未操作自动退出登录

思路 在WPF应用程序中实现长时间未操作自动退出&#xff0c;主要思路是先收集用户操作行为&#xff0c;用一个全局变量记录用户最后操作时间&#xff0c;再用一个异步线程去监控用户的最后操作时间和当前时间进行比较如果超过了设定时间认为长时间未操作自动退出登录并显示相关…...

pytorch学习笔记3

标量数据 标量数据通常指的是单个数值&#xff0c;比如一个损失值、准确率、学习率等。这些单个的数值数据可以被记录下来&#xff0c;用于分析模型的训练过程、性能等。在代码中&#xff0c;writer.add_scalar() 的作用就是将这些标量数据添加到日志中&#xff0c;以便后续在可…...

开源监控工具monit安装部署

Monit 简介 Monit是一个轻量级(500KB)跨平台的用来监控Unix/linux系统的开源工具。部署简单&#xff0c;并且不依赖任何第三方程序、插件或者库。 Monit可以监控服务器进程、文件、文件系统、网络状态&#xff08;HTTP/SMTP等协议&#xff09;、远程主机、服务器资源变化等等。…...

Python 时间戳转时间

一、 10 位 时间戳 &#xff0c;秒级 转换为时间 方式一&#xff1a; import timetimeStamp 1717149862 timeArray time.localtime(timeStamp) timeStr time.strftime("%Y-%m-%d %H:%M:%S", timeArray) print(timeStr) 输出: 2024-05-31 18:04:22方式二&#xf…...

【网络层】IP地址基础 与 子网掩码

文章目录 IP地址基础IP地址概念IP地址分类公网地址和私网地址 子网掩码子网掩码作用默认子网掩码网络地址、主机地址、广播地址 IP地址基础 IP地址概念 IP地址&#xff1a;IP Address 在网络中&#xff0c;通信节点都需要有一个IP地址 IP地址以点分十进制表示&#xff0c;有…...

Cholesky分解(A=L * L^T)

Cholesky分解是一种用于解线性方程组和计算矩阵平方根的算法&#xff0c;特别适用于对称正定矩阵。这种方法相比于其他解法&#xff08;如高斯消元法&#xff09;在数值稳定性上通常有更好的表现&#xff0c;并且能够有效地利用矩阵的对称性和正定性。下面简要介绍如何使用Chol…...

2024大模型新应用井喷即将到来,算力问题如何解决?

#大模型新应用 #NLP #智合同 随着人工智能技术的加速演进&#xff0c;AI大模型已成为全球科技竞争的新高地、未来产业的新赛道、经济发展的新引擎。大模型的快速发展&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;和计算机视觉&#xff08;CV&#xff09;等…...

SpringBoot 七牛云 OSS 私有模式 获取访问链接

目录 一、问题引出 二、在SpringBoot中获取私有访问路径的操作 一、问题引出 由于七牛云OSS的公有模式存在被盗刷的风险&#xff0c;可能导致服务器额外的费用&#xff0c;于是我选择私有模式进行操作。私有模式的访问路径是一个问题&#xff0c;因为需要对应着token和e这两…...

python-模块-网络编程-多任务

一、模块 1-1 Python 自带模块 Json模块 处理json数据 {"key":"value"} json不是字典 本质是一个有引号的字符串数据 json注意点 {} 中的数据是字符串引号必须是双引号 使用json模块可以实现将json转为字典&#xff0c;使用字典的方法操作数据 。 或者将…...

别再死记硬背公式了!用Simulink玩转单相全桥逆变,从方波驱动到IGBT参数设置全解析

用Simulink玩转单相全桥逆变&#xff1a;从方波驱动到IGBT参数设置的实战指南 电力电子领域的学习常常陷入公式推导的泥潭&#xff0c;而Simulink提供的可视化仿真环境就像一盏明灯。想象一下&#xff0c;当你调整一个参数就能立即看到波形变化&#xff0c;比纸上推导要直观十倍…...

GitHub协作开发:AnythingtoRealCharacters2511动漫转真人开源项目实践

GitHub协作开发&#xff1a;AnythingtoRealCharacters2511动漫转真人开源项目实践 1. 项目介绍与准备 AnythingtoRealCharacters2511是一个专门将动漫角色转换为真实人像的开源项目&#xff0c;基于先进的AI图像生成技术。这个项目在GitHub上开源&#xff0c;让开发者可以共同…...

【西瓜带你学设计模式 | 第四期 - 抽象工厂模式】抽象工厂模式 —— 定义、核心结构、实战示例、优缺点与适用场景及模式区别

文章目录前言1. 抽象工厂模式是什么&#xff1f;2. 解决什么问题&#xff1f;2.1 有多个“产品维度”&#xff0c;并且需要成套切换2.2 变化点分散导致代码难维护3. 核心结构4. 示例4.1 抽象产品&#xff1a;Slice&#xff08;切片&#xff09;4.2 抽象产品&#xff1a;Pulp&am…...

宠物店主的福音:用LongCat一键生成宠物服装电商主图,省时省力

宠物店主的福音&#xff1a;用LongCat一键生成宠物服装电商主图&#xff0c;省时省力 1. 为什么宠物店主需要AI图片编辑工具 开宠物店的朋友们都知道&#xff0c;商品主图的质量直接影响销量。一件宠物小衣服&#xff0c;如果只是平铺拍摄或者随便套在模特身上&#xff0c;很…...

电话号码定位开源工具实战完全指南:从部署到企业应用

电话号码定位开源工具实战完全指南&#xff1a;从部署到企业应用 【免费下载链接】location-to-phone-number This a project to search a location of a specified phone number, and locate the map to the phone number location. 项目地址: https://gitcode.com/gh_mirro…...

Mac用户的移动Win10工坊:从WTG配置到驱动、激活、文件共享的完整避坑指南

Mac用户的移动Win10工坊&#xff1a;从WTG配置到驱动、激活、文件共享的完整避坑指南 当Mac用户需要运行Windows应用时&#xff0c;双系统方案往往是最佳选择。而通过Windows To Go&#xff08;WTG&#xff09;技术将Win10安装在移动硬盘上&#xff0c;不仅保留了Mac原生系统的…...

3步快速解密QQ音乐加密文件:QMCDecode终极免费解决方案

3步快速解密QQ音乐加密文件&#xff1a;QMCDecode终极免费解决方案 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#xff0c;默认…...

共享图书借阅系统 Java 源码 + 数据库设计完整方案

以下是一个共享图书借阅系统的Java源码与数据库设计的完整方案&#xff0c;涵盖系统架构、核心功能实现、数据库设计以及安全防护措施等方面&#xff1a;一、系统架构技术栈&#xff1a;后端&#xff1a;Spring Boot 2.x MyBatis-Plus&#xff08;简化数据库操作&#xff09;前…...

Java学习——String 类的不可变性、底层实现(JDK1.8+)

目录 一、核心定义与设计思想 1. 核心定义 2. 核心设计思想 二、底层实现原理&#xff08;含 JDK 源码分析 / 反编译验证&#xff09; 1. JDK1.8 String 核心源码解析 2. 字符串常量池&#xff08;JDK1.8 底层&#xff09; 3. 反编译验证&#xff08;不可变性 编译器优…...

丹青识画部署教程:Nginx反向代理+HTTPS保障书法API安全

丹青识画部署教程&#xff1a;Nginx反向代理HTTPS保障书法API安全 1. 引言&#xff1a;当AI艺术遇见生产环境 想象一下&#xff0c;你开发了一个能看懂画作、还能用行草书法题跋的AI应用。它优雅、智能&#xff0c;充满了东方美学韵味。但当你准备把它开放给更多人使用时&…...