【问题标题】:Loading all the images from gallery into the Application in android将画廊中的所有图像加载到android中的应用程序中
【发布时间】:2013-09-06 14:00:29
【问题描述】:

我正在创建一个应用程序,其中我需要将图库中的所有图像放入我的应用程序中,其中包含一个 girdview。我希望所有文件夹中的所有图像都出现在 gridview 中。

String[] proj = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID };
actualimagecursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj,
                      null, null, MediaStore.Images.Media.DEFAULT_SORT_ORDER);

actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
actualimagecursor.moveToPosition(position);
String i = actualimagecursor.getString(actual_image_column_index);

我已将此代码添加到我的代码中,但我只获得了 sd 卡图像,没有获得其他文件夹图像。 如何从图库中获取所有图像?

提前致谢。

【问题讨论】:

标签: android image android-gallery


【解决方案1】:

Glide 的帮助下工作的解决方案。奖励部分是 Glide 会自动播放 Gif。

import java.util.ArrayList;

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;

/**
 * The Class GallarySample.
 */
public class GallarySample extends Activity {

    /** The images. */
    private ArrayList<String> images;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallery_activity);

        GridView gallery = (GridView) findViewById(R.id.galleryGridView);

        gallery.setAdapter(new ImageAdapter(this));

        gallery.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
                if (null != images && !images.isEmpty())
                    Toast.makeText(
                            getApplicationContext(),
                            "position " + position + " " + images.get(position),
                            300).show();
                ;

            }
        });

    }

    /**
     * The Class ImageAdapter.
     */
    private class ImageAdapter extends BaseAdapter {

        /** The context. */
        private Activity context;

        /**
         * Instantiates a new image adapter.
         *
         * @param localContext
         *            the local context
         */
        public ImageAdapter(Activity localContext) {
            context = localContext;
            images = getAllShownImagesPath(context);
        }

        public int getCount() {
            return images.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(final int position, View convertView,
                ViewGroup parent) {
            ImageView picturesView;
            if (convertView == null) {
                picturesView = new ImageView(context);
                picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                picturesView
                        .setLayoutParams(new GridView.LayoutParams(270, 270));

            } else {
                picturesView = (ImageView) convertView;
            }

            Glide.with(context).load(images.get(position))
                    .placeholder(R.drawable.ic_launcher).centerCrop()
                    .into(picturesView);

            return picturesView;
        }

        /**
         * Getting All Images Path.
         *
         * @param activity
         *            the activity
         * @return ArrayList with images Path
         */
        private ArrayList<String> getAllShownImagesPath(Activity activity) {
            Uri uri;
            Cursor cursor;
            int column_index_data, column_index_folder_name;
            ArrayList<String> listOfAllImages = new ArrayList<String>();
            String absolutePathOfImage = null;
            uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

            String[] projection = { MediaColumns.DATA,
                    MediaStore.Images.Media.BUCKET_DISPLAY_NAME };

            cursor = activity.getContentResolver().query(uri, projection, null,
                    null, null);

            column_index_data = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
            column_index_folder_name = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
            while (cursor.moveToNext()) {
                absolutePathOfImage = cursor.getString(column_index_data);

                listOfAllImages.add(absolutePathOfImage);
            }
            return listOfAllImages;
        }
    }
}

gridView 的布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <GridView
        android:id="@+id/galleryGridView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnWidth="280dp"
        android:gravity="center"
        android:horizontalSpacing="2dp"
        android:numColumns="2"
        android:padding="2dp"
        android:stretchMode="columnWidth"
        android:verticalSpacing="2dp" >
    </GridView>

</RelativeLayout>

2019 年更新,KotlinLoderManager

** 2) 使用 LoderManager 加载异步加载图片。**

在您的活动或片段类中实现LoaderManager.LoaderCallbacks&lt;Cursor&gt;

重写 LoaderCallbacks 这个:

private val IMAGE_LOADER_ID = 1
private val listOfAllImages = ArrayList<String>()



override fun onCreateLoader(p0: Int, p1: Bundle?): Loader<Cursor> {

    val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    val projection = arrayOf(MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
    val selection: String? = null     //Selection criteria
    val selectionArgs = arrayOf<String>()  //Selection criteria
    val sortOrder: String? = null

    return CursorLoader(
            activity!!.applicationContext,
            uri,
            projection,
            selection,
            selectionArgs,
            sortOrder)
}

override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor?) {

    cursor?.let {
        val columnIndexData = it.getColumnIndexOrThrow(MediaColumns.DATA);

        while (it.moveToNext()) {

            listOfAllImages.add(it.getString(columnIndexData));
        }
    }
}


override fun onLoaderReset(loader: Loader<Cursor>) {
}

最后是 onCreate 方法初始化加载器:

 loaderManager.initLoader(IMAGE_LOADER_ID,
                null,
                this)

3) 使用Kotlin Coroutine & ViewModel

实现'androidx.core:core-ktx:1.0.2'

实现'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-M2'

实现“org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0-M2”

使用Coroutine 上下文创建视图模型

  /**
   * Use Coroutines To Load Images
   */
   class ImageViewModel : ViewModel(), CoroutineScope {

    private val job = Job()
    override val coroutineContext: CoroutineContext
        get() = job + Dispatchers.Main

    private var imagesLiveData: MutableLiveData<List<String>> = MutableLiveData()
    fun getImageList(): MutableLiveData<List<String>> {
        return imagesLiveData
    }

    /**
     * Getting All Images Path.
     *
     * Required Storage Permission
     *
     * @return ArrayList with images Path
     */
    internal fun loadImagesfromSDCard(): ArrayList<String> {
        val uri: Uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        val cursor: Cursor?
        val column_index_data: Int
        val column_index_folder_name: Int
        val listOfAllImages = ArrayList<String>()
        var absolutePathOfImage: String? = null

        val projection = arrayOf(MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME)

        cursor = AppController.globalContentResolvere!!.query(uri, projection, null, null, null)

        column_index_data = cursor!!.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)
        column_index_folder_name = cursor!!
            .getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
        while (cursor!!.moveToNext()) {
            absolutePathOfImage = cursor!!.getString(column_index_data)
            listOfAllImages.add(absolutePathOfImage)
        }
        return listOfAllImages
    }

    fun getAllImages() {
        launch(Dispatchers.Main) {
            imagesLiveData.value = withContext(Dispatchers.IO) {
                loadImagesfromSDCard()
            }
        }
    }
}

然后使用viewModel

 val imageViewModel = ViewModelProviders.of(this).get(ImageViewModel::class.java)

    imageViewModel.getImageList().observe(this, Observer<List<String>> { listOfImage ->
        imageWidgetStatus.text = """ Found ${listOfImage.size} Images"""


    // load images
    imageViewModel.getAllImages()

【讨论】:

  • 有没有办法对图像进行排序并逐月显示?以及如何将视频与图像一起显示。
  • 有一个 MediaStore.Images.Media.DEFAULT_SORT_ORDER.. 这是查询的参数... cursor = activity.getContentResolver().query(uri, projection, null, null, MediaStore.图片.Media.DEFAULT_SORT_ORDER);
  • 访问 DATA 路径似乎已被弃用
  • 你为什么要在另一个协程中启动一个协程。可以删除 getAllImages() 中的外部启动以防止不必要的上下文切换
  • ImageViewModel 类 kotlin 中的 AppController 是什么?
【解决方案2】:

您正在使用MediaStore.Images.Media.EXTERNAL_CONTENT_URI,这只是外部存储。对于内部有MediaStore.Images.Media.INTERNAL_CONTENT_URI。 您可以使用MergeCursor 来合并两个查询结果。

【讨论】:

  • 我也尝试过这样做,但可以做到。对于 INTERNAL_CONTENT_URI 它说没有可用的数据。虽然我的手机内存里也有图片
  • 你所说的内部存储是什么意思?
  • 内部存储是您的应用程序可以存储文件的默认位置。它对您的应用是私有的。
  • 例如 +1
【解决方案3】:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE);

【讨论】:

  • 它将允许您从手机中的任何位置选择图像
  • 嘿朋友 Onik 我已经代表如何从画廊或 android 手机中的任何位置获取图像给出了答案
【解决方案4】:
 public static ArrayList<String> fetchGalleryImages(Activity context) {
        ArrayList<String> galleryImageUrls;
        final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID};//get all columns of type images
        final String orderBy = MediaStore.Images.Media.DATE_TAKEN;//order data by date

        Cursor imagecursor = context.managedQuery(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
                null, orderBy + " DESC");//get all data in Cursor by sorting in DESC order

        galleryImageUrls = new ArrayList<String>();

        for (int i = 0; i < imagecursor.getCount(); i++) {
            imagecursor.moveToPosition(i);
            int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);//get column index
            galleryImageUrls.add(imagecursor.getString(dataColumnIndex));//get Image from column index

        }
        Log.e("fatch in","images");
        return galleryImageUrls;
    }

【讨论】:

    【解决方案5】:

    你不能只用一个查询得到结果,尝试实例化两个不同的游标。 既然你已经添加了EXTERNAL_CONTENT_URI,这里还有一个:

     actualimagecursor2 = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI, proj,
                          null, null, MediaStore.Images.Media.DEFAULT_SORT_ORDER);
    

    【讨论】:

      【解决方案6】:

      从这里下载源代码 (Get all images from gallery in android programmatically)

      activity_main.xml

      <RelativeLayout android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="#ffffff"
      xmlns:android="http://schemas.android.com/apk/res/android">
      
      
      <GridView
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:id="@+id/gv_folder"
          android:numColumns="2"
          android:layout_marginLeft="10dp"
          android:layout_marginRight="10dp"></GridView>
      
      
      </RelativeLayout>
      

      MainActivity.java

      package galleryimages.galleryimages;
      
      import android.Manifest;
      import android.content.Intent;
      import android.content.pm.PackageManager;
      import android.database.Cursor;
      import android.net.Uri;
      import android.provider.MediaStore;
      import android.support.v4.app.ActivityCompat;
      import android.support.v4.content.ContextCompat;
      import android.support.v7.app.AppCompatActivity;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.View;
      import android.widget.AdapterView;
      import android.widget.GridView;
      import android.widget.Toast;
      
      import java.util.ArrayList;
      
      public class MainActivity extends AppCompatActivity {
      public static ArrayList<Model_images> al_images = new ArrayList<>();
      boolean boolean_folder;
      Adapter_PhotosFolder obj_adapter;
      GridView gv_folder;
      private static final int REQUEST_PERMISSIONS = 100;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          gv_folder = (GridView)findViewById(R.id.gv_folder);
      
          gv_folder.setOnItemClickListener(new AdapterView.OnItemClickListener() {
              @Override
              public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                  Intent intent = new Intent(getApplicationContext(), PhotosActivity.class);
                  intent.putExtra("value",i);
                  startActivity(intent);
              }
          });
      
      
          if ((ContextCompat.checkSelfPermission(getApplicationContext(),
                  Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(),
                  Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
              if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                      Manifest.permission.WRITE_EXTERNAL_STORAGE)) && (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                      Manifest.permission.READ_EXTERNAL_STORAGE))) {
      
              } else {
                  ActivityCompat.requestPermissions(MainActivity.this,
                          new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
                          REQUEST_PERMISSIONS);
              }
          }else {
              Log.e("Else","Else");
              fn_imagespath();
          }
      
      
      
      }
      
      public ArrayList<Model_images> fn_imagespath() {
          al_images.clear();
      
          int int_position = 0;
          Uri uri;
          Cursor cursor;
          int column_index_data, column_index_folder_name;
      
          String absolutePathOfImage = null;
          uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
      
          String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
      
          final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
          cursor = getApplicationContext().getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
      
          column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
          column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
          while (cursor.moveToNext()) {
              absolutePathOfImage = cursor.getString(column_index_data);
              Log.e("Column", absolutePathOfImage);
              Log.e("Folder", cursor.getString(column_index_folder_name));
      
              for (int i = 0; i < al_images.size(); i++) {
                  if (al_images.get(i).getStr_folder().equals(cursor.getString(column_index_folder_name))) {
                      boolean_folder = true;
                      int_position = i;
                      break;
                  } else {
                      boolean_folder = false;
                  }
              }
      
      
              if (boolean_folder) {
      
                  ArrayList<String> al_path = new ArrayList<>();
                  al_path.addAll(al_images.get(int_position).getAl_imagepath());
                  al_path.add(absolutePathOfImage);
                  al_images.get(int_position).setAl_imagepath(al_path);
      
              } else {
                  ArrayList<String> al_path = new ArrayList<>();
                  al_path.add(absolutePathOfImage);
                  Model_images obj_model = new Model_images();
                  obj_model.setStr_folder(cursor.getString(column_index_folder_name));
                  obj_model.setAl_imagepath(al_path);
      
                  al_images.add(obj_model);
      
      
              }
      
      
          }
      
      
          for (int i = 0; i < al_images.size(); i++) {
              Log.e("FOLDER", al_images.get(i).getStr_folder());
              for (int j = 0; j < al_images.get(i).getAl_imagepath().size(); j++) {
                  Log.e("FILE", al_images.get(i).getAl_imagepath().get(j));
              }
          }
          obj_adapter = new Adapter_PhotosFolder(getApplicationContext(),al_images);
          gv_folder.setAdapter(obj_adapter);
          return al_images;
      }
      
      @Override
      public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      
          switch (requestCode) {
              case REQUEST_PERMISSIONS: {
                  for (int i = 0; i < grantResults.length; i++) {
                      if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                          fn_imagespath();
                      } else {
                          Toast.makeText(MainActivity.this, "The app was not allowed to read or write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
                      }
                  }
              }
          }
      }
      
      }
      

      adapter_photosfolder.xml

         <?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
      
      
          <LinearLayout
              android:layout_width="match_parent"
              android:orientation="vertical"
              android:layout_marginTop="10dp"
              android:layout_marginLeft="10dp"
              android:background="@drawable/drawable_photofolder"
              android:layout_marginRight="10dp"
              android:layout_marginBottom="10dp"
              android:layout_height="match_parent">
          <ImageView
              android:layout_width="150dp"
              android:layout_gravity="center"
              android:layout_height="150dp"
              android:id="@+id/iv_image"/>
      
          <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:id="@+id/tv_folder"
              android:textStyle="bold"
              android:textColor="#000000"
              android:layout_marginLeft="10dp"
              android:textSize="15dp"/>
      
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:id="@+id/tv_folder2"
                  android:textColor="#dfdfdf"
                  android:layout_marginBottom="10dp"
                  android:layout_marginLeft="10dp"
                  android:textSize="15dp"/>
          </LinearLayout>
      
          <RelativeLayout
              android:layout_width="match_parent"
              android:id="@+id/rl_select"
              android:alpha="0.5"
              android:layout_height="match_parent">
      
          </RelativeLayout>
      
          </RelativeLayout>
      

      Adapter_PhotosFolder.java

          package galleryimages.galleryimages;
      
      
          import android.content.Context;
          import android.util.Log;
          import android.view.LayoutInflater;
          import android.view.View;
          import android.view.ViewGroup;
          import android.widget.ArrayAdapter;
          import android.widget.ImageView;
          import android.widget.TextView;
      
          import com.bumptech.glide.Glide;
          import com.bumptech.glide.load.engine.DiskCacheStrategy;
      
          import java.util.ArrayList;
      
      
           public class Adapter_PhotosFolder extends ArrayAdapter<Model_images> {
      
          Context context;
          ViewHolder viewHolder;
          ArrayList<Model_images> al_menu = new ArrayList<>();
      
      
          public Adapter_PhotosFolder(Context context, ArrayList<Model_images> al_menu) {
              super(context, R.layout.adapter_photosfolder, al_menu);
              this.al_menu = al_menu;
              this.context = context;
      
      
          }
      
          @Override
          public int getCount() {
      
              Log.e("ADAPTER LIST SIZE", al_menu.size() + "");
              return al_menu.size();
          }
      
          @Override
          public int getItemViewType(int position) {
              return position;
          }
      
          @Override
          public int getViewTypeCount() {
              if (al_menu.size() > 0) {
                  return al_menu.size();
              } else {
                  return 1;
              }
          }
      
          @Override
          public long getItemId(int position) {
              return position;
          }
      
      
          @Override
          public View getView(final int position, View convertView, ViewGroup parent) {
      
              if (convertView == null) {
      
                  viewHolder = new ViewHolder();
                  convertView = LayoutInflater.from(getContext()).inflate(R.layout.adapter_photosfolder, parent, false);
                  viewHolder.tv_foldern = (TextView) convertView.findViewById(R.id.tv_folder);
                  viewHolder.tv_foldersize = (TextView) convertView.findViewById(R.id.tv_folder2);
                  viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.iv_image);
      
      
                  convertView.setTag(viewHolder);
              } else {
                  viewHolder = (ViewHolder) convertView.getTag();
              }
      
              viewHolder.tv_foldern.setText(al_menu.get(position).getStr_folder());
                  viewHolder.tv_foldersize.setText(al_menu.get(position).getAl_imagepath().size()+"");
      
      
      
              Glide.with(context).load("file://" + al_menu.get(position).getAl_imagepath().get(0))
                      .diskCacheStrategy(DiskCacheStrategy.NONE)
                      .skipMemoryCache(true)
                      .into(viewHolder.iv_image);
      
      
              return convertView;
      
          }
      
          private static class ViewHolder {
              TextView tv_foldern, tv_foldersize;
              ImageView iv_image;
      
      
          }
      
      
          }
      
      **PhotosActivity.java**
          package galleryimages.galleryimages;
          import android.app.Activity;
          import android.os.Bundle;
          import android.support.v7.app.AppCompatActivity;
          import android.widget.GridView;
      
      
          public class PhotosActivity extends AppCompatActivity {
          int int_position;
          private GridView gridView;
          GridViewAdapter adapter;
      
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              gridView = (GridView)findViewById(R.id.gv_folder);
              int_position = getIntent().getIntExtra("value", 0);
              adapter = new GridViewAdapter(this,MainActivity.al_images,int_position);
              gridView.setAdapter(adapter);
          }
      }
      
      **GridViewAdapter.java**
      
      package galleryimages.galleryimages;
      
      
          import android.app.Activity;
          import android.content.Context;
          import android.util.Log;
          import android.view.LayoutInflater;
          import android.view.View;
          import android.view.ViewGroup;
          import android.widget.ArrayAdapter;
          import android.widget.BaseAdapter;
          import android.widget.ImageView;
          import android.widget.TextView;
      
          import com.bumptech.glide.Glide;
          import com.bumptech.glide.load.engine.DiskCacheStrategy;
      
      
          import java.util.ArrayList;
          import java.util.List;
      
      
          public class GridViewAdapter extends ArrayAdapter<Model_images> {
      
          Context context;
          ViewHolder viewHolder;
          ArrayList<Model_images> al_menu = new ArrayList<>();
          int int_position;
      
      
          public GridViewAdapter(Context context, ArrayList<Model_images> al_menu,int int_position) {
              super(context, R.layout.adapter_photosfolder, al_menu);
              this.al_menu = al_menu;
              this.context = context;
              this.int_position = int_position;
      
      
          }
      
          @Override
          public int getCount() {
      
              Log.e("ADAPTER LIST SIZE", al_menu.get(int_position).getAl_imagepath().size() + "");
              return al_menu.get(int_position).getAl_imagepath().size();
          }
      
          @Override
          public int getItemViewType(int position) {
              return position;
          }
      
          @Override
          public int getViewTypeCount() {
              if (al_menu.get(int_position).getAl_imagepath().size() > 0) {
                  return al_menu.get(int_position).getAl_imagepath().size();
              } else {
                  return 1;
              }
          }
      
          @Override
          public long getItemId(int position) {
              return position;
          }
      
      
          @Override
          public View getView(final int position, View convertView, ViewGroup parent) {
      
              if (convertView == null) {
      
                  viewHolder = new ViewHolder();
                  convertView = LayoutInflater.from(getContext()).inflate(R.layout.adapter_photosfolder, parent, false);
                  viewHolder.tv_foldern = (TextView) convertView.findViewById(R.id.tv_folder);
                  viewHolder.tv_foldersize = (TextView) convertView.findViewById(R.id.tv_folder2);
                  viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.iv_image);
      
      
                  convertView.setTag(viewHolder);
              } else {
                  viewHolder = (ViewHolder) convertView.getTag();
              }
      
              viewHolder.tv_foldern.setVisibility(View.GONE);
              viewHolder.tv_foldersize.setVisibility(View.GONE);
      
      
      
              Glide.with(context).load("file://" + al_menu.get(int_position).getAl_imagepath().get(position))
                      .diskCacheStrategy(DiskCacheStrategy.NONE)
                      .skipMemoryCache(true)
                      .into(viewHolder.iv_image);
      
      
              return convertView;
      
          }
      
          private static class ViewHolder {
              TextView tv_foldern, tv_foldersize;
              ImageView iv_image;
      
      
          }
      
      
          }
      

      Model_images.java

        package galleryimages.galleryimages;
      
          import java.util.ArrayList;
      
          public class Model_images {
          String str_folder;
          ArrayList<String> al_imagepath;
      
          public String getStr_folder() {
              return str_folder;
          }
      
          public void setStr_folder(String str_folder) {
              this.str_folder = str_folder;
          }
      
          public ArrayList<String> getAl_imagepath() {
              return al_imagepath;
          }
      
          public void setAl_imagepath(ArrayList<String> al_imagepath) {
              this.al_imagepath = al_imagepath;
          }
      }
      

      AndroidManifest.xml

      <?xml version="1.0" encoding="utf-8"?>
      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="galleryimages.galleryimages">
      
          <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
          <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
      
          <application
              android:allowBackup="true"
              android:icon="@mipmap/ic_launcher"
              android:label="@string/app_name"
              android:supportsRtl="true"
              android:theme="@style/AppTheme">
              <activity android:name=".MainActivity">
                  <intent-filter>
                      <action android:name="android.intent.action.MAIN" />
      
                      <category android:name="android.intent.category.LAUNCHER" />
                  </intent-filter>
              </activity>
      
              <activity android:name=".PhotosActivity"></activity>
          </application>
      
      </manifest>
      

      【讨论】:

      • 看图不需要android.permission.WRITE_EXTERNAL_STORAGE
      • 很抱歉,这段代码写得很糟糕……读起来很痛苦,或者我只是习惯了 java 风格。还是谢谢
      【解决方案7】:

      这就是我在 Kotlin 中使用 Coroutines 和 Flow 的方式(但 Flow 可以轻松更改为 LivaData)。

      依赖关系:

      def lifecycle_version = "2.2.0"
      def coroutines_version = "1.4.2"
      def glide_version = "4.11.0"
      
      // Coroutines https://github.com/Kotlin/kotlinx.coroutines
      implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
      implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
      
      // Lifecycle https://developer.android.com/jetpack/androidx/releases/lifecycle#declaring_dependencies
      implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
      
      // Glide https://github.com/bumptech/glide (OPTIONALLY)
      implementation "com.github.bumptech.glide:glide:$glide_version"
      

      视图模型:

      import android.app.Application
      import android.content.ContentUris
      import android.net.Uri
      import android.provider.MediaStore
      import androidx.lifecycle.AndroidViewModel
      import androidx.lifecycle.viewModelScope
      import kotlinx.coroutines.Dispatchers
      import kotlinx.coroutines.flow.MutableStateFlow
      import kotlinx.coroutines.flow.StateFlow
      import kotlinx.coroutines.launch
      import kotlinx.coroutines.withContext
      
      class AddViewModel(
          application: Application
      ) : AndroidViewModel(application)
      {
          private val _allImagesFromGallery: MutableStateFlow<List<Uri>> = MutableStateFlow(listOf())
          val allImagesFromGallery: StateFlow<List<Uri>> = _allImagesFromGallery
      
          private fun getAllImages(): List<Uri>
          {
              val allImages = mutableListOf<Uri>()
      
              val imageProjection = arrayOf(
                  MediaStore.Images.Media._ID
              )
      
              val imageSortOrder = "${MediaStore.Images.Media.DATE_ADDED} DESC"
      
              val cursor = getApplication<Application>().contentResolver.query(
                  MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                  imageProjection,
                  null,
                  null,
                  imageSortOrder
              )
      
              cursor.use {
      
                  if (cursor != null)
                  {
                      val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
                      while (cursor.moveToNext())
                      {
                          allImages.add(
                              ContentUris.withAppendedId(
                                  MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                                  cursor.getLong(idColumn)
                              )
                          )
                      }
                  }
                  else
                  {
                      Log.d("AddViewModel", "Cursor is null!")
                  }
              }
              return allImages
          }
      
          fun loadAllImages()
          {
              viewModelScope.launch {
                  _allImagesFromGallery.value = withContext(Dispatchers.IO) {
                      getAllImages()
                  }
              }
          }
      }
      

      在片段(或活动)中:

      import android.os.Bundle
      import android.view.View
      import androidx.databinding.DataBindingUtil
      import androidx.fragment.app.Fragment
      import androidx.fragment.app.activityViewModels
      import androidx.lifecycle.lifecycleScope
      import com.bumptech.glide.Glide
      import kotlinx.coroutines.flow.collectLatest
      
      class AddFragment : Fragment(R.layout.fragment_add)
      {
          private lateinit var binding: FragmentAddBinding
          private val viewModel: AddViewModel by activityViewModels()
      
          override fun onViewCreated(view: View, savedInstanceState: Bundle?)
          {
              super.onViewCreated(view, savedInstanceState)
              binding = DataBindingUtil.bind(view)!!
      
              viewModel.loadAllImages()
              setupCollecting()
          }
      
          private fun setupCollecting()
          {
              lifecycleScope.launchWhenStarted {
                  viewModel.allImagesFromGallery.collectLatest {
                      // simple test, take first image and load it to ImageView using Glide
                      if (it.isNotEmpty())
                      {
                          Glide.with(requireContext())
                              .load(it[0])
                              .into(binding.imgSelected)
                      }
                  }
              }
          }
      }
      

      1. 在从图库中加载所有图片之前,Manifest.permission.READ_EXTERNAL_STORAGE 必须获得授权。

      2. 当在 Manifest 中使用 Glide 时,还应该有:android:requestLegacyExternalStorage="true"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多