Can you open multiple files with intent in Android? - java

I'm trying to write an app in Android Studio that opens multiple music files and stores their paths. At the moment all I'm doing is loading one file at a time which works without issue. For example - the code below shows my onclicklister for the load button and associated code. Some of the code has been simplified for this example. A user clicks the load button in the app and then uses whatever file manager they have installed to select a file which then passes the Uri back to my app. All well and good. However, is it possible to select multiple files and have them passed back to my app as an array of files? So instead of selecting a single audio file maybe the user selects 5 or 6.
If so how do you do this? Many thanks.
Anyway - what I
final View.OnClickListener mGlobal_OnClickListener = new View.OnClickListener() {
public void onClick(final View v) {
int resID2 = v.getId();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("audio/*");
try {
startActivityForResult(intent,resID2); }
catch (Exception e) {
Toast.makeText(getApplicationContext(), "Please install a file manager",Toast.LENGTH_LONG).show();
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent result) {
if (resultCode == RESULT_OK)
{
Uri data = result.getData();
String thePath = data.getPath();
// Do something with the file path
}
}

You will have to put an extra value to your intent inorder to create a chooser to pick multiple files.
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("audio/*");
chooseFile.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(chooseFile, "Choose a file") , 2);
Note: Above method will work only of API level 18 and above. To support API level < 18 in your app, use some library project like Android Multiple File Selector Dialog.

Related

Android auto take picture

I am working on app that is suppose to take a selfie every 20 minutes without the user interface or user pressing something. I start this job using a JobScheduler and I create a notification that tells the user that my app is working. I've managed to take a slefie but it needs user's action and preview and I do not want this. I just simply want to take a selfie without the preview or user pressing a button.
private void pic()
{
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera,7);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
Log.d("bine","true");
if (requestCode == 7)
{
Log.d("bine","true");
Bitmap photo = (Bitmap) data.getExtras().get("data");
img.setImageBitmap(photo);
}
}
P.S: I am working with android 9!

Android Intent, Action Create Document, Opens the file explorer multiple times creating duplicate 0b files

I am developing an app for filling pdf forms, I am saving the pdf to the internal storage and then sharing it using the intent ACTION_CREATE_DOCUMENT. This intent returns a URI which i then copy my local pdf into.
All this works fine however the intent opens a file explorer popup so that the user can choose where to save the pdf, and here in lies the problem, when the user presses SAVE; the app creates a 0b file in that location (as it should), but then it reopens the file explorer prompting the user to SAVE again, this happens two or three times and then it finally close for real at which point the pdf data overwrites the latest of the now numerous 0b files.
public int WRITE_REQUEST_CODE=45;
...
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void buttonExport(View view) {
Toast.makeText(this, "Exporting - This will take around 1min", Toast.LENGTH_LONG).show();
// Template of PDF with acrofields (template.pdf).
// TRY to open the pdf stored in the raw res directory
// then convert it to a file object by copying it
try {
//
InputStream inputStream =null;
if (template.equals("crfminortemplate")){
inputStream = getResources().openRawResource(R.raw.crfminorpdftemplat);
}
else if (template.equals("crfmajortemplate")){
inputStream = getResources().openRawResource(R.raw.crfmajorpdftemplat);
}
File tempFile = new File(getFilesDir(),template);
//
copyFile(inputStream, new FileOutputStream(tempFile));
// Now Questions res is tempFile ..
} catch (IOException e) {
throw new RuntimeException("Can't create temp file ", e);
}
try {
PDFManipulation.fillPDF(view, template, fileName, Answers);
} catch (IOException e) {
e.printStackTrace();
}
catch (NullPointerException e)
{
e.printStackTrace();
}
Toast.makeText(this, "Export Complete - save to drive or email", Toast.LENGTH_LONG).show();
sharePDF(getFilesDir()+"/"+fileName+".pdf");
}
private void sharePDF(String PDFPPath) {
Uri path = FileProvider.getUriForFile(this, "com.example.cst_app_v3", new File(getFilesDir(),fileName+".pdf"));
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, "Sent from CST App Android " + PDFPPath);
shareIntent.putExtra(Intent.EXTRA_STREAM, path);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("application/pdf");
startActivityForResult(shareIntent,0);
Intent saveIntent = new Intent();
saveIntent.setAction(Intent.ACTION_CREATE_DOCUMENT);
saveIntent.putExtra(Intent.EXTRA_TITLE,fileName+".pdf");
saveIntent.addCategory(Intent.CATEGORY_OPENABLE);
saveIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
saveIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
saveIntent.setType("application/pdf");
startActivityForResult(saveIntent,WRITE_REQUEST_CODE);
Intent chooserIntent = Intent.createChooser(shareIntent, "Share or Save ...");
Intent[]arrayofintent = {saveIntent};
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,arrayofintent);
startActivityForResult(chooserIntent,0);
startActivity(chooserIntent);
Log.d("Alert",path.getAuthority()+" "+ path.getPath());
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if (resultCode == RESULT_OK && requestCode == WRITE_REQUEST_CODE) {
//DO THE COPY PASTE FROM LOCAL to THE URI data
}
}
Again
I want the user to start the save intent and have the file selector popup once let the user name the file and choose the save location, press save and then return to my the my app where the pdf is copied to the location they specified
if anyone knows/has experienced this issue or thinks they know what might be happening it would be great to hear from you.
Every time you call startActivityForResult or startActivity it will start a new Activity.
So I count 4 of these in your example code but with only 2 calls that will actually return a result that would cause a file to be written.
To fix this just remove all the startActivityForResult or startActivity EXCEPT for the third one which you change to startActivityForResult(chooserIntent,WRITE_REQUEST_CODE);
This works (was tested) BUT provides a very bad UI experience as you have to know to select the Files App to save the document.
It would be much better to split these to different types of action in to separate menu items, Buttons, Floating Action Buttons, or however you getting the user to "Share or Save" as you can provide a better UI than the Intent chooser.

Android app dev: trying to save an image to store into SQLite

I am creating an Android app for class that will take you to the camera app if you click the "capture" button on my user interface. It then returns you to the app and displays the images thumbnail and if you click the "save" button, it will save the button in a SQLite database that I haven't created yet.
My problem is trying to figure out how to access the actual picture and its data, not information about the thumbnail.
The tutorial I was reading has information for storing the image in Android's built in Android's directories, but I can not figure out how to access the actual fullsize image data to store into the database I will be creating myself.
This is the link to the tutorial:
https://developer.android.com/training/camera/photobasics#java
This is not the complete code, just a snipet and it was created in Android Studio:
'''
ImageView pic;
public void capture(View view) {
dispatchTakePictureIntent();
}
public void save(View view) {
}
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
pic.setImageBitmap(imageBitmap); // sets the imageview on the UI as the thumbnail
}
}
'''
I believe that you need to pass a URI of a storage location (file), via the takePictureIntent intent using
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, your_image_Uri);
You can then open the file and retrieve it into a byte[] and store it as a blob. The SQLiteDatase convenience, insert method makes this very easy.
e.g. assuming the byte[] is name my_picture then
ContentValues cv = new ContentValues();
cv.put(column_name_for_picture,my_picture);
long id = insert("the_table_name",null,cv);
You retrieve the stored picture from the db using the SQLiteDatabase query method and then extract the byte[] using the Cursor's getBlob method.
However
If the picture, is 2MB or larger, you will not be able to retrieve it as there is a limitation of 2MB for a CursorWindow (1MB for older versions of Android). I'd suggest that even at 1MB you may well have issues retrieving the image(s).
The recommended way is to not store the image in the database, but to store the path of a file where the image is stored in the database.
You may wish to have a look at How to use images in Android SQLite that are larger than the limitations of a CursorWindow? as this shows a work-around albeit NOT recommended.

How to skip or avoid 'retake and review' option after capturing photo from camera using ACTION_IMAGE_CAPTURE

I want to display the image when I click on the photo and want to set in my ImageView without user select yes or not....
I had searched for it and I also know it very well that the camera app itself gives you the ability to review/retake the image, and once an image is accepted, the activity displays it. But, I want to do it without review/retake the activity display it.....
I am trying this code fine
Initialise
Uri mImageCaptureUri;
For Click on Button
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
File file = new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mImageCaptureUri = Uri.fromFile(file);
try {
intent.putExtra(MediaStore.AUTHORITY, true);
intent.putExtra("return-data", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap bitmap = null;
mPath = mImageCaptureUri.getPath();
System.out.println("THE PAtH:_" + mPath);
BitmapFactory.Options o2 = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(mPath, o2);
ivSelfie.setImageBitmap(bitmap);
}
When I am Click the Photo Than I am Take this screen to select yes or not......
But My requirement is not select review/retake task and direct set to ImageView on activity display when just click and set.....
Actually it's quite useful to have confirmation of taken picture. But, in case if you really don't want to have it, you have to use SurfaceView inside your app and show camera stream here. There is tones of example how to do it, for example consider to check that one.
Use method setImageURI() it will get the bitmap from the uri and set it for you.
Yes it will set the image weather the user press ok or cancel no matter because your file exists on your given path while launching intent.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_FROM_CAMERA) {
// only one line code
ivSelfie.setImageURI(mImageCaptureUri);
}
}
You cannot avoid that screen. The reason is that when you use new MediaStore.ACTION_IMAGE_CAPTURE you are using a different camera application for clicking image. Showing this screen might be the default functionality of the. This screen will be different in different devices depending upon the camera application.
So to get rid of this the only thing you can do is to implement your custom camera instead of using default camera application.
As per default camera app you can't breach that functionality. Instead of, you can use SurfaceView to capture image inside you application. Please have a look at this answer thread.
May be this link will help you.
Thank you
Use "android.intent.extra.quickCapture" for your picture intent.
// File ImagePickerModule.java#248
cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra("android.intent.extra.quickCapture",true);
See https://github.com/react-native-community/react-native-image-picker/issues/647 for details.

file chooser for android

I am making an android album app where I can create an album and add photos and delete photos from the album. Adding a photo is a bit tricky where I need a photo filename with a file path. This was very easy using JFileChooser in java but this is android and I have no clue on getting the filename and file path. Is there any thing in the android api where I can get the same functionality as the JFileChooser.
I am looking for a solution to this problem either using a file chooser of some sort or an entire to new approach. Any help is appreciated..
Or is there any other approach I can implement to add a photo...
You may use Intent.ACTION_PICK to invoke an image picker. This intent may be caught by the default gallery app, or some other app installed on the device.
private static final int REQUEST_PICKER = 1;
private void invokePicker() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Complete action using"), REQUEST_PICKER);
}
Then receive the result on onActivityResult.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)
return;
if (requestCode == PICK_FROM_FILE) {
// Get Uri of the file selected,
Uri theImageUri = data.getData();
// Or if you want a Bitmap,
Bitmap theBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), theImageUri);
}
}
Edited:
Though in this way you don't need a real file path, you can get it from MediaStore if you need.

Categories