I am using below code to scan media after image deletion but it takes too much time. I want to quickly update my images list after image deletion. How to achieve that?
if (Build.VERSION.SDK_INT >= 14) {
Log.e("-->", " >= 14");
MediaScannerConnection.scanFile(this, new String[]{String.valueOf(Environment.getExternalStorageDirectory())}, null, new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
* #see android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri) {
Log.e("ext str gal", "Scanned " + path + ":");
Log.e("ext str gal", "-> uri=" + uri);
}
});
} else {
Log.e("-->", " < 14");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
I got the answer.Use ContentResolver to scan mediaStore.I hope it helps someone.
public void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
try{
final Uri uri = MediaStore.Files.getContentUri("internal");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[] {canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if(!absolutePath.equalsIgnoreCase(canonicalPath)){
contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
}
}
//remove thumbnail of deleted image
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
getContext().sendBroadcast(mediaScanIntent);
}catch (Exception e){
e.printStackTrace();
}
}
Related
The following code seems to be working fine on android 10 and below - but on android 11 video doesn't play and I get the following error
onPlayerError - Source error
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG,"onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_play);
playerView = findViewById(R.id.playerView);
exoPlayer = new SimpleExoPlayer.Builder(this).build();
playerView.setPlayer(exoPlayer);
if (getIntent() != null)
{
String videoPath = getIntent().getExtras().getString(VIDEO_PATH);
Log.d(TAG,"intent not null");
Log.d(TAG,"videoPath = "+videoPath);
Log.d(TAG,"video URI from file= "+Uri.fromFile(new File(videoPath)));
Uri videoURI = FileProvider.getUriForFile(
this, VideoPlayerActivity.this.getPackageName() + ".provider",
new File(videoPath));
Log.d(TAG,"video URI from FileProvider = "+videoURI);
MediaItem mediaItem = MediaItem.fromUri(
Uri.fromFile(new File(videoPath))
);
exoPlayer.setMediaItem(mediaItem);
exoPlayer.prepare();
exoPlayer.play();
exoPlayer.addListener(new Player.Listener() {
#Override
public void onPlayerError(ExoPlaybackException error) {
Log.e(TAG,"onPlayerError - "+error.getMessage());
}
#Override
public void onMetadata(Metadata metadata) {
Log.d(TAG,"onMetadata - "+metadata.toString());
}
});
}
else
{
Log.e(TAG,"something is null");
}
}
I have tried to get the URI of the video using both the approaches and neither works. Is there any way to make it work?
The code that saves the video in previous activity -
String fileName = SR_PreferencesHelper.getString(SR_PreferencesHelper.KEY_FILE_NAME_PREFIX, "recording") + "_" + new SimpleDateFormat(SR_PreferencesHelper.getString(SR_PreferencesHelper.KEY_FILE_NAME_FOMART, Config.itemsFileNameFomart[0].getValue())).format(new Date()) + ".mp4";
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES + File.separator + context.getString(R.string.app_name));
contentValues.put(MediaStore.Video.Media.TITLE, fileName);
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
contentValues.put(MediaStore.Video.Media.IS_PENDING, 1);
Uri mUri = context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues);
Also, this function works fine -
public void openMediaUsingOtherApps(String filePath)
{
try
{
Uri fileUri = FileProvider.getUriForFile(
getContext(), getContext().getPackageName() + ".provider",
new File(filePath));
Intent openVideoIntent = new Intent();
openVideoIntent.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK)
.setDataAndType(
fileUri,
getContext().getContentResolver().getType(fileUri));
getContext().startActivity(openVideoIntent);
}
catch (Exception e)
{
Log.e(TAG,"openMediaUsingOtherApps, msg - "+e.getMessage());
}
}
When I save the video in the folder from the gallery then select this video not display. but I go back previous activity then display video
String[] vidfilePathColumn = {android.provider.MediaStore.Video.Media.DATA};
try {
videoAsset = getContentResolver().openAssetFileDescriptor(selectedImage, "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Cursor videocursor = getContentResolver().query(selectedImage, vidfilePathColumn, null, null, null);
videocursor.moveToFirst();
int columnIndex = videocursor.getColumnIndex(vidfilePathColumn[0]);
String filePath = videocursor.getString(columnIndex);
String vidstrlenght = filePath.substring(filePath.lastIndexOf('/') + 1);
File filevidpath = Environment.getExternalStorageDirectory();
File dir = new File(filevidpath.getAbsolutePath() + "/mantrademo/");
dir.mkdir();
File file = new File(dir, vidstrlenght);
getVideofile(file);
videocursor.close();
Tell the media scanner about the new file so that it is
immediately available to the user.
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
or
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("your file path"))));
Hi I am trying to save image in my gallery but the issue is that, not able to see in my gallery, following is my code can any one help?
public void OnClickSave(View view)
{
Bitmap bitmap =getBitmapFromView(idForSaveView);
try {
ContextWrapper wrapper = new ContextWrapper(context);
File file = wrapper.getDir("MilMilaImages",MODE_PRIVATE);
// Create a file to save the image
file = new File(file, "MilMila"+".jpg");
try{
OutputStream stream = null;
stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);
stream.flush();
stream.close();
}catch (IOException e) // Catch the exception
{
e.printStackTrace();
}
// Parse the gallery image url to uri
final Uri savedImageURI = Uri.parse(file.getAbsolutePath());
// Display the saved image to ImageView
System.out.println("HLL"+savedImageURI);
iv.setImageURI(savedImageURI);
MediaScannerConnection.scanFile(context, new String[] { file.getAbsolutePath()},
null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
} else {
context.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getRootDirectory())));
}
// Display saved image uri to TextView
// Toast.makeText(context,"Saved Successfully",Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
I have used this code and it works for me :
// show the image in the device gallery
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
val contentUri = Uri.fromFile(compressFile) //out is your output file
mediaScanIntent.data = contentUri
this.sendBroadcast(mediaScanIntent)
} else {
sendBroadcast(Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())))
}// // show the image in the device gallery
How to refresh gallery the in android kitkat ?
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
I tried with the above, but its not refreshing in android 4.4. How to refresh the gallery when add/delete the images programatically ?
This works for me :)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File("folderPATH", "fileName");
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
appContext.sendBroadcast(mediaScanIntent);
} else {
appContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/" + "FOLDER_TO_REFRESH")));
}
Hope it helps :)
You can use following technique to update all files present in a single folder:
for (File child : fileFolder.listFiles()) {
if (child.isFile()) {
fName = child.getName();
Log.d("MyTag", "Scanning >> " + child.getName());
MediaScannerConnection
.scanFile( MyActivity.this,
new String[] { "path/of/our/folder" + fName },
null, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(
String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
}
Source: here
Use this code to add/ refresh gallery images.
String version = Build.VERSION.RELEASE;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
String mCurrentPhotoPath = "file://"
+ Environment.getExternalStorageDirectory() + "/AppDirectory"; // image
// is
// the
// created
// file
// image
File file = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
} else {
MediaScannerConnection.scanFile(this, new String[] { Environment
.getExternalStorageDirectory().toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
*
* #see android.media.MediaScannerConnection.
* OnScanCompletedListener
* #onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri) {
Log.i(TAG, "Scanned ................" + path);
}
});
}
I'm currently working on an App that receives multiple images via socket. To save them, I wrote the following methods:
public static boolean saveTempImageToGallery(Context c) {
try {
FileInputStream fis = c.openFileInput(Settings.TEMP_PHOTO_STORAGE);
// create name of file: [date]-[time]-baby
final String tFilename = new SimpleDateFormat("dd-MM-yyyy_hh-mm-ss")
.format(new Date()) + ".png";
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
Log.d(TAG, "External storage available.");
// sd card available
File dir = getExternalStorageDir("Photos");
if (dir.mkdirs() || dir.isDirectory()) {
Log.i(TAG, "Directory: "+dir.getAbsolutePath());
File newImage = new File(dir, tFilename);
if (newImage.createNewFile() && newImage.isFile()) {
Log.i(TAG, "Saving image to "+newImage.getAbsolutePath());
final Bitmap bmp = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// compress image to png
bmp.compress(Bitmap.CompressFormat.PNG, 40, baos);
FileOutputStream fo = new FileOutputStream(newImage);
fo.write(baos.toByteArray());
fo.close();
Log.i(TAG, "Image saved!");
return true;
}
} else {
Log.d(TAG, "Could not create directory.");
}
} else {
Log.d(TAG, "External storage not available.");
}
} catch (Exception e) {
}
return false;
}
public static File getExternalStorageDir() {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/"
+ Settings.EXT_STORAGE_DIRECTORY);
return dir;
}
public static File getExternalStorageDir(String subdir) {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/"
+ Settings.EXT_STORAGE_DIRECTORY + "/" + subdir);
return dir;
}
After saving them, I'd like to offer the user the possibility to view them in the default gallery app. After reading some post, I adapted the following code:
MediaScannerConnectionClient mScanClient = new MediaScannerConnectionClient() {
#Override
public void onScanCompleted(String path, Uri uri) {
try {
Log.d("onScanCompleted", uri + "success");
if (uri != null) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
}
} finally {
if (mScanCon != null)
mScanCon.disconnect();
mScanCon = null;
}
}
#Override
public void onMediaScannerConnected() {
Log.i(TAG, "Media Scan Connected.");
String[] files = Support.getExternalStorageDir("Photos")
.list();
Log.i(TAG,
Support.getExternalStorageDir("Photos").list().length
+ " elements in dir.");
if (files.length > 0) {
for (String cur : files) {
if (cur.equals(".") || cur.equals(".."))
continue;
Log.i(TAG, "Using "
+ cur
+ " to scan stuff. "
+ Support.getExternalStorageDir("Photos")
.getAbsolutePath() + "/" + cur);
Log.i(TAG, "Not using "
+ cur
+ " to scan stuff. "
+ Support.getExternalStorageDir("Photos")
.toString() + "/" + cur);
mScanCon.scanFile(
Support.getExternalStorageDir("Photos")
.getAbsolutePath() + "/" + cur,
"image/*");
break;
}
} else {
Toast.makeText(getApplicationContext(),
"No images available.", Toast.LENGTH_LONG)
.show();
}
}
};
if (mScanCon != null)
mScanCon.disconnect();
mScanCon = new MediaScannerConnection(getApplicationContext(),
mScanClient);
mScanCon.connect();
Weird thing: Seems like onMediaScannerConnected is never fired - anyone has an idea? I've been searching the web and stackoverflow for the last hour..
Thank you.
You really don't have to connect to the media scanner to start a scan, you can use this static method instead.
MediaScannerConnection.scanFile(context, new String[] {dir.getAbsolutePath()}, null, null);
edit:
Uri uri = Uri.parse(filePath);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(uri, "image/*");
startActivity(i);