0

我正在尝试使用默认的 Android 图库在特定文件夹中显示图像。我发现只有一个示例代码可以做到这一点。我已经简化了该代码,现在很清楚了:

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)上我只看到黑屏(见下面的屏幕截图)。当然,扫描的文件夹包含两台设备上的照片。

截图 4.1

日志输出:

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

我用谷歌搜索并没有发现有关此异常的信息。

我真的很困惑这个问题,不知道如何解决它。有谁知道如何解决它?谢谢。

4

5 回答 5

2

看来我发现了问题。换线

conn.scanFile(scanPath, FILE_TYPE);

//what is ectualy equals to:
//conn.scanFile(scanPath, "image/*");

到这一行:

conn.scanFile(scanPath, null);

修复了一个问题。我不确定,但这似乎是一个 Android 错误。

于 2012-11-05T20:39:22.733 回答
1

我在果冻豆上遇到了同样的问题。FILE_TYPE = "image/jpeg" 为我解决了

于 2013-01-03T22:26:18.833 回答
1

更改以下代码以扫描此文件夹中的所有文件。它适用于我的 JB。

        public void onMediaScannerConnected()
    {
        for(File f : allFiles)
        {
            conn.scanFile(f.getAbsolutePath(), "image/*");
        }
    }
于 2013-06-06T02:49:31.510 回答
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;
    }

}

我希望这有帮助

于 2012-11-03T16:54:36.393 回答
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" 
于 2013-01-04T11:43:21.317 回答