如何在android画廊上显示特定文件夹中的图像
Posted
技术标签:
【中文标题】如何在android画廊上显示特定文件夹中的图像【英文标题】:How can I display images from a specific folder on android gallery 【发布时间】:2012-11-05 07:25:24 【问题描述】:如何在 android 库中显示特定文件夹中的所有图像,例如 whatapp 所做的。 我正在使用 MediaScannerConnectionClient
File folder = new File("/sdcard/myfolder/");
allFiles = folder.list();
SCAN_PATH=Environment.getExternalStorageDirectory().toString()+"/myfolder/"+allFiles[0];
@Override
public void onScanCompleted(String path, Uri uri)
try
if (uri != null)
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
finally
conn.disconnect();
conn = null;
private void startScan()
if (conn != null)
conn.disconnect();
conn = new MediaScannerConnection(this, this);
conn.connect();
@Override
public void onMediaScannerConnected()
conn.scanFile(SCAN_PATH, "image/*");
但此时我遇到了错误:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
这里具体:
startActivity(intent);
无法获取以下内容的类型:content://media/external/images/media/267830 没有找到处理 Intent 的 Activity
在 onScanCompleted 我的路径和 uri 参数不为空。
【问题讨论】:
你给出一个静态路径,你不需要调用你正在尝试使用意图的画廊 你是说我不需要 onScanCompleted 里面的代码? :是的..动作视图不会给你你打算做的静态路径。 This Tutorial Can Help you 【参考方案1】:您好,您可以使用下面的代码,希望对您有所帮助。
package com.example.browsepicture;
import java.io.File;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class BrowsePicture2 extends Activity
String SCAN_PATH;
File[] allFiles ;
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browse_picture);
File folder = new File(Environment.getExternalStorageDirectory().getPath()+"/aaaa/");
allFiles = folder.listFiles();
((Button) findViewById(R.id.button1))
.setOnClickListener(new OnClickListener()
public void onClick(View arg0)
new SingleMediaScanner(BrowsePicture2.this, allFiles[0]);
);
public class SingleMediaScanner implements MediaScannerConnectionClient
private MediaScannerConnection mMs;
private File mFile;
public SingleMediaScanner(Context context, File f)
mFile = f;
mMs = new MediaScannerConnection(context, this);
mMs.connect();
public void onMediaScannerConnected()
mMs.scanFile(mFile.getAbsolutePath(), null);
public void onScanCompleted(String path, Uri uri)
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
mMs.disconnect();
【讨论】:
talhakosen,我认为这个例子有点不同。有没有办法代替我开发自己的查看器,而是使用 android 本机画廊来显示我的图像文件夹? 但public void onScanCompleted(String path, Uri uri)
不会打开特定文件?这是allFiles[0]
?
是的@EladBenda,它只是打开一个特定的文件。但它会在图库中打开它,以便用户可以浏览图像。这并不理想,我同意。我正在开发一个基于 AOSP 的应用内图库库。周围似乎没有我所知道的。
folder.listFiles();返回空值。我在那个文件夹中有 2 张图片。有什么帮助吗?【参考方案2】:
您应该添加网格视图适配器类。
public class GalleryPictureActivity extends Activity
private String[] FilePathStrings;
private File[] listFile;
GridView grid;
GridViewAdapter adapter;
File file;
public static Bitmap bmp = null;
ImageView imageview;
@Override
protected void onCreate (Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery_picture);
// Check for SD Card
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED))
Toast.makeText(this, "Error! No SDCARD Found!",
Toast.LENGTH_LONG).show();
else
// Locate the image folder in your SD Card
file = new File(Environment.getExternalStorageDirectory()
.getPath() + "/images");
if (file.isDirectory())
listFile = file.listFiles();
FilePathStrings = new String[listFile.length];
for (int i = 0; i < listFile.length; i++)
FilePathStrings[i] = listFile[i].getAbsolutePath();
grid = (GridView)findViewById(R.id.gridview);
adapter = new GridViewAdapter(this, FilePathStrings);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick (AdapterView<?> parent, View view,
int position, long id)
imageview = (ImageView)findViewById(R.id.imageView1);
int targetWidth = 700;
int targetHeight = 500;
BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
bmpOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(FilePathStrings[position],
bmpOptions);
int currHeight = bmpOptions.outHeight;
int currWidth = bmpOptions.outWidth;
int sampleSize = 1;
if (currHeight > targetHeight || currWidth > targetWidth)
if (currWidth > currHeight)
sampleSize = Math.round((float)currHeight
/ (float)targetHeight);
else
sampleSize = Math.round((float)currWidth
/ (float)targetWidth);
bmpOptions.inSampleSize = sampleSize;
bmpOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(FilePathStrings[position],
bmpOptions);
imageview.setImageBitmap(bmp);
imageview.setScaleType(ImageView.ScaleType.FIT_XY);
bmp = null;
);
另一个类 GridView 适配器:
public class GridViewAdapter extends BaseAdapter
private Activity activity;
private String[] filepath;
private static LayoutInflater inflater = null;
Bitmap bmp = null;
public GridViewAdapter (Activity a, String[] fpath)
activity = a;
filepath = fpath;
inflater = (LayoutInflater)activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
public int getCount ()
return filepath.length;
public Object getItem (int position)
return position;
public long getItemId (int position)
return position;
public View getView (int position, View convertView, ViewGroup parent)
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.gridview_item, null);
ImageView image = (ImageView)vi.findViewById(R.id.image);
int targetWidth = 100;
int targetHeight = 100;
BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
bmpOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filepath[position], bmpOptions);
int currHeight = bmpOptions.outHeight;
int currWidth = bmpOptions.outWidth;
int sampleSize = 1;
if (currHeight > targetHeight || currWidth > targetWidth)
if (currWidth > currHeight)
sampleSize = Math.round((float)currHeight
/ (float)targetHeight);
else
sampleSize = Math.round((float)currWidth
/ (float)targetWidth);
bmpOptions.inSampleSize = sampleSize;
bmpOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(filepath[position], bmpOptions);
image.setImageBitmap(bmp);
image.setScaleType(ImageView.ScaleType.FIT_XY);
bmp = null;
return vi;
活动:
activity_gallery_picture:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
android:layout_
android:layout_
android:gravity="center" >
<GridView
android:id="@+id/gridview"
android:layout_
android:layout_
android:layout_weight=".85">
</GridView>
<ImageView
android:id="@+id/imageView1"
android:layout_
android:layout_
android:layout_weight=".25"
android:scaleType="fitXY"
android:src="@drawable/galleryimage" />
</LinearLayout>
另一个活动布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" >
<ImageView
android:id="@+id/image"
android:layout_
android:layout_ />
</RelativeLayout>
【讨论】:
Mediascanner 将在您扫描时显示已删除的图像【参考方案3】:你可以使用android.database.Cursor
public boolean OpenGalleryFromFolder(android.content.Context context, String folderName)
String filePath = android.os.Environment.getExternalStorageDirectory().getPath() + "/Pictures/" + folderName + "/";
return OpenGalleryFromPathToFolder(context, filePath);
// Finds the first image in the specified folder and uses it to open a the devices native gallery app with all images in that folder.
public boolean OpenGalleryFromPathToFolder(android.content.Context context, String folderPath)
java.io.File folder = new java.io.File(folderPath);
java.io.File[] allFiles = folder.listFiles();
if (allFiles != null && allFiles.length > 0)
android.net.Uri imageInFolder = getImageContentUri(context, allFiles[0]);
if (imageInFolder != null)
android.content.Intent intent = new android.content.Intent(android.content.Intent.ACTION_VIEW);
intent.setData(imageInFolder);
context.startActivity(intent);
return true;
return false;
// converts the absolute path of a file to a content path
// absolute path example: /storage/emulated/0/Pictures/folderName/Image1.jpg
// content path example: content://media/external/images/media/47560
private android.net.Uri getImageContentUri(android.content.Context context, java.io.File imageFile)
String filePath = imageFile.getAbsolutePath();
android.database.Cursor cursor = context.getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]android.provider.MediaStore.Images.Media._ID,
android.provider.MediaStore.Images.Media.DATA + "=? ",
new String[]filePath, null);
if (cursor != null && cursor.moveToFirst())
int id = cursor.getInt(cursor.getColumnIndex(android.provider.MediaStore.MediaColumns._ID));
return android.net.Uri.withAppendedPath(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id);
else
if (imageFile.exists())
android.content.ContentValues values = new android.content.ContentValues();
values.put(android.provider.MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
else
return null;
【讨论】:
【参考方案4】:@Talha 给出的答案效果很好,但它尝试使用图像应用程序选项打开图像。如果您只想用 sd 卡中的文件夹刷新图库,您可以为 SingleMediaScanner 修改如下代码
class SingleMediaScanner implements MediaScannerConnectionClient
private MediaScannerConnection mMs;
private File mFile;
public SingleMediaScanner(Context context, File f)
mFile = f;
mMs = new MediaScannerConnection(context, this);
mMs.connect();
public void onMediaScannerConnected()
mMs.scanFile(mFile.getAbsolutePath(), null);
public void onScanCompleted(String path, Uri uri)
mMs.disconnect();
然后在按钮单击循环中遍历您从中获取的每个文件:
File folder = new File(Environment.getExternalStorageDirectory().getPath()+"/aaaa/");
allFiles = folder.listFiles();
并一次将其传递给 SingleMediaScanner。
它在我的情况下有效。
【讨论】:
【参考方案5】:您可以使用我的方式从 SD 卡上的特定文件夹中获取图像,也可以删除文件。
主活动
FileAdapter fileAdapter;
RecyclerView recyclerView;
ArrayList<String> filePath = new ArrayList<>();
ArrayList<String> filename = new ArrayList<>();
private File[] listFile;
File file;
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
tv_empty = findViewById(R.id.tv_empty);
loadFiles();
fileAdapter = new FileAdapter(this, filePath, filename);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
recyclerView.setAdapter(fileAdapter);
fileAdapter.notifyDataSetChanged();
private void loadFiles()
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
Toast.makeText(getActivity(), "Error! No SDCARD Found!", Toast.LENGTH_LONG).show();
else
file = new File(Environment.getExternalStorageDirectory().getPath() + "/StorySaver");
if (!file.exists())
file.mkdirs();
filePath.clear();
filename.clear();
if (file.isDirectory())
listFile = file.listFiles();
for (File absolutePath : listFile)
filePath.add(absolutePath.getAbsolutePath());
filename.add(absolutePath.getName());
if (filePath.size() == 0)
tv_empty.setVisibility(View.VISIBLE);
else
tv_empty.setVisibility(View.GONE);
我的适配器
public class FileAdapter extends RecyclerView.Adapter<FileAdapter.CustomViewHolder>
ArrayList<String> filepath;
ArrayList<String> filename;
public Context mContext;
File file;
public class CustomViewHolder extends RecyclerView.ViewHolder
TextView content;
ImageView imageView;
public CustomViewHolder(final View view)
super(view);
this.content = (TextView) view.findViewById(R.id.content);
this.imageView = (ImageView) view.findViewById(R.id.image);
public FileAdapter(Context context, ArrayList<String> filepath, ArrayList<String> filename)
this.filepath = filepath;
this.filename = filename;
this.mContext = context;
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)
return new CustomViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_file, null));
public void onBindViewHolder(CustomViewHolder customViewHolder, final int i)
file = new File(filepath.get(i));
customViewHolder.content.setText(filename.get(i));
Glide.with(this.mContext).load(filepath.get(i)).into(customViewHolder.imageView);
customViewHolder.imageView.setOnLongClickListener(new OnLongClickListener()
public boolean onLongClick(View view)
Builder builder = new Builder(mContext);
builder.setMessage("Are you sure you want delete this?");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialogInterface, int v)
if (file.exists())
file.delete();
filepath.remove(i);
notifyDataSetChanged();
);
builder.setNegativeButton("NO", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialogInterface, int i)
dialogInterface.cancel();
);
builder.show();
return false;
);
customViewHolder.imageView.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
Uri data = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", new File(filepath.get(i)));
intent.setDataAndType(data, "*/*");
try
String substring = filename.get(i).substring(filename.get(i).lastIndexOf("."));
if (substring.equals(".jpg"))
intent.setDataAndType(data, "image/*");
else if (substring.equals(".mp4"))
intent.setDataAndType(data, "video/*");
catch (Exception e)
e.printStackTrace();
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try
mContext.startActivity(intent);
catch (ActivityNotFoundException unused)
Toast.makeText(mContext, "No application available", Toast.LENGTH_SHORT).show();
);
public int getItemCount()
return filepath.size();
【讨论】:
以上是关于如何在android画廊上显示特定文件夹中的图像的主要内容,如果未能解决你的问题,请参考以下文章