最近开发需要用到相机和相册。记录一下开发的过程。第一次再上写文章,各位看官不惜勿喷。如果有更好的方案一起交流。先上图
1、添加权限
Android 6版本以上需要动态添加权限
internal var permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.INTERNET)
internal var mPermissionList: MutableList = java.util.ArrayList()
private val mRequestCode = 100
private fun isPermission() {
if (Build.VERSION.SDK_INT >= 23){
mPermissionList.clear()
for (i in permissions.indices) {
if (ContextCompat.checkSelfPermission(
this,
permissions[i]
) != PackageManager.PERMISSION_GRANTED
) {
mPermissionList.add(permissions[i])
}
}
if (mPermissionList.size > 0) {
ActivityCompat.requestPermissions(this, permissions, mRequestCode)
}
}
}
2、调起相机
@RequiresApi(Build.VERSION_CODES.KITKAT)
private fun openCamera() {
val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
//判断是否有相机
//if (captureIntent.resolveActivity(packageManager)!= null){ //Android 11 判断为null
if(this.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) { //适配Android11
photoUri = creatImageUri()
mCameraUrl = photoUri
if (photoUri != null){
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri)
captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
startActivityForResult(captureIntent,PERMISSION_CAMERA_REQUEST_CODE)
}
}
}
3、调起系统相册,长按图片实现多选
private fun selectimage() {
Thread(Runnable {
runOnUiThread{
val intent = Intent()
intent.setType("image/*")
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true)
//intent.setAction(Intent.ACTION_GET_CONTENT) //实现相册多选 该方法获得的uri在转化为真实文件路径时Android 4.4以上版本会有问题
intent.setAction(Intent.ACTION_PICK)
intent.data = MediaStore.Images.Media.EXTERNAL_CONTENT_URI //直接打开系统相册 不设置会有选择相册一步(例:系统相册、QQ浏览器相册)
startActivityForResult(Intent.createChooser(intent,"Select Picture"),200)
}
}).start()
}
4、创建图片地址Uri,用于保存拍照后的照片
private fun creatImageUri(): Uri? {
val status = Environment.getExternalStorageState()
//判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机储存
if (status.equals(Environment.MEDIA_MOUNTED)){
return contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
ContentValues()
)
}else{
return contentResolver.insert(
MediaStore.Images.Media.INTERNAL_CONTENT_URI,
ContentValues()
)
}
}
5、重写onActivityResult,接收拍照结果和显示图片 从Uri获取图片
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
//拍照的结果
if (requestCode == PERMISSION_CAMERA_REQUEST_CODE){
if (resultCode == Activity.RESULT_OK){
//iv_photo.setImageURI(mCameraUrl)
bitmap = MediaStore.Images.Media.getBitmap(contentResolver,mCameraUrl)
imageUriList.add(mCameraUrl!!)
adapter.notifyDataSetChanged()
}
}
//相册选择的结果
else if (requestCode == 200 && data != null){
Thread(Runnable {
runOnUiThread {
val imageNames = data.clipData
if (imageNames != null){
for (i in 0..imageNames.itemCount - 1){
val uri = imageNames.getItemAt(i).uri
imageUriList.add(uri)
adapter.notifyDataSetChanged()
}
}else{
imageUriList.add(data.data!!)
adapter.notifyDataSetChanged()
}
}
}).start()
}
}
Demo功能基本完成下面附上整个Activity代码
class MainActivity : AppCompatActivity() {
// 申请相机权限的requestCode
private val PERMISSION_CAMERA_REQUEST_CODE = 0x00000012
private val PERMISSION_REQUEST = 1001
private var RC_CHOOSE_PHOTO: Int = 2
internal var permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.INTERNET)
internal var mPermissionList: MutableList = java.util.ArrayList()
private val mRequestCode = 100
private var mCameraUrl: Uri ?= null
private var photoUri: Uri ?= null
private lateinit var tv_camera: TextView
private lateinit var tv_album: TextView
private lateinit var gv_image: GridView
private lateinit var adapter: BaseAdapter
private lateinit var bt_clear: Button
var bitmap:Bitmap ?= null
private var imageUriList: ArrayList = ArrayList()
var file: File ?= null
var wordlist: ArrayList = ArrayList()
private lateinit var bt_gonext: Button
private var words: String ?= null
@RequiresApi(Build.VERSION_CODES.KITKAT)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
isPermission()
gv_image = findViewById(R.id.gv_image)
bt_gonext = findViewById(R.id.bt_gonext)
bt_clear = findViewById(R.id.bt_clear)
bt_clear.setOnClickListener {
wordlist.clear()
Toast.makeText(this,"清除缓存成功",Toast.LENGTH_SHORT).show()
}
bt_gonext.setOnClickListener {
val intent = Intent(this@MainActivity,ImageActivity::class.java)
intent.putExtra("data",words)
startActivity(intent)
}
//btn = findViewById(R.id.bt_btn)
//btn.setOnClickListener { selectimage() }
gv_image.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
if (position == parent.childCount - 1) {
if (imageUriList.size == 9){
Toast.makeText(this, "最多选择9张图片", Toast.LENGTH_LONG).show()
// }else{
//点击图片事件
}
}
adapter = SeleceImageAdapter(this,imageUriList)
gv_image.adapter = adapter
}
private fun isPermission() {
if (Build.VERSION.SDK_INT >= 23){
mPermissionList.clear()
for (i in permissions.indices) {
if (ContextCompat.checkSelfPermission(
this,
permissions[i]
) != PackageManager.PERMISSION_GRANTED
) {
mPermissionList.add(permissions[i])
}
}
if (mPermissionList.size > 0) {
ActivityCompat.requestPermissions(this, permissions, mRequestCode)
}
}
}
/**
* 调起系统相册
*/
private fun selectimage() {
Thread(Runnable {
runOnUiThread{
val intent = Intent()
intent.setType("image/*")
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,true)
//intent.setAction(Intent.ACTION_GET_CONTENT)
intent.setAction(Intent.ACTION_PICK)
intent.data = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
startActivityForResult(Intent.createChooser(intent,"Select Picture"),200)
}
}).start()
}
//region 拍照和相册功能
@RequiresApi(Build.VERSION_CODES.KITKAT)
private fun selectCameraDialog(context: Context) {
val flater = LayoutInflater.from(context)
val mView = flater.inflate(R.layout.select_camera_dialog, null)
tv_camera = mView.findViewById(R.id.tv_camera)
tv_album = mView.findViewById(R.id.tv_album)
val builder = AlertDialog.Builder(context).create()
builder.setTitle("请选择")
builder.setView(mView)
builder.setCancelable(true)
builder.setButton("取消",DialogInterface.OnClickListener { dialog, which ->
})
builder.show()
//选择拍照
tv_camera.setOnClickListener {
openCamera()
builder.dismiss()
}
//选择相册
tv_album.setOnClickListener {
selectimage()
builder.dismiss()
}
}
//region 拍照
/**
* 调起照相机
*/
@RequiresApi(Build.VERSION_CODES.KITKAT)
private fun openCamera() {
val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
//判断是否有相机
if (captureIntent.resolveActivity(packageManager)!= null){
photoUri = creatImageUri()
mCameraUrl = photoUri
if (photoUri != null){
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri)
captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
startActivityForResult(captureIntent,PERMISSION_CAMERA_REQUEST_CODE)
}
}
}
/**
* 创建图片地址Uri,用于保存拍照后的照片
*/
private fun creatImageUri(): Uri? {
val status = Environment.getExternalStorageState()
//判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机储存
if (status.equals(Environment.MEDIA_MOUNTED)){
return contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
ContentValues()
)
}else{
return contentResolver.insert(
MediaStore.Images.Media.INTERNAL_CONTENT_URI,
ContentValues()
)
}
}
/**
* 接收拍照结果和显示图片 从Uri获取图片
*/
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PERMISSION_CAMERA_REQUEST_CODE){
if (resultCode == Activity.RESULT_OK){
//iv_photo.setImageURI(mCameraUrl)
bitmap = MediaStore.Images.Media.getBitmap(contentResolver,mCameraUrl)
imageUriList.add(mCameraUrl!!)
adapter.notifyDataSetChanged()
}
}
else if (requestCode == 200 && data != null){
Thread(Runnable {
runOnUiThread {
val imageNames = data.clipData
if (imageNames != null){
for (i in 0..imageNames.itemCount - 1){
val uri = imageNames.getItemAt(i).uri
imageUriList.add(uri)
adapter.notifyDataSetChanged()
}
}else{
imageUriList.add(data.data!!)
adapter.notifyDataSetChanged()
}
}
}).start()
}
}
//endregion
/**
* 选择从相册中选取图片
* 单选
*/
// private fun selectAlbum() {
//val intent = Intent(Intent.ACTION_PICK, null)
//intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*")
//startActivityForResult(intent,RC_CHOOSE_PHOTO)
//}
//endregion
}