I tried this code.
public static void openGallery(Context context) {
String bucketId = "";
final String[] projection = new String[] {"DISTINCT " + MediaStore.Images.Media.BUCKET_DISPLAY_NAME + ", " + MediaStore.Images.Media.BUCKET_ID};
final Cursor cur = context.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("Your_dir_name")) {
bucketId = cur.getString((cur.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_ID)));
break;
}
}
Uri mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
if (bucketId.length() > 0) {
mediaUri = mediaUri.buildUpon()
.authority("media")
.appendQueryParameter("bucketId", bucketId)
.build();
}
if(cur != null){
cur.close();
}
Intent intent = new Intent(Intent.ACTION_VIEW, mediaUri);
context.startActivity(intent);
}
But I failed to open the gallery specific folder, but the gallery home screen appears with 'file not supported' Toast.
Is there any way I can solve this problem?
You can't set initial path to specific folder when working with files stored in MediaStore.
However, you can use DocumentsContract.EXTRA_INITIAL_URI when working with DocumentFile, so you can set initial path when user wants to select files from Storage Access Framework (SAF):
Uri initialUri = DocumentFileCompat.createDocumentUri(DocumentFileCompat.PRIMARY, "DCIM")
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
.putExtra(DocumentsContract.EXTRA_INITIAL_URI, initialUri)
DocumentFileCompat.createDocumentUri() helps you constructing the initial URI. You can get DocumentFileCompat from SimpleStorage.
Related
I'm trying to get image from the camera or the gallery (whatever the user chose) in one intent. the problem is that I always get intent.getData() as null in OnActivityResult.
I'm doing the following as suggested here:
Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent });
startActivityForResult(chooserIntent, SELECT_PICTURE);
OnActivityResult:
if (requestCode == SELECT_PICTURE && resultCode == Activity.RESULT_OK) {
if (data != null) {
try {
final Uri imageUri = data.getData();
Log.e("uri", imageUri + "");
uri is null
Well, ACTION_IMAGE_CAPTURE does not return Uri.
But if by any chance you really want to get the Uri after taking a photo by using it, then you need to specify the path for the picture (it will save the photo on that path, so it's not temporary).
This is one of that example (this will create directory & prepare the new file for your image):
// Determine Uri of camera image to save.
File root = new File(
Environment.getExternalStorageDirectory() + File.separator + locationName + File.separator);
root.mkdirs();
String fname = imagePrefixName + System.currentTimeMillis() + ".jpg";
File imageMainDirectory = new File(root, fname);
Uri outputFileUri = Uri.fromFile(imageMainDirectory); //make sure you store this in the place that can be accessed from your onActivityResult
After you decided your outputUri & store it, then you need to implement that uri on your camera intent like this:
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
Then, when you received the data you can do this to check if the picture is come from gallery or camera (picture that stored has Uri on it):
final Uri imageUri = data.getData();
if (imageUri == null)
{
imageUri = outputFileUri;
}
Make sure you implement the permission for write & read external storage & with this, i think you will get Uri that you want.
I am using Exo Player in order to make an audio player for android. So far i am using this code and fetching the following info from my phone. Data, Name, Artist.
public void getMp3Songs() {
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
int songId = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
arrayList.add(new Songs(songId, name, url));
} while (cursor.moveToNext());
}
cursor.close();
}
}
The next thing i need is exact path of these tracks.
For that purpose i am using this code.
private void initializePlayer(){
player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this), new DefaultTrackSelector()
, new DefaultLoadControl());
simpleExoPlayerView.setPlayer(player);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow,playbackPosition);
Uri uri = Uri.parse(url);
MediaSource mediaSource = buildMediaSource(uri);
player.prepare(mediaSource, true, false);
}
private MediaSource buildMediaSource(Uri uri) {
return new ExtractorMediaSource(uri,
new DefaultHttpDataSourceFactory("ua"),
new DefaultExtractorsFactory(), null, null);
}
The problem is that when i start the player, nothing happens. Its just a blank player and its not playing anything. I think i am messing with the file paths here. Please help.
Okay so i found the solution if someone is in need he can use it. The problem was not in getting the address or building the Uri. It was in this particular section. new DefaultHttpDataSourceFactory("ua") Change this to this:
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "idk"), new DefaultBandwidthMeter());
Now use this instance while returning MediaSource.
I have this weird problem that seems to only happen on one of my tablets that runs android 6.
I have this chunk of code to add a photo taken from the camera to a recycler view
1) I create a file object onto device (this is the photo)
2) I get the uri from that file
3) I create an intent passing in that uri as such
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getActivity().getPackageManager()) != null)
// this is done in a fragment, everything else below is in the if statement
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(take_photo_intent, option_int);
I know MediaStore.EXTRA_OUTPUT does NOT return anything to onActivityResult, but instead writes to the uri you pass in.
now inside of onActivityResult I have
Log.i("PHOTO", "path--->" + uri.getPath());
So I want to mention, when the program works or DOESN'T work, the uri ALWAYS has a path, one example of one of the paths is
/storage/emulated/0/data/20161212_175150797715155.jpg
so to continue on in the onActivityResult
5) create bitmap based on uri path to use it later on
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
*************** problem here ****************
Bitmap temp = BitmapFactory.decodeFile(uri.getPath());
the temp bitmap returns null SOME of the time, let me explain
when I take the photo, the asus android 6 tablet shows two buttons when you take the photo, one button to discard the photo, another to keep the photo.. here is the weird part, ON THAT screen, if I wait like 5-15 seconds before pressing the button to keep the photo, the bitmap will NOT be null, but if I take a photo and immediately accept it, the a bitmap is null.
now as said before, does not matter how i do it, if the bitmap comes out null, or it does not come out null, it always has a path before passing it into the bitmapdecode function (which is weird)
I have no clue if it is the camera software, the physical camera hardware, an android 6 bug....
I also want to say, I am not sure if this is the best code but it has worked on 4 other android devices ( phones, tablets) it is just this ONE tablet that is a asus and only one with android 6, it works fine with everything else
EDIT:
I tried this as suggested
Bitmap TEMP = null;
try {
TEMP = BitmapFactory.decodeStream(getContext().getContentResolver().openInputStream(uri));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
with no luck
EDIT 2:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
BitmapFactory.Options bitmap_options = new BitmapFactory.Options();
bitmap_options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap TEMP = BitmapFactory.decodeFile(uri.getPath());
Bitmap bitmap_image = ThumbnailUtils.extractThumbnail(TEMP, THUMBNAIL_SIZE, THUMBNAIL_SIZE);
if (bitmap_image == null)
Log.i("PHOTO", "BITMAP THUMBNAIL NULL");
setAdapterBitmap(bitmap_image, uri.getPath(), 1);
}
}
SOLUTION:
I had this method to create a File object and turn it into a URI Object
private File createFileForImage() throws IOException {
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = DIR_NAME + "_" + file_creation_time;
File storage_dir = new File(String.valueOf(Environment.getExternalStorageDirectory()), DIR_NAME);
if (!storage_dir.exists())
{
if(!storage_dir.mkdir())
{
return null;
}
}
return File.createTempFile(image_file_name, ".jpg", storage_dir);
}
then I used this after it was return
uri = Uri.fromFile(image_file);
but for some reason this was working but it had a slight delay that cause bizarre behavior as stated in the original post
Jan Kaufmann suggestion seem to work, to i made some small modifications
private Uri getOutputMediaUriFromFile()
{
File photo_storage_dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), DIR_NAME);
if (!photo_storage_dir.exists())
{
if (!photo_storage_dir.mkdirs())
{
return null;
}
}
String file_creation_time = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String image_file_name = "ipr" + "_" + file_creation_time;
File photo = new File(photo_storage_dir.getPath() + File.separator + image_file_name + ".jpg");
return Uri.fromFile(photo);
}
It does essentially the same thing, but for some reason this doesn't cause the issue I was having, at least not with my testing.
I am glad this now works but can anyone explain why this worked?
Make sure the image size is not too big. If needed,subsample the original image to save memory
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inSampleSize = 8;
Make sure you have permission for
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Or try constructing your URI into something like this:
Uri uri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE, "myimage"); where getOutputMediaFileUri is :
private File getOutputMediaFile(int type, String imgname) {
// External sdcard location
//public static String DIRECTORY_PICTURES = "Pictures";
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + imgname + ".jpg");
} else {
return null;
}
return mediaFile;
}
Try this dude:
TEMP = MediaStore.Images.Media.getBitmap(context.getContentResolver(), YOUR_URL);
If this is not work, I guess that you didn't create a temp file to save the image.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try{
GEY_FILE;
}catch (Exception ex){
Log.i(TAG, "run: " + ex);
}
}
}, 15000);
How know that subject is well documented and I have read a lot on that issue, but I still have the following problem: when I take a picture with my app and click on "validate" button, nothing occur. The aime of what I am doing: passing to onActivityReult function not only the thumbnail, but the "whole" picture taken by the camera.
Here is the listener as defined for the "take a picture" button:
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "CameraTest");
mediaStorageDir.mkdir(); // make sure you got this folder
Log.i("Report",mediaStorageDir.toString());
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
try
{
//create directories and the file
mediaFile.getParentFile().mkdirs();
mediaFile.createNewFile();
} catch (IOException e) {
Log.e("Report", "create error for file "+mediaFile);
e.printStackTrace();
}
mFileUri = Uri.fromFile(mediaFile);
Log.i("Report","Uri: "+mFileUri);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);// this line causes issue - onActivityResult not called...
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
});
and here is the onActivityResult method... that is never called (and that is not declared in the onClickListener method):
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("Report", "1");
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CAMERA_PIC_REQUEST) {
try {
String[] projection = {
MediaStore.Images.Thumbnails._ID, // The columns we want
MediaStore.Images.Thumbnails.IMAGE_ID,
MediaStore.Images.Thumbnails.KIND,
MediaStore.Images.Thumbnails.DATA };
String selection = MediaStore.Images.Thumbnails.KIND + "=" +
MediaStore.Images.Thumbnails.MINI_KIND;
String sort = MediaStore.Images.Thumbnails._ID + " DESC";
Cursor myCursor = this.managedQuery(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, selection, null, sort);
Log.d("Report", "3");
long imageId = 0l;
long thumbnailImageId = 0l;
String thumbnailPath = "";
try {
myCursor.moveToFirst();
imageId = myCursor
.getLong(myCursor
.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID));
thumbnailImageId = myCursor
.getLong(myCursor
.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID));
thumbnailPath = myCursor
.getString(myCursor
.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
} finally {
myCursor.close();
}
String[] largeFileProjection = {
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA };
String largeFileSort = MediaStore.Images.ImageColumns._ID
+ " DESC";
myCursor = this.managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
largeFileProjection, null, null, largeFileSort);
String largeImagePath = "";
try {
myCursor.moveToFirst();
// This will actually give yo uthe file path location of the
// image.
largeImagePath = myCursor
.getString(myCursor
.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
mImageCaptureUri = Uri.fromFile(new File(
largeImagePath));
} finally {
// myCursor.close();
}
Uri uriLargeImage = Uri.withAppendedPath(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
String.valueOf(imageId));
Uri uriThumbnailImage = Uri.withAppendedPath(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
String.valueOf(thumbnailImageId));
Bitmap thumbnail = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uriThumbnailImage);
Bitmap image = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uriLargeImage);
But, as said in the title, onActivityResult is not called. Could you please find out why? Because I have tried almost everything I have found on that subject but I should have missed something.
Thanks !
check if you have declared the right permissions in the AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
and be sure the file you want to write into exists:
add this below puc_img = new File(photo,"Puc_Img.jpg");
try
{
//create directories and the file
puc_file.getParentFile().mkdirs();
puc_file.createNewFile();
} catch (IOException e) { }
It's not clear from your code but you could be declaring onActivityResult within your onClickListener. If that's true you need to move it.
Take a look at this answer:
OnActivityResult ()
Ok, to solve that issue, I used some "trick" detailed here:
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "CameraTest");
mediaStorageDir.mkdir(); // make sure you got this folder
Log.i("Report",mediaStorageDir.toString());
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
try
{
//create directories and the file
mediaFile.getParentFile().mkdirs();
mediaFile.createNewFile();
} catch (IOException e) {
Log.e("Report", "create error for file "+mediaFile);
e.printStackTrace();
}
tmpFilePath = mediaFile.getPath();
mFileUri = Uri.fromFile(mediaFile);
Log.i("Report","Uri: "+mFileUri);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
});
So then, I am recovering the file stored in the tmpFilePath, by using that method in the onActivityResult function:
Bitmap image = BitmapFactory.decodeFile(this.tmpFilePath);
And... It's working fine. I still have some issues when sending the file to the WS but that very question have been solved by that piece of code. Thanks for the help, you put me on the track :)
Is it possible to get the video thumbnail PATH, not Bitmap object itself? I'm aware of method
MediaStore.Images.Thumbnails.queryMiniThumbnail
but since I use my own Bitmap caching mechanism I want to have the path to video thumbnail rather than the Bitmap object itself. This method returns Bitmap object, not path.
Thanks
First get the video file URL and then use below query.
Sample Code:
private static final String[] VIDEOTHUMBNAIL_TABLE = new String[] {
Video.Media._ID, // 0
Video.Media.DATA, // 1 from android.provider.MediaStore.Video
};
Uri videoUri = MediaStore.Video.Thumbnails.getContentUri("external");
cursor c = cr.query(videoUri, VIDEOTHUMBNAIL_TABLE, where,
new String[] {filepath}, null);
if ((c != null) && c.moveToFirst()) {
VideoThumbnailPath = c.getString(1);
}
VideoThumbnailPath, should have video thumbnail path. Hope it help's.
Get Video thumbnail path from video_id:
public static String getVideoThumbnail(Context context, int videoID) {
try {
String[] projection = {
MediaStore.Video.Thumbnails.DATA,
};
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(
MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI,
projection,
MediaStore.Video.Thumbnails.VIDEO_ID + "=?",
new String[] { String.valueOf(videoID) },
null);
cursor.moveToFirst();
return cursor.getString(0);
} catch (Exception e) {
}
return null;
}