Unable to play video on exoplayer on android 11 - android

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

Related

Image is not showing in gallery after save

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 reduce scan time of media using media scanner?

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

Unable to display newly added media inside Gallery folder in Android

I am able to successfully record the audio and play it back. The file is being stored in the SD and has a filePath like so: /storage/emulated/0/20160516_104008. The problem is that I want the user to be able to access it via the gallery widget.
I researched this problem and this post recommended using MediaScannerConnection API, which I have implemented as follows:
MediaScannerConnection.scanFile(_reactContext,
new String[] { audioFileName }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
});
Here is the relevant code:
private boolean prepareAudioRecorder() {
audioRecorder = new MediaRecorder();
audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
audioFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
audioFileName += "/" + timeStamp;
audioRecorder.setOutputFile(audioFileName);
audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
audioRecorder.prepare();
return true;
} catch (IOException e) {
Log.e(TAG, "prepare() failed");
return false;
}
}
public void stopAudioRecording(final Promise promise) {
if (audioRecorderPromise != null) {
audioFile = new File(audioFileName);
releaseAudioRecorder();
storeFile();
promise.resolve("finished recording");
} else {
promise.resolve("not recording");
}
private void releaseAudioRecorder() {
if (audioRecorder != null) {
audioRecorder.stop();
audioRecorder.release();
audioRecorder = null;
if (audioRecorderPromise != null) {
// audioRecorderPromise.resolve(Uri.fromFile(audioFile).toString());
audioRecorderPromise.resolve(audioFileName);
audioRecorderPromise = null;
}
}
}
private void storeFile() {
values = new ContentValues();
values.put(MediaStore.Audio.Media.TITLE, audioFileName);
values.put(MediaStore.Audio.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/3gpp");
values.put(MediaStore.Audio.Media.DATA, audioFileName);
ContentResolver cr = _reactContext.getContentResolver();
cr.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Uri newUri = cr.insert(base, values);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(audioFile));
_reactContext.sendBroadcast(intent);
}
You should not provide the file name but the absolute path
Refer Android Developers
Update Better use MediaScannerConnectionClient:
private MediaScannerConnectionClient mediaScannerConnectionClient = new MediaScannerConnectionClient() {
#Override
public void onMediaScannerConnected() {
mediaScannerConnection.scanFile("pathToFile/someName.extension", null);
}
#Override
public void onScanCompleted(String path, Uri uri) {
if(path.equals("pathToFile/someName.extension"))
mediaScannerConnection.disconnect();
}
};
MediaScannerConnection mediaScannerConnection = new MediaScannerConnection(context, mediaScannerConnectionClient).connect();

Video not shown on Gallery

I have saved the video on SD card but its not showing in gallery
I can see the video in the sd card and its playing
I am using this method to get video uri and save it
public static Uri getVideoUri(Context context) {
Marapreferences marapreferences=Marapreferences.getInstance(context);
boolean ismedia=marapreferences.isMedia();
File file = null;
File file2 = new File(Environment.getExternalStorageDirectory()
+ "/mara_messenger/videos");
if (!file2.exists()) {
file2.mkdirs();
}
currentFileName = "" + System.currentTimeMillis() + ".mp4";
imageName = Environment.getExternalStorageDirectory()
+ "/mara_messenger/videos/" + currentFileName;
file = new File(imageName);
Uri imgUri = Uri.fromFile(file);
System.out.println("Image uri" + imgUri);
return imgUri;
}
File file=new File(uri);
MediaScannerConnection.scanFile(this, new String[] {file.getAbsolutePath()},
new String[]{"video/mp4"}, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri)
{
System.out.println("completed");
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uri);
sendBroadcast(intent);
}
});
I can see after scan URI and path but still not showing on gallery

unable to upload video through action_send intent in android 4.3

i am able to upload video through this code till 4.1.2 version of android. but in 4.3 this fails.
calling shareVideo() method android displays a list of apps, but in case of selecting
youtube from list, youtube app opens then stops without any message and in case of selecting instagram, instagram app crashes. i am not able to upload video through any App including facebook also.
Please tell me what is the issue??
Thanks in advance.
public void shareVideo(View view){
new Handler().post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
ContentValues content = new ContentValues(4);
content.put(MediaStore.Video.VideoColumns.DATE_ADDED,
System.currentTimeMillis() / 1000);
content.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
content.put(MediaStore.Video.Media.DATA, filename);
Uri videoURI = getBaseContext().getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, content);
//Uri videoURI = Uri.fromFile(new File(filename));
Intent intent = new Intent(Intent.ACTION_SEND);
//intent.setAction(Intent.ACTION_SEND);
intent.setType("video/mp4");
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoURI);
try {
startActivity(Intent.createChooser(intent,"Upload video via:"));
} catch (android.content.ActivityNotFoundException ex) {
}
}
});
}
After 4.1 android changed the mechanism of sd card path. now i can upload the the video by getting uri through the id of video file.
here is my code
public static String getVideoContentUriFromFilePath(Context ctx, String filePath) {
ContentResolver contentResolver = ctx.getContentResolver();
String videoUriStr = null;
long videoId = -1;
Log.d("first log","Loading file " + filePath);
// This returns us content://media/external/videos/media (or something like that)
// I pass in "external" because that's the MediaStore's name for the external
// storage on my device (the other possibility is "internal")
Uri videosUri = MediaStore.Video.Media.getContentUri("external");
Log.d("second log","videosUri = " + videosUri.toString());
String[] projection = {MediaStore.Video.VideoColumns._ID};
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = contentResolver.query(videosUri, projection, MediaStore.Video.VideoColumns.DATA + " LIKE ?", new String[] { filePath }, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
videoId = cursor.getLong(columnIndex);
Log.d("third log","Video ID is " + videoId);
cursor.close();
if (videoId != -1 ) videoUriStr = videosUri.toString() + "/" + videoId;
return videoUriStr;
}
and on click of your upload button
use this method-
public void shareVideo(View view){
new Handler().post(new Runnable() {
#Override
public void run() {
String newPath=getVideoContentUriFromFilePath(ShareVideoActivity.this, videoPath);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Title");
//intent.setAction(Intent.ACTION_SEND);
intent.setType("video/mp4");
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse(newPath));
try {
startActivity(Intent.createChooser(intent,"Upload video via:"));
} catch (android.content.ActivityNotFoundException ex) {
}
}
}
});
}

Categories

Resources