我正在尝试使用一些MediaStore.Images.Thumbnails
代码从SD卡上的特定目录加载所有图像,但是在cursor
上获取空指针,这可能意味着它没有检索到任何内容。有谁知道如何正确使用MediaStore.Images.Thumbnails.getContentUri(String volumeName)
?我假设它是SD卡上目录的具体名称,但我猜这是错误的,因为我的代码不起作用。 Android doc pages非常模糊,没有任何帮助,我找不到有人尝试从特定目录中获取图像的单个示例。通常使用的是这个MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI
,它起作用,但它从谁知道在哪里拉出照片。我想你SD卡上的所有照片都在任何地方。
或者,如果您知道从SD卡上的特定目录中提取文件的解决方法,我将非常感激。
更新
以下是需要进行更改的方法。目前没有从SD卡上传任何内容,即使其中有2张照片。
private ArrayList<PhotoGridItem> loadSDCard() {
try {
// gets directory CutePhotos from sd card
File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_DOCUMENTS), "CutePhotos");
// lists all files in CutePhotos, loads in Files[] array
files = cutePhotosDir.listFiles();
for (File singleFile : files) {
String filePath = singleFile.getAbsolutePath();
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
photoList.add(new PhotoGridItem(bitmap));
}
} catch (Exception e) {
e.printStackTrace();
}
return photoList;
}
PhotoTab.java
package org.azurespot.cutecollection;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import org.azurespot.R;
/**
* Created by mizu on 2/8/15.
*/
public class PhotoTab extends Fragment{
private GridView gridView;
private GridViewPhotoAdapter gvPhotoAdapter;
Bitmap bitmap;
// Cursor used to access the results from querying for images on the SD card.
protected Cursor cursor;
// Column index for the Thumbnails Image IDs.
protected int columnIndex;
public PhotoTab(){
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.photo_tab, container, false);
// Set up an array of the Thumbnail Image ID column we want
String[] thumbNails = {MediaStore.Images.Thumbnails._ID};
cursor = getActivity().getContentResolver().query
(MediaStore.Images.Thumbnails.getContentUri("/Documents/CutePhotos"),
thumbNails, // Which columns to return
null, // Return all rows
null,
MediaStore.Images.Thumbnails.IMAGE_ID);
// Get the column index of the Thumbnails Image ID
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
// with fragments, make sure you include the rootView when finding id
gridView = (GridView) v.findViewById(R.id.photo_grid);
// Create the Custom Adapter Object, must use v.getContext() instead of
// getActivity()
gvPhotoAdapter = new GridViewPhotoAdapter(v.getContext());
// Set the Adapter to GridView
gridView.setAdapter(gvPhotoAdapter);
return v;
}
private class GridViewPhotoAdapter extends BaseAdapter {
public Context context;
public ImageView photoView;
public GridViewPhotoAdapter(Context context) {
this.context = context;
}
public int getCount() {
return 24;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
photoView = new ImageView(context);
// Move cursor to current position
cursor.moveToPosition(position);
// Get the current value for the requested column
int imageID = cursor.getInt(columnIndex);
// Set the content of the image based on the provided URI
photoView.setImageURI(Uri.withAppendedPath(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID));
// positioning the image in the GridView slot
photoView.setScaleType(ImageView.ScaleType.CENTER_CROP);
photoView.setLayoutParams(new GridView.LayoutParams(320, 320));
}
else {
photoView = (ImageView)convertView;
}
return photoView;
}
}
}
logcat的
FATAL EXCEPTION: main
Process: org.azurespot, PID: 10577
java.lang.NullPointerException
at org.azurespot.cutecollection.PhotoTab.onCreateView(PhotoTab.java:65)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:486)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1073)
at android.support.v4.view.ViewPager.populate(ViewPager.java:919)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1441)
at android.view.View.measure(View.java:17619)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:719)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455)
at android.view.View.measure(View.java:17619)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:17619)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:453)
at android.view.View.measure(View.java:17619)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:17619)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:17619)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5428)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2588)
at android.view.View.measure(View.java:17619)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2317)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1412)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1613)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1270)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6691)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:813)
at android.view.Choreographer.doCallbacks(Choreographer.java:613)
at android.view.Choreographer.doFrame(Choreographer.java:583)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:799)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5731)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
03-18 22:38:22.062 10577-10577/org.azurespot I/Process﹕ Sending signal. PID: 10577 SIG: 9
答案 0 :(得分:1)
我假设您只想从相机拍摄中获取照片。这是一个很好的网页@ Camera Saving Media。看Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
。它是图片的目录。静态类环境适用于其他有效目录。样本相关代码:
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyApp");
对象mediaStorageDir至少保存目录名称。
答案 1 :(得分:0)
看一下这篇文章:Listing thumbnails per bucket 它开始为所有文件夹带来gridview。然后在单击文件夹时,它会显示该文件夹中的图片。那就是OP想要的。
在onClick侦听器中使用String bucketId = thumbnails.getId(position);
来获取rigth文件夹。您需要更改类Th以将bucketId作为参数。然后selection = MediaStore.Images.Media.BUCKET_ID + "=" + buckedId;
答案 2 :(得分:0)
如果我理解正确,您只需要正确设置Uri。我查看了MediaScannerService的代码,这就是我所知道的。 Uri前缀可以是:
content://media/internal/
file://
在您的情况下,您可以尝试file:// Documents / CutePhotos 。
由于您已知道要使用哪个文件夹,因此您只需使用文件类,并将路径设置为/ Documents / CutePhotos。但是使用 Environment.DIRECTORY_DOCUMENTS 作为正确的路径前缀。 这种方式可以提高性能,因为它不使用数据库。