8

我正在使用以下代码在我的应用程序内打开一个画廊

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, FIND_RESULT);

是否可以将图像列表限制为仅显示相机拍摄的图像?在我的 2.1 系统上查看图库时,图像被分组,因此必须有一个参数来定义它属于哪个文件夹。

检查MediaStore.Images.ImageColumns我没有找到任何可以定义此类内容的列。

我会错吗?因为如果我可以创建一个查询来按文件夹过滤并创建我自己的画廊视图,那么我的问题就会得到解决。

4

5 回答 5

8

您只需要在您的活动中实现 MediaScannerConnectionClient ,然后您必须在此处提供该文件夹名称中的文件之一的确切路径作为 SCAN_PATH ,它将扫描该文件夹中包含的所有文件并在内置画廊中打开它。所以只要给你文件夹的名字,你就会得到里面的所有文件,包括视频。如果您只想打开图像更改FILE_TYPE="image/*"

public class SlideShow extends Activity implements MediaScannerConnectionClient {

        public String[] allFiles;
        private String SCAN_PATH ;
        private static final String FILE_TYPE = "*/*";
        private MediaScannerConnection conn;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);

            setContentView(R.layout.main);

            File folder = new File("/sdcard/yourfoldername/");
            allFiles = folder.list();

            SCAN_PATH=Environment.getExternalStorageDirectory().toString()+"/yourfoldername/"+allFiles[0];

            Button scanBtn = (Button) findViewById(R.id.scanBtn);
            scanBtn.setOnClickListener(new OnClickListener()
            {
                public void onClick(View v)
                {
                    startScan();
                }
            });
        }

        private void startScan()
        {
            if(conn!=null)
            {
                conn.disconnect();
            }

            conn = new MediaScannerConnection(this, this);
            conn.connect();
        }


        public void onMediaScannerConnected()
        {
            conn.scanFile(SCAN_PATH, FILE_TYPE);    
        }


        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;
            }
        }
    }
于 2011-11-24T10:42:58.600 回答
4

以上答案均不正确,包括标记为正确的答案。

这是实际正确的解决方案:

秘诀是找到您的文件夹所代表的存储桶/专辑。成功完成 MediaScan 后会显示存储桶,因此请确保首先扫描您想要显示的任何图像/视频,如上面多次演示的那样。

假设我在 /sdcard/myapp/ myappsmediafolder中有一个索引文件夹:

String bucketId = "";

final String[] projection = new String[] {"DISTINCT " + MediaStore.Images.Media.BUCKET_DISPLAY_NAME + ", " + MediaStore.Images.Media.BUCKET_ID};
final Cursor cur = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);

while (cur != null && cur.moveToNext()) {
    final String bucketName = cur.getString((cur.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME)));
    if (bucketName.equals("myappsmediafolder")) {
        bucketId = cur.getString((cur.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_ID)));
        break;
    }
}

现在我们有了相册的 bucketId,我们可以用一个简单的意图打开它。

过滤视频文件:

Uri mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

过滤图像文件:

Uri mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

...

if (bucketId.length() > 0) {
    mediaUri = mediaUri.buildUpon()
            .authority("media")
            .appendQueryParameter("bucketId", bucketId)
            .build();
}

Intent intent = new Intent(Intent.ACTION_VIEW, mediaUri);
startActivity(intent);

我可以使用内置的 Gallery 应用程序验证这是否有效。里程可能因 Google 相册等其他应用程序而异。

我还没有弄清楚如何不过滤图像/视频,即使在图库中您可以选择没有过滤器的特定专辑。

我通过查看画廊应用程序的 AOSP 源来弄清楚这一点。

于 2016-02-14T19:54:49.693 回答
1

我没有足够的声誉来支持或评论他的回答,但 ShellDude 的回答允许您将目录 URI 放入画廊意图中。因此,当打开图库应用程序时,它会显示所有图像而不是 1。

对我来说,像上面的答案那样扫描我的文件是行不通的。仅在使用 ContentResolver 将新行插入 MediaStore.Images.Media.DATA 表后,查询 MediaStore.Images.Media.EXTERNAL_CONTENT_URI 才有效:

ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, image.getPath());  
values.put(MediaStore.Images.Media.MIME_TYPE,"image/jpeg");
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
于 2016-06-21T00:25:59.747 回答
0

这是一个简化的

private  MediaScannerConnection conn;
private void notifySystemWithImage(final File imageFile) {

        conn = new MediaScannerConnection(this, new MediaScannerConnectionClient() {

        @Override
        public void onScanCompleted(String path, Uri uri) {

            try {
                if (uri != null) {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(uri, "image/*");
                    startActivity(intent);
                }
            } finally {
                conn.disconnect();
                conn = null;
            }
        }

        @Override
        public void onMediaScannerConnected() {
            conn.scanFile(imageFile.getAbsolutePath(), "*/*"); 

        }
    });

        conn.connect();
}
于 2013-10-27T23:11:57.163 回答
0

对于那些仍然给活动未找到异常的人:

您需要指定内部应用程序文件夹的目录。如果图像和所有内容,则不是用户默认根。

public class SlideShow extends Activity implements MediaScannerConnectionClient {

        public String[] allFiles;
        private String SCAN_PATH ;
        private static final String FILE_TYPE = "*/*";
        private MediaScannerConnection conn;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);

            setContentView(R.layout.main);

            File folder = new File(HistoryActivity.this.getExternalFilesDir(null)+"/a/");
            allFiles = folder.list();

            SCAN_PATH= HistoryActivity.this.getExternalFilesDir(null)+"/a/"+allFiles[0];

            Button scanBtn = (Button) findViewById(R.id.scanBtn);
            scanBtn.setOnClickListener(new OnClickListener()
            {
                public void onClick(View v)
                {
                    startScan();
                }
            });
        }

        private void startScan()
        {
            if(conn!=null)
            {
                conn.disconnect();
            }

            conn = new MediaScannerConnection(this, this);
            conn.connect();
        }


        public void onMediaScannerConnected()
        {
            conn.scanFile(SCAN_PATH, FILE_TYPE);    
        }


        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;
            }
        }
    }

有效...但 kitkat 只显示一张照片。我设法使用(更新图库,存储图像时)修复了早期版本:

public void savePhoto(Bitmap bmp)
{
    File imageFileFolder = new File(context.getExternalFilesDir(null)+"/a/") ;
    imageFileFolder.mkdir();
    FileOutputStream out = null;
    Calendar c = Calendar.getInstance();
    String date = fromInt(c.get(Calendar.MONTH))
            + fromInt(c.get(Calendar.DAY_OF_MONTH))
            + fromInt(c.get(Calendar.YEAR))
            + fromInt(c.get(Calendar.HOUR_OF_DAY))
            + fromInt(c.get(Calendar.MINUTE))
            + fromInt(c.get(Calendar.SECOND));
    File imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
    try
    {
        out = new FileOutputStream(imageFileName);
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
        out.flush();
        out.close();
        scanPhoto(imageFileName.toString());
        out = null;
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}


public String fromInt(int val)
{
    return String.valueOf(val);
}


public void scanPhoto(final String imageFileName)
{
    msConn = new MediaScannerConnection(context,new MediaScannerConnection.MediaScannerConnectionClient()
    {
        public void onMediaScannerConnected()
        {
            msConn.scanFile(imageFileName, null);
            Log.i("msClient obj  in Photo Utility", "connection established");
        }
        public void onScanCompleted(String path, Uri uri)
        {
            msConn.disconnect();
            Log.i("msClient obj in Photo Utility","scan completed");
        }
    });
    msConn.connect();
}
于 2014-10-02T11:47:38.577 回答