package cn.shangyu.gdxzExpert.activity; import android.Manifest; import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Build; import android.provider.MediaStore; import android.provider.MediaStore.Images.Thumbnails; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.FrameLayout.LayoutParams; import android.widget.GridView; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import com.gyf.immersionbar.ImmersionBar; import java.io.InvalidClassException; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import cn.shangyu.gdxzExpert.R; import cn.shangyu.gdxzExpert.adapter.PhotoAdappter2; import cn.shangyu.gdxzExpert.base.BaseActivity; import cn.shangyu.gdxzExpert.bean.PhotoAibum; import cn.shangyu.gdxzExpert.bean.PhotoItem; import cn.shangyu.gdxzExpert.ecdemo.common.ECPreferenceSettings; import cn.shangyu.gdxzExpert.ecdemo.common.ECPreferences; import cn.shangyu.gdxzExpert.photo.AlbumPreviewActivity; import cn.shangyu.gdxzExpert.utils.LogUtil; import cn.shangyu.gdxzExpert.utils.ToastUtil; import cn.shangyu.gdxzExpert.utils.UIUtils; import cn.shangyu.gdxzExpert.widget.LoadingPage.ResultState; /****************************************** * 类描述: 直接显示全部照片的相册选择页面 类名称:AllPhotosActivity * * @version: 1.0 * @author: Auto * @time: 2024 *****************************************/ public class AllPhotosActivity extends BaseActivity { private GridView photosGV; private PhotoAdappter2 adapter; private View view; private Intent getIntent; private String haveNums; private String istopc; private boolean isTopc = false; private boolean isTalke = false; private ArrayList gl_arr = new ArrayList(); private int PhotoNum = 8; int maxnumber, issendgroup; // 设置获取图片的字段信息 private static final String[] STORE_IMAGES = { MediaStore.Images.Media.DISPLAY_NAME, // 显示的名称 MediaStore.Images.Media.DATA,//路径 MediaStore.Images.Media.LONGITUDE, // 经度 MediaStore.Images.Media._ID, // id MediaStore.Images.Media.BUCKET_ID, // dir id 目录 MediaStore.Images.Media.BUCKET_DISPLAY_NAME // dir name 目录名字 }; @Override public void setTitle() { top_title.setText("选择图片"); } private PhotoAibum allPhotosAibum; @Override public View onCreateSuccessedView() { LogUtil.d("AllPhotosActivity", "onCreateSuccessedView: 开始创建视图"); ImmersionBar.with(this).keyboardEnable(true).statusBarDarkFont(true).titleBar(mToolbar).init(); view = UIUtils.inflate(R.layout.activity_photoalbum); photosGV = (GridView) view.findViewById(R.id.album_gridview); if (photosGV == null) { LogUtil.e("AllPhotosActivity", "onCreateSuccessedView: photosGV 为 null"); } // 直接加载所有照片 allPhotosAibum = getAllPhotos(); LogUtil.d("AllPhotosActivity", "onCreateSuccessedView: 照片加载完成, allPhotosAibum.bitList.size=" + (allPhotosAibum != null && allPhotosAibum.bitList != null ? allPhotosAibum.bitList.size() : 0)); if (allPhotosAibum == null || allPhotosAibum.bitList == null || allPhotosAibum.bitList.isEmpty()) { LogUtil.w("AllPhotosActivity", "onCreateSuccessedView: 照片列表为空,无法显示照片"); } initIntent(); initPhotosView(); LogUtil.d("AllPhotosActivity", "onCreateSuccessedView: 视图创建完成"); return view; } /** * 初始化照片视图 */ private void initPhotosView() { top_right_text.setVisibility(View.VISIBLE); if (isTopc) { maxnumber = 3; PhotoNum = 3; top_right_text.setText("确认" + haveNums + "/3"); } else { maxnumber = PhotoNum; top_right_text.setText("确认" + haveNums + "/" + PhotoNum); } top_right_text.setTextColor(AllPhotosActivity.this.getResources() .getColor(R.color.white)); top_right_text.setTextSize(14); top_right_text.setBackgroundResource(R.drawable.selector_btn); LayoutParams paras = (LayoutParams) top_right_text .getLayoutParams(); paras.setMargins(0, 0, dip2px(AllPhotosActivity.this, 10), 0); paras.height = dip2px(AllPhotosActivity.this, 30); top_right_text.setLayoutParams(paras); top_right_text.setOnClickListener(this); adapter = new PhotoAdappter2(this, allPhotosAibum); photosGV.setNumColumns(3); photosGV.setAdapter(adapter); adapter.setOnItemClickListener(new PhotoAdappter2.ViewItemClickListener() { @Override public void onItemClick(int position) { if (potisions.contains(position + "")) { potisions.remove(position + ""); haveNums = (Integer.parseInt(haveNums) - 1) + ""; } else { if (isTopc) { if (Integer.parseInt(haveNums) < 3) { potisions.add(position + ""); haveNums = (Integer.parseInt(haveNums) + 1) + ""; maxnumber = 3; } else { ToastUtil.showMessage("最多添加" + PhotoNum + "张"); return; } } else { if (Integer.parseInt(haveNums) < PhotoNum) { potisions.add(position + ""); haveNums = (Integer.parseInt(haveNums) + 1) + ""; maxnumber = PhotoNum; } else { ToastUtil.showMessage("最多添加" + PhotoNum + "张"); return; } } } if (isTopc) { maxnumber = 3; top_right_text.setText("确认" + haveNums + "/3"); } else { maxnumber = PhotoNum; top_right_text.setText("确认" + haveNums + "/" + PhotoNum); } adapter.getPosition(potisions); adapter.notifyDataSetChanged(); } }); photosGV.setOnItemClickListener(gvItemClickListener); } private ArrayList potisions = new ArrayList(); private OnItemClickListener gvItemClickListener = new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { Intent intent = new Intent(AllPhotosActivity.this, AlbumPreviewActivity.class); intent.putExtra(AlbumPreviewActivity.ARG_BUCKET_INDEX, 0); intent.putExtra(AlbumPreviewActivity.ARG_INDEX, position); intent.putExtra(AlbumPreviewActivity.MAX_NUMBER, maxnumber); intent.putExtra("aibum", allPhotosAibum); intent.putExtra("haveNums", Integer.parseInt(haveNums)); intent.putStringArrayListExtra("potisions", potisions); startActivityForResult(intent, 500); } }; ContentResolver cr; public void getpath() { LogUtil.d("AllPhotosActivity", "getpath: potisions=" + (potisions != null ? "not null, size=" + potisions.size() : "null") + ", allPhotosAibum=" + (allPhotosAibum != null ? "not null" : "null") + ", allPhotosAibum.bitList=" + (allPhotosAibum != null && allPhotosAibum.bitList != null ? "not null, size=" + allPhotosAibum.bitList.size() : "null")); gl_arr.clear(); if (potisions == null || potisions.isEmpty()) { LogUtil.w("AllPhotosActivity", "getpath: potisions 为空,没有选中的照片"); return; } if (allPhotosAibum == null || allPhotosAibum.bitList == null || allPhotosAibum.bitList.isEmpty()) { LogUtil.w("AllPhotosActivity", "getpath: allPhotosAibum 或 bitList 为空,无法获取照片"); return; } for (int i = 0; i < potisions.size(); i++) { try { int position = Integer.parseInt(potisions.get(i)); if (position >= 0 && position < allPhotosAibum.bitList.size()) { PhotoItem item = allPhotosAibum.bitList.get(position); if (item != null) { gl_arr.add(item); LogUtil.d("AllPhotosActivity", "getpath: 添加 PhotoItem[" + i + "], position=" + position + ", path=" + item.getPath()); } else { LogUtil.e("AllPhotosActivity", "getpath: PhotoItem[" + position + "] 为 null"); } } else { LogUtil.e("AllPhotosActivity", "getpath: 索引越界, position=" + position + ", bitList.size=" + allPhotosAibum.bitList.size()); } } catch (NumberFormatException e) { LogUtil.e("AllPhotosActivity", "getpath: 无法解析位置索引[" + i + "]=" + potisions.get(i) + ", error: " + e.getMessage()); } catch (Exception e) { LogUtil.e("AllPhotosActivity", "getpath: 处理位置[" + i + "]时发生异常, error: " + e.getMessage()); } } LogUtil.d("AllPhotosActivity", "getpath: 最终 gl_arr.size=" + gl_arr.size()); } private void getThumbnail() { LogUtil.d("AllPhotosActivity", "getThumbnail: 开始加载缩略图"); cr = AllPhotosActivity.this.getContentResolver(); String[] projection = { Thumbnails._ID, Thumbnails.IMAGE_ID, Thumbnails.DATA }; try { Cursor cursor = cr.query(Thumbnails.EXTERNAL_CONTENT_URI, projection, null, null, null); if (cursor == null) { LogUtil.w("AllPhotosActivity", "getThumbnail: cursor 为 null"); } else { LogUtil.d("AllPhotosActivity", "getThumbnail: cursor.count=" + cursor.getCount()); getThumbnailColumnData(cursor); } } catch (Exception e) { LogUtil.e("AllPhotosActivity", "getThumbnail: 查询缩略图时发生异常, error: " + e.getMessage()); e.printStackTrace(); } } HashMap thumbnailList = new HashMap(); private void getThumbnailColumnData(Cursor cur) { if (cur.moveToFirst()) { int _id; int image_id; String image_path; int _idColumn = cur.getColumnIndex(Thumbnails._ID); int image_idColumn = cur.getColumnIndex(Thumbnails.IMAGE_ID); int dataColumn = cur.getColumnIndex(Thumbnails.DATA); do { _id = cur.getInt(_idColumn); image_id = cur.getInt(image_idColumn); image_path = cur.getString(dataColumn); thumbnailList.put("" + image_id, image_path); } while (cur.moveToNext()); } } /** * 方法描述:获取所有照片(不分类) * * @author: Auto * @time: 2024 */ private PhotoAibum getAllPhotos() { LogUtil.d("AllPhotosActivity", "getAllPhotos: 开始加载所有照片, SDK_INT=" + Build.VERSION.SDK_INT); getThumbnail(); PhotoAibum allPhotos = new PhotoAibum(); allPhotos.setName("全部图片"); // 检查权限 boolean hasPermission = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // Android 13+ 需要 READ_MEDIA_IMAGES 权限 hasPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; LogUtil.d("AllPhotosActivity", "getAllPhotos: Android 13+, READ_MEDIA_IMAGES permission=" + hasPermission); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Android 6.0-12 需要 READ_EXTERNAL_STORAGE 权限 hasPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; LogUtil.d("AllPhotosActivity", "getAllPhotos: Android 6.0-12, READ_EXTERNAL_STORAGE permission=" + hasPermission); } else { // Android 6.0 以下不需要运行时权限 hasPermission = true; LogUtil.d("AllPhotosActivity", "getAllPhotos: Android < 6.0, 不需要运行时权限"); } if (!hasPermission) { LogUtil.e("AllPhotosActivity", "getAllPhotos: 没有读取照片的权限,无法查询照片"); ToastUtil.showMessage("需要照片访问权限才能查看相册"); return allPhotos; } try { LogUtil.d("AllPhotosActivity", "getAllPhotos: 查询 MediaStore.Images.Media.EXTERNAL_CONTENT_URI=" + MediaStore.Images.Media.EXTERNAL_CONTENT_URI); Cursor cursor = null; try { cursor = getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, STORE_IMAGES, null, null, MediaStore.Images.Media.DATE_ADDED + " ASC"); } catch (SecurityException e) { LogUtil.e("AllPhotosActivity", "getAllPhotos: SecurityException - 权限被拒绝, error: " + e.getMessage()); e.printStackTrace(); ToastUtil.showMessage("无法访问照片,请检查权限设置"); return allPhotos; } catch (Exception e) { LogUtil.e("AllPhotosActivity", "getAllPhotos: 查询时发生异常, error: " + e.getMessage()); e.printStackTrace(); return allPhotos; } if (cursor == null) { LogUtil.e("AllPhotosActivity", "getAllPhotos: cursor 为 null,无法查询照片"); return allPhotos; } int cursorCount = cursor.getCount(); LogUtil.d("AllPhotosActivity", "getAllPhotos: cursor.count=" + cursorCount); if (cursorCount == 0) { LogUtil.w("AllPhotosActivity", "getAllPhotos: cursor 为空,没有找到照片。可能原因:1)设备上没有照片 2)权限问题 3)Android 10+分区存储限制"); cursor.close(); return allPhotos; } List photoList = allPhotos.getBitList(); int processedCount = 0; while (cursor.moveToNext()) { try { String path = cursor.getString(1) + ""; String id = cursor.getString(3) + ""; if (path == null || path.isEmpty() || "null".equals(path)) { LogUtil.w("AllPhotosActivity", "getAllPhotos: 跳过无效路径的照片, id=" + id); continue; } processedCount++; if (processedCount <= 5) { LogUtil.d("AllPhotosActivity", "getAllPhotos: 处理照片[" + processedCount + "], id=" + id + ", path=" + path); } photoList.add(new PhotoItem(Integer.valueOf(id), path)); } catch (Exception e) { LogUtil.e("AllPhotosActivity", "getAllPhotos: 处理照片时发生异常, error: " + e.getMessage()); e.printStackTrace(); } } cursor.close(); allPhotos.setCount(photoList.size()); LogUtil.d("AllPhotosActivity", "getAllPhotos: 处理完成, processedCount=" + processedCount + ", total=" + photoList.size()); } catch (Exception e) { LogUtil.e("AllPhotosActivity", "getAllPhotos: 发生异常, error: " + e.getMessage()); e.printStackTrace(); } return allPhotos; } private void initIntent() { getIntent = getIntent(); haveNums = getIntent.getStringExtra("photonum"); PhotoNum = getIntent.getIntExtra("maxphotonum", 8); issendgroup = getIntent.getIntExtra("issendgroup", 0); if (haveNums.equals("-1")) { PhotoNum = 5; haveNums = "0"; isTalke = true; } else if ("1".equals(issendgroup + "")) { isTalke = true; } istopc = getIntent.getStringExtra("isTopic"); if (istopc != null && istopc.equals("isTopic")) { isTopc = true; } } @Override public ResultState onLoad() { return ResultState.STATE_SUCCESSED; } @Override protected void processClick(View v) { switch (v.getId()) { case R.id.top_right_text: LogUtil.d("AllPhotosActivity", "确认按钮点击,开始返回照片数据"); getpath(); LogUtil.d("AllPhotosActivity", "确认按钮: gl_arr.size=" + gl_arr.size() + ", isTalke=" + isTalke); if (gl_arr.size() > 0) { try { ECPreferences.savePreference( ECPreferenceSettings.SETTINGS_PREVIEW_SELECTED, Boolean.TRUE, true); } catch (InvalidClassException e) { e.printStackTrace(); } for (int i = 0; i < gl_arr.size(); i++) { PhotoItem item = gl_arr.get(i); LogUtil.d("AllPhotosActivity", "返回 PhotoItem[" + i + "]: path=" + (item != null ? item.getPath() : "null")); } } else { LogUtil.w("AllPhotosActivity", "确认按钮: gl_arr 为空,没有选择照片"); } Intent intent = new Intent(); intent.putExtra("photos", (Serializable) gl_arr); if (isTalke) { setResult(RESULT_OK, intent); LogUtil.d("AllPhotosActivity", "设置返回结果: RESULT_OK, photos count=" + gl_arr.size()); } else { setResult(102, intent); LogUtil.d("AllPhotosActivity", "设置返回结果: 102, photos count=" + gl_arr.size()); } this.finish(); break; default: break; } } // dp到像素的转换 public static int dip2px(Context context, double d) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (d * scale + 0.5f); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 500) { if (resultCode == Activity.RESULT_OK) { potisions = data.getExtras().getStringArrayList("potisions"); haveNums = data.getExtras().getInt("haveNums") + ""; adapter.getPosition(potisions); adapter.notifyDataSetChanged(); top_right_text.setText("确认" + haveNums + "/" + maxnumber + "张"); } } } }