我正在尝试使用默认的Android图库在特定文件夹中显示图像。我发现只有one sample code to do this。我简化了代码,现在很清楚了:
public class ScanActivity extends Activity implements MediaScannerConnectionClient {
private static final String SCAN_DIR = Environment.getExternalStorageDirectory() + File.separator + "MyFolder" + File.separator;
private static final String FILE_TYPE="image/*";
private String scanPath;
private MediaScannerConnection conn;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
scanPath = SCAN_DIR + new File(SCAN_DIR).list()[0];
conn = new MediaScannerConnection(getApplicationContext(), this);
conn.connect();
}
@Override
public void onMediaScannerConnected()
{
conn.scanFile(scanPath, FILE_TYPE);
}
@Override
public void onScanCompleted(String path, Uri uri)
{
try
{
if (uri != null)
{
//uri = content://media/external/images/media/11271
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, FILE_TYPE);
startActivity(intent);
}
}
finally
{
conn.disconnect();
conn = null;
}
}
}
在 Android Froyo(2.2)上工作正常 - 图库打开MyFolder
目录中的所有图片,但在 Jelly Bean(4.1)上我看到了黑屏(见下面的截图)。当然扫描的文件夹包含两个设备上的照片。
logcat输出:
11-03 18:31:31.872: W/DataManager(12540): exception in creating media object: /local/image/item/11271
11-03 18:31:31.872: W/DataManager(12540): java.lang.RuntimeException: cannot find data for: /local/image/item/11271
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.data.LocalImage.<init>(LocalImage.java:104)
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.data.LocalSource.createMediaObject(LocalSource.java:106)
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.data.DataManager.getMediaObject(DataManager.java:165)
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.data.LocalSource.getDefaultSetOf(LocalSource.java:183)
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.data.DataManager.getDefaultSetOf(DataManager.java:261)
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.app.Gallery.startViewAction(Gallery.java:198)
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.app.Gallery.initializeByIntent(Gallery.java:91)
11-03 18:31:31.872: W/DataManager(12540): at com.android.gallery3d.app.Gallery.onCreate(Gallery.java:68)
11-03 18:31:31.872: W/DataManager(12540): at android.app.Activity.performCreate(Activity.java:5008)
11-03 18:31:31.872: W/DataManager(12540): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-03 18:31:31.872: W/DataManager(12540): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140)
11-03 18:31:31.872: W/DataManager(12540): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2211)
11-03 18:31:31.872: W/DataManager(12540): at android.app.ActivityThread.access$600(ActivityThread.java:143)
11-03 18:31:31.872: W/DataManager(12540): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1209)
11-03 18:31:31.872: W/DataManager(12540): at android.os.Handler.dispatchMessage(Handler.java:99)
11-03 18:31:31.872: W/DataManager(12540): at android.os.Looper.loop(Looper.java:137)
11-03 18:31:31.872: W/DataManager(12540): at android.app.ActivityThread.main(ActivityThread.java:4965)
11-03 18:31:31.872: W/DataManager(12540): at java.lang.reflect.Method.invokeNative(Native Method)
11-03 18:31:31.872: W/DataManager(12540): at java.lang.reflect.Method.invoke(Method.java:511)
11-03 18:31:31.872: W/DataManager(12540): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
11-03 18:31:31.872: W/DataManager(12540): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
11-03 18:31:31.872: W/DataManager(12540): at dalvik.system.NativeStart.main(Native Method)
11-03 18:31:31.872: V/StateManager(12540): startState class com.android.gallery3d.app.PhotoPage
11-03 18:31:31.911: V/NFC(12540): this device does not have NFC support
11-03 18:31:32.044: W/DecodeService(12540): java.lang.NullPointerException
11-03 18:31:32.044: W/DecodeService(12540): at java.io.File.fixSlashes(File.java:185)
11-03 18:31:32.044: W/DecodeService(12540): at java.io.File.<init>(File.java:134)
11-03 18:31:32.044: W/DecodeService(12540): at java.io.FileInputStream.<init>(FileInputStream.java:105)
11-03 18:31:32.044: W/DecodeService(12540): at com.android.gallery3d.data.DecodeUtils.decodeThumbnail(DecodeUtils.java:92)
11-03 18:31:32.044: W/DecodeService(12540): at com.android.gallery3d.data.LocalImage$LocalImageRequest.onDecodeOriginal(LocalImage.java:188)
11-03 18:31:32.044: W/DecodeService(12540): at com.android.gallery3d.data.ImageCacheRequest.run(ImageCacheRequest.java:74)
11-03 18:31:32.044: W/DecodeService(12540): at com.android.gallery3d.data.LocalImage$LocalImageRequest.run(LocalImage.java:154)
11-03 18:31:32.044: W/DecodeService(12540): at com.android.gallery3d.data.ImageCacheRequest.run(ImageCacheRequest.java:28)
11-03 18:31:32.044: W/DecodeService(12540): at com.android.gallery3d.util.ThreadPool$Worker.run(ThreadPool.java:124)
11-03 18:31:32.044: W/DecodeService(12540): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-03 18:31:32.044: W/DecodeService(12540): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-03 18:31:32.044: W/DecodeService(12540): at java.lang.Thread.run(Thread.java:856)
11-03 18:31:32.044: W/DecodeService(12540): at com.android.gallery3d.util.PriorityThreadFactory$1.run(PriorityThreadFactory.java:43)
11-03 18:31:32.044: W/ImageCacheRequest(12540): decode orig failed /local/image/item/11271,THUMB
我用Google搜索,没有找到有关此例外的信息。
我真的很困惑这个问题而且不知道如何修复它。有谁知道如何解决它?感谢。
答案 0 :(得分:2)
似乎我发现了问题。改变行
conn.scanFile(scanPath, FILE_TYPE);
//what is ectualy equals to:
//conn.scanFile(scanPath, "image/*");
到这一行:
conn.scanFile(scanPath, null);
解决了问题。我不确定,但这似乎是一个Android错误。
答案 1 :(得分:1)
更改以下代码以扫描此文件夹中的所有文件。它适用于JB。
public void onMediaScannerConnected()
{
for(File f : allFiles)
{
conn.scanFile(f.getAbsolutePath(), "image/*");
}
}
答案 2 :(得分:0)
我遇到了类似的问题,这是我用来修复它的代码:
public class CostumeLog extends Activity{
Integer[] imageIDs = {R.drawable.login_button, R.drawable.logout_button};
File root = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/TrickorTreater/Photos");
File[] files;
Bitmap[] bitmapArray;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.costume_log_layout);
root.mkdirs();
Gallery gallery = (Gallery)findViewById(R.id.gallery1);
if ((root.isDirectory()) && (root.exists())){
files = root.listFiles();
if (!files.equals(null) || !(files.length <= 0)){
bitmapArray = new Bitmap[(files.length)];
for (int index = 0; (index <= files.length - 1); index++){
if (files[index] != null){
bitmapArray[index] = decodeSampledBitmapFromFile(files[index].toString(), 300, 240);
}//third if
}//for loop
gallery.setAdapter(new ImageAdapter(this));
gallery.setOnItemClickListener( new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id){
Intent viewImage = new Intent(CostumeLog.this, ViewLargeImage.class);
viewImage.putExtra("INDEX", position);
startActivity(viewImage);
}
});
}//second if
}//first if
}
public class ImageAdapter extends BaseAdapter{
Context context;
int itemBackground;
public ImageAdapter(Context c){
context = c;
TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
itemBackground = a.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
public int getCount() {
return bitmapArray.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View converView, ViewGroup parent) {
ImageView imageView;
if (converView == null) {
imageView = new ImageView(context);
imageView.setImageBitmap(bitmapArray[position]);
//imageView.setImageResource(imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(300, 240));
} else {
imageView = (ImageView) converView;
}
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
我希望这会有所帮助
答案 3 :(得分:0)
我来这里寻找同样的事情但是现在我最终设计了我自己的自定义画廊,也许它可以帮助那里的人:
public class ImageViewFlipper extends Activity {
private static final int EXIT = 0;
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private static final String DIRECTORY = "/sdcard/edu";
private static final String DATA_DIRECTORY = "/sdcard/edu";
private static final String DATA_FILE = "/sdcard/imagelist.dat";
private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;
private Animation slideLeftIn;
private Animation slideLeftOut;
private Animation slideRightIn;
private Animation slideRightOut;
private ViewFlipper viewFlipper;
private int currentView = 0;
List<String> ImageList;
private int currentIndex = 0;
private int maxIndex = 0;
FileOutputStream output = null;
OutputStreamWriter writer = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
ImageView iv = (ImageView) findViewById(R.id.zero);
File data_directory = new File(DATA_DIRECTORY);
if (!data_directory.exists()) {
if (data_directory.mkdir()) {
FileUtils savedata = new FileUtils();
Toast toast = Toast.makeText(ImageViewFlipper.this,
"Please wait while we search your SD Card for images...", Toast.LENGTH_SHORT);
toast.show();
SystemClock.sleep(100);
ImageList = FindFiles();
savedata.saveArray(DATA_FILE, ImageList);
} else {
ImageList = FindFiles();
}
}
else {
File data_file= new File(DATA_FILE);
if (!data_file.exists()) {
FileUtils savedata = new FileUtils();
SystemClock.sleep(100);
ImageList = FindFiles();
savedata.saveArray(DATA_FILE, ImageList);
} else {
FileUtils readdata = new FileUtils();
ImageList = readdata.loadArray(DATA_FILE);
}
}
if (ImageList == null) {
quit();
}
SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
MODE_PRIVATE);
if (indexPrefs.contains("currentIndex")) {
currentIndex = indexPrefs.getInt("currentIndex", 0);
}
maxIndex = ImageList.size() - 1;
Log.v("currentIndex", "Index: "+currentIndex);
viewFlipper = (ViewFlipper) findViewById(R.id.flipper);
slideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
slideLeftOut = AnimationUtils
.loadAnimation(this, R.anim.slide_left_out);
slideRightIn = AnimationUtils
.loadAnimation(this, R.anim.slide_right_in);
slideRightOut = AnimationUtils.loadAnimation(this,
R.anim.slide_right_out);
viewFlipper.setInAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_in));
viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_out));
iv.setImageDrawable(Drawable.createFromPath(ImageList
.get(currentIndex)));
System.gc();
gestureDetector = new GestureDetector(new MyGestureDetector());
gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
};
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
int NONE = Menu.NONE;
menu.add(NONE, EXIT, NONE, "Exit");
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case EXIT:
quit();
break;
}
return super.onOptionsItemSelected(item);
}
protected void onPause() {
super.onPause();
SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
MODE_PRIVATE);
SharedPreferences.Editor indexEditor = indexPrefs.edit();
indexEditor.putInt("currentIndex", currentIndex);
indexEditor.commit();
}
protected void onResume() {
super.onResume();
SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
MODE_PRIVATE);
if (indexPrefs.contains("currentIndex")) {
currentIndex = indexPrefs.getInt("currentIndex", 0);
}
}
private List<String> FindFiles() {
final List<String> tFileList = new ArrayList<String>();
Resources resources = getResources();
// array of valid image file extensions
String[] imageTypes = resources.getStringArray(R.array.image);
FilenameFilter[] filter = new FilenameFilter[imageTypes.length];
int i = 0;
for (final String type : imageTypes) {
filter[i] = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith("." + type);
}
};
i++;
}
FileUtils fileUtils = new FileUtils();
File[] allMatchingFiles = fileUtils.listFilesAsArray(
new File(DIRECTORY), filter, -1);
for (File f : allMatchingFiles) {
tFileList.add(f.getAbsolutePath());
}
return tFileList;
}
public class FileUtils {
public void saveArray(String filename, List<String> output_field) {
try {
FileOutputStream fos = new FileOutputStream(filename);
GZIPOutputStream gzos = new GZIPOutputStream(fos);
ObjectOutputStream out = new ObjectOutputStream(gzos);
out.writeObject(output_field);
out.flush();
out.close();
}
catch (IOException e) {
e.getStackTrace();
}
}
@SuppressWarnings("unchecked")
public List<String> loadArray(String filename) {
try {
FileInputStream fis = new FileInputStream(filename);
GZIPInputStream gzis = new GZIPInputStream(fis);
ObjectInputStream in = new ObjectInputStream(gzis);
List<String> read_field = (List<String>)in.readObject();
in.close();
return read_field;
}
catch (Exception e) {
e.getStackTrace();
}
return null;
}
public File[] listFilesAsArray(File directory, FilenameFilter[] filter,
int recurse) {
Collection<File> files = listFiles(directory, filter, recurse);
File[] arr = new File[files.size()];
return files.toArray(arr);
}
public Collection<File> listFiles(File directory,
FilenameFilter[] filter, int recurse) {
Vector<File> files = new Vector<File>();
File[] entries = directory.listFiles();
if (entries != null) {
for (File entry : entries) {
for (FilenameFilter filefilter : filter) {
if (filter == null
|| filefilter
.accept(directory, entry.getName())) {
files.add(entry);
Log.v("ImageViewFlipper", "Added: "
+ entry.getName());
}
}
if ((recurse <= -1) || (recurse > 0 && entry.isDirectory())) {
recurse--;
files.addAll(listFiles(entry, filter, recurse));
recurse++;
}
}
}
return files;
}
}
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
viewFlipper.setInAnimation(slideLeftIn);
viewFlipper.setOutAnimation(slideLeftOut);
if (currentIndex == maxIndex) {
currentIndex = 0;
} else {
currentIndex = currentIndex + 1;
}
if (currentView == 0) {
currentView = 1;
ImageView iv = (ImageView) findViewById(R.id.one);
iv.setImageDrawable(Drawable.createFromPath(ImageList
.get(currentIndex)));
System.gc();
} else if (currentView == 1) {
currentView = 2;
ImageView iv = (ImageView) findViewById(R.id.two);
iv.setImageDrawable(Drawable.createFromPath(ImageList
.get(currentIndex)));
System.gc();
} else {
currentView = 0;
ImageView iv = (ImageView) findViewById(R.id.zero);
iv.setImageDrawable(Drawable.createFromPath(ImageList
.get(currentIndex)));
System.gc();
}
Log.v("ImageViewFlipper", "Current View: " + currentView);
viewFlipper.showNext();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
viewFlipper.setInAnimation(slideRightIn);
viewFlipper.setOutAnimation(slideRightOut);
if (currentIndex == 0) {
currentIndex = maxIndex;
} else {
currentIndex = currentIndex - 1;
}
if (currentView == 0) {
currentView = 2;
ImageView iv = (ImageView) findViewById(R.id.two);
iv.setImageDrawable(Drawable.createFromPath(ImageList
.get(currentIndex)));
} else if (currentView == 2) {
currentView = 1;
ImageView iv = (ImageView) findViewById(R.id.one);
iv.setImageDrawable(Drawable.createFromPath(ImageList
.get(currentIndex)));
} else {
currentView = 0;
ImageView iv = (ImageView) findViewById(R.id.zero);
iv.setImageDrawable(Drawable.createFromPath(ImageList
.get(currentIndex)));
}
Log.v("ImageViewFlipper", "Current View: " + currentView);
viewFlipper.showPrevious();
}
} catch (Exception e) {
// nothing
}
return false;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
}
public void quit() {
SharedPreferences indexPrefs = getSharedPreferences("currentIndex",
MODE_PRIVATE);
SharedPreferences.Editor indexEditor = indexPrefs.edit();
indexEditor.putInt("currentIndex", 0);
indexEditor.commit();
File settings = new File(DATA_FILE);
settings.delete();
finish();
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
System.exit(0);
}
}
Dont forget: (Manifest)
android:configChanges="orientation"