我试图从我的应用程序中打开画廊内置应用程序中的图像/图片。
我有一个图片的URI(图片位于SD卡上)。
你有什么建议吗?
我试图从我的应用程序中打开画廊内置应用程序中的图像/图片。
我有一个图片的URI(图片位于SD卡上)。
你有什么建议吗?
当前回答
要显示图像和视频,请尝试以下方法:
Intent intent = new Intent();
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 1);
startActivityForResult(Intent.createChooser(intent,"Wybierz plik"), SELECT_FILE);
其他回答
这是一个完整的解决方案。我刚刚用@mad在下面的答案中提供的信息更新了这个示例代码。还可以查看下面来自@Khobaib的解决方案,解释如何处理picasa图像。
更新
我刚刚回顾了我最初的答案,并创建了一个简单的Android Studio项目,您可以从github签出并直接导入到您的系统。
https://github.com/hanscappelle/SO-2169649
(注意多个文件选择仍然需要工作)
单张图片选择
感谢用户mad,支持来自文件探索者的图像。
public class BrowsePictureActivity extends Activity {
// this is the action code we use in our intent,
// this way we know we're looking at the response from our own action
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.Button01)
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
}
}
}
/**
* helper to retrieve the path of an image URI
*/
public String getPath(Uri uri) {
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
cursor.close();
return path;
}
// this is our fallback here
return uri.getPath();
}
}
选择多张图片
因为有人在评论中要求这些信息,所以最好收集信息。
在intent上设置一个额外的参数EXTRA_ALLOW_MULTIPLE:
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
在Result处理中检查该参数:
if (Intent.ACTION_SEND_MULTIPLE.equals(data.getAction()))
&& Intent.hasExtra(Intent.EXTRA_STREAM)) {
// retrieve a collection of selected images
ArrayList<Parcelable> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
// iterate over these images
if( list != null ) {
for (Parcelable parcel : list) {
Uri uri = (Uri) parcel;
// TODO handle the images one by one here
}
}
}
注意,只有API级别18+支持这一点。
以下是hcpl发布的优良代码的更新。但这适用于OI文件管理器,astro文件管理器和媒体库(测试)。所以我想它将适用于每个文件管理器(除了上面提到的这些,还有很多其他的吗?)修改了他写的代码。
public class BrowsePicture extends Activity {
//YOU CAN EDIT THIS TO WHATEVER YOU WANT
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
//ADDED
private String filemanagerstring;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button) findViewById(R.id.Button01))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
//UPDATED
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
//OI FILE Manager
filemanagerstring = selectedImageUri.getPath();
//MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
//DEBUG PURPOSE - you can delete this if you want
if(selectedImagePath!=null)
System.out.println(selectedImagePath);
else System.out.println("selectedImagePath is null");
if(filemanagerstring!=null)
System.out.println(filemanagerstring);
else System.out.println("filemanagerstring is null");
//NOW WE HAVE OUR WANTED STRING
if(selectedImagePath!=null)
System.out.println("selectedImagePath is the right one for you!");
else
System.out.println("filemanagerstring is the right one for you!");
}
}
}
//UPDATED!
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if(cursor!=null)
{
//HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
//THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
else return null;
}
除了前面的答案,如果你在获得正确的路径(如AndroZip)有问题,你可以使用这个:
public String getPath(Uri uri ,ContentResolver contentResolver) {
String[] projection = { MediaStore.MediaColumns.DATA};
Cursor cursor;
try{
cursor = contentResolver.query(uri, projection, null, null, null);
} catch (SecurityException e){
String path = uri.getPath();
String result = tryToGetStoragePath(path);
return result;
}
if(cursor != null) {
//HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
//THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
String filePath = cursor.getString(columnIndex);
cursor.close();
return filePath;
}
else
return uri.getPath(); // FOR OI/ASTRO/Dropbox etc
}
private String tryToGetStoragePath(String path) {
int actualPathStart = path.indexOf("//storage");
String result = path;
if(actualPathStart!= -1 && actualPathStart< path.length())
result = path.substring(actualPathStart+1 , path.length());
return result;
}
这是我的例子,可能不完全是你的情况。
假设你从你的API提供者获得base64格式,给它一个文件名和文件扩展名,将它保存到文件系统中的某个位置。
public static void shownInBuiltInGallery(final Context ctx, String strBase64Image, final String strFileName, final String strFileExtension){
new AsyncTask<String, String, File>() {
@Override
protected File doInBackground(String... strBase64Image) {
Bitmap bmpImage = convertBase64StringToBitmap(strBase64Image[0], Base64.NO_WRAP);
if(bmpImage == null) {
cancel(true);
return null;
}
byte[] byImage = null;
if(strFileExtension.compareToIgnoreCase(FILE_EXTENSION_JPG) == 0) {
byImage = convertToJpgByte(bmpImage); // convert bitmap to binary for latter use
} else if(strFileExtension.compareToIgnoreCase(FILE_EXTENSION_PNG) == 0){
byImage = convertToPngByte(bmpImage); // convert bitmap to binary for latter use
} else if(strFileExtension.compareToIgnoreCase(FILE_EXTENSION_BMP) == 0){
byImage = convertToBmpByte(bmpImage); // convert bitmap to binary for latter use
} else {
cancel(true);
return null;
}
if(byImage == null) {
cancel(true);
return null;
}
File imageFolder = ctx.getExternalCacheDir();
if(imageFolder.exists() == false){
if(imageFolder.mkdirs() == false){
cancel(true);
return null;
}
}
File imageFile = null;
try {
imageFile = File.createTempFile(strFileName, strFileExtension, imageFolder);
} catch (IOException e){
e.printStackTrace();
}
if(imageFile == null){
cancel(true);
return null;
}
if (imageFile.exists() == true) {
if(imageFile.delete() == false){
cancel(true);
return null;
}
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imageFile.getPath());
fos.write(byImage);
fos.flush();
fos.close();
} catch (java.io.IOException e) {
e.printStackTrace();
} finally {
fos = null;
}
return imageFile;
}
@Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
String strAuthority = ctx.getPackageName() + ".provider";
Uri uriImage = FileProvider.getUriForFile(ctx, strAuthority, file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uriImage, "image/*");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ctx.startActivity(intent);
}
}.execute(strBase64Image);}
不要忘记在AndroidManifest.xml中首先设置一个适当的文件提供程序
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
文件路径是XML在…/res/ XML /file_path.xml
<?xml version="1.0" encoding="utf-8"?>
<external-files-path name="external_files" path="Accessory"/>
<external-path name="ex_Download" path="Download/" />
<external-path name="ex_Pictures" path="Pictures/" />
<external-files-path name="my_Download" path="Download/" />
<external-files-path name="my_Pictures" path="Pictures/" />
<external-cache-path name="my_cache" path="." />
<files-path name="private_Download" path="Download/" />
<files-path name="private_Pictures" path="Pictures/" />
<cache-path name="private_cache" path="." />
长话短说,首先准备好文件提供程序,将已知且可访问的图片源的Uri传递给Intent,否则,将图片保存在所需的位置,然后将位置(作为Uri)传递给Intent。
检索特定类型的文件
这个示例将获得图像的副本。
static final int REQUEST_IMAGE_GET = 1;
public void selectImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_GET);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
Bitmap thumbnail = data.getParcelable("data");
Uri fullPhotoUri = data.getData();
// Do work with photo saved at fullPhotoUri
...
}
}
打开特定类型的文件
在4.4或更高版本上运行时,您请求打开由另一个应用程序管理的文件
static final int REQUEST_IMAGE_OPEN = 1;
public void selectImage() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
Uri fullPhotoUri = data.getData();
// Do work with full size photo saved at fullPhotoUri
...
}
}
原始来源