I'm updating an app to targetSdkVersion 32 from what was originally targetSdkVersion 29. We never got it to the Play Store before November, so I need to update it to >30.
Part of the app is a fairly simple use case - the user can choose to take a picture or record a video and then upload it to our server. I was able to make some adjustments on externalstorage directory and get taking photos working. Video is proving to have more problems.
My dispatch intent is pretty simple:
else if (options[item].equals("Take video"))
{
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
//intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file
//intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set video quality
// name
// start the video capture Intent
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
}
I had to comment out the intent.putExtra lines to get the stock camera app to work properly.
The onActivityResult is also pretty simple. I'm trying to use a MediaMetadataRetriever to validate the length of the video before doing further processing
case CAMERA_CAPTURE_VIDEO_REQUEST_CODE:
if(resultCode == RESULT_OK) {
try {
if (data.getData() != null && !data.getData().equals("null")) {
Uri videoUri = data.getData();
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(getActivity(), videoUri); //EXCEPTION HERE
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long timeInMilliSec = Long.parseLong(time);
long duration = timeInMilliSec / 1000;
long hours = duration / 3600;
long minutes = (duration - hours * 3600) / 60;
long seconds = duration - (hours * 3600 + minutes * 60);
// less than one minute long videos get sent, otherwise show issue builder
if (minutes < 1) {
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
File dir = new File(filepath.getAbsolutePath() + "/" + "PROCESSEDVIDEOS" + "/");
new VideoCompressAsyncTask(getActivity().getApplicationContext()).execute("false", videoUri.toString(), dir.getPath());
} else {
final CharSequence[] options = {"Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("You can only send videos less than 60 seconds.");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
break;
The app is throwing an illegalStateException on the retriever.setDataSource(getActivity(), videoUri); line with
java.lang.IllegalStateException: Only owner is able to interact with pending item content://media/external_primary/video/media/25
I'm presuming there is some asynchronous action going on here, but I can't find any docs on the proper way to know the recorded video is fully available.
Going be simple android docs here: https://developer.android.com/training/camera/videobasics#TaskCaptureIntent