I know that there is a lot of examples on the internet for it but no one of those does what I really want. I want to select multiple images with an intent and get it "url" like this code does with one. (I know that this code cannot select more than one, but I use this as example of what I'm trying to do)
Code:
public static final int RESULT_LOAD_IMG = 0;
public void LoadImg() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
}
ArrayList<Part> files = new ArrayList<>();
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
files.add(new FilePart("uploadedfile[" + String.valueOf(files.size()) + "]", new File(picturePath)));
cursor.close();
}
}
Searching on the internet I found this example from Laith Mihyar in this post: Select multiple images from android gallery
and I want to do the same here, but the file path is different here and dont work for what I'm trying to do.
Code:
int PICK_IMAGE_MULTIPLE = 1
String imageEncoded;
List<String> imagesEncodedList;
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), PICK_IMAGE_MULTIPLE);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
// When an Image is picked
if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == RESULT_OK
&& null != data) {
// Get the Image from data
String[] filePathColumn = { MediaStore.Images.Media.DATA };
imagesEncodedList = new ArrayList<String>();
if(data.getData()!=null){
Uri mImageUri=data.getData();
// Get the cursor
Cursor cursor = getContentResolver().query(mImageUri,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageEncoded = cursor.getString(columnIndex);
cursor.close();
}else {
if (data.getClipData() != null) {
ClipData mClipData = data.getClipData();
ArrayList<Uri> mArrayUri = new ArrayList<Uri>();
for (int i = 0; i < mClipData.getItemCount(); i++) {
ClipData.Item item = mClipData.getItemAt(i);
Uri uri = item.getUri();
mArrayUri.add(uri);
// Get the cursor
Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imageEncoded = cursor.getString(columnIndex);
imagesEncodedList.add(imageEncoded);
cursor.close();
}
Log.v("LOG_TAG", "Selected Images" + mArrayUri.size());
}
}
} else {
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
super.onActivityResult(requestCode, resultCode, data);
}
Thanks
There is no "file path". ACTION_GET_CONTENT does not have to return a file Uri, and most of the time on newer devices it will return a content Uri.
Use ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Use DocumentFile and fromSingleUri() to get at metadata about the content identified by the Uri.
I can't even load it in an ImageView
Picasso and other image-loading libraries (even Ion) work with content Uri values without an issue.
I'm trying to upload those files with the Ion lib, that needs a path
The best solution would be to use a better HTTP client library, one that offers greater flexibility. OkHttp (with Okio) should be able to handle uploading from a Uri.
Or, use ContentResolver and openInputStream() to get an InputStream on the content. Use FileOutputStream to get a stream on some local file (e.g., in getCacheDir()). Use Java I/O to copy the bytes from the InputStream to the FileOutputStream. Then, use the local file with Ion.
Related
I'm trying to get a Bitmap from a video which I get from the device's gallery or the camera, but when I call this, I'm getting a null Bitmap:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri uri = data.getData();
if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK) {
Uri videoUri = data.getData(); // -> content://com.android.providers.media.documents/document/video%3A76
// This returns null
Bitmap thumbnailVideo = ThumbnailUtils.createVideoThumbnail(videoUri.toString(), MediaStore.Video.Thumbnails.MICRO_KIND);
media1.setImageBitmap(thumbnailVideo);
}
I also tried using this, but it stills returns a null value:
String path = uri.getPath(); // -> /document/video:76
Bitmap thumbnailVideo = ThumbnailUtils.createVideoThumbnail(path , MediaStore.Video.Thumbnails.MICRO_KIND);
And the last thing I tried is this code, but as before, it doesn't work:
String[] filePathColumn = {MediaStore.Video.Media.DATA};
Cursor cursor = this.getContentResolver().query(uri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap thumbnailVideo = ThumbnailUtils.createVideoThumbnail(picturePath, MediaStore.Video.Thumbnails.MICRO_KIND);
What am I doing wrong? I tried different solutions from Stackoverflow but none of them seem to work for me.
I found a way to make this work.
try {
Bitmap thumbnailVideo;
if (Build.VERSION.SDK_INT < 19) {
thumbnailVideo = ThumbnailUtils.createVideoThumbnail(getRealPathFromURIForVideoAPI18(videoUri), MediaStore.Video.Thumbnails.MICRO_KIND);
}
else {
thumbnailVideo = ThumbnailUtils.createVideoThumbnail(getRealPathFromURIForVideoAPI19(videoUri), MediaStore.Video.Thumbnails.MICRO_KIND);
}
setThumbnail(thumbnailVideo);
} catch (Exception ex) {
ex.printStackTrace();
}
// API 18 or less (Android 4.3)
#SuppressLint("NewApi")
public String getRealPathFromURIForVideoAPI18(Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
String result = null;
CursorLoader cursorLoader = new CursorLoader(this, contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
cursor.close();
}
return result;
}
// API 19 or higher (>Android 4.4 Kitkat)
#SuppressLint("NewApi")
private String getRealPathFromURIForVideoAPI19(Uri selectedVideoUri) {
String wholeID = DocumentsContract.getDocumentId(selectedVideoUri);
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Video.Media.DATA };
String sel = MediaStore.Video.Media._ID + "=?";
Cursor cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);
String filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}
I try to select multiple images from photo gallery and save it in my custom folder on sdCard.
I wrote some code but i have nullPintException
this is a my source
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), PICK_FROM_GALLERY);
and this is OnActivityResultCode
if(data!=null)
{
ClipData clipData = data.getClipData();
for (int i = 0; i < clipData.getItemCount(); i++)
{
Uri selectedImage = clipData.getItemAt(i).getUri();
if (selectedImage != null) {
mCurrentPhotoPath = getRealPathFromURI(selectedImage);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, options);
// bitmap=getResizedBitmap(bitmap,1280,720);
String partFilename = currentDateFormat();
if (bitmap != null) {
SaveImage(bitmap, partFilename);
}
}
}
public String getRealPathFromURI(Uri uri) {
Cursor cursor = CarRecieveActivity.this.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
private void SaveImage(Bitmap finalBitmap,String fileName) {
File myDir = new File(rootDirectory + "/"+vinNumber.getText().toString());
myDir.mkdirs();
String fname = fileName+".jpg";
File file = new File (myDir, fname);
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
this is my source .i have two errors.
first when i click only one image in my gallery clipData is null and second,when i choose multiple images from gallery and click ok button i have this error
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it
error is in this function getRealPathFromURI()
how i can solve both problems?
thanks
Select images from device
//Uri to store the image uri
private List<Uri> filePath;
public String path[];
public static List<ImageBeen> listOfImage;
//Image request code
private int PICK_IMAGE_REQUEST = 1;
private int PICK_IMAGE_REQUEST_MULTI = 2;
// select multiple image
private void pickImages() {
filePath = new ArrayList<>();
listOfImage = new ArrayList<>();
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST_MULTI);
}else {
intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
}
Activity result
//handling the image chooser activity result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST_MULTI && resultCode == RESULT_OK && data != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ClipData imagesPath = data.getClipData();
if (imagesPath != null) {
path = new String[imagesPath.getItemCount()];
for (int i = 0; i < imagesPath.getItemCount(); i++) {
filePath.add(imagesPath.getItemAt(i).getUri());
path[i] = getPath(imagesPath.getItemAt(i).getUri());
ImageBeen imageBeen = new ImageBeen(imagesPath.getItemAt(i).getUri());
imageBeen.setPath(path[i]);
listOfImage.add(imageBeen);
initViewPager();
}
}else {
path = new String[1];
path[0] = getPath(data.getData());
ImageBeen imageBeen = new ImageBeen(data.getData());
imageBeen.setPath(path[0]);
listOfImage.add(imageBeen);
initViewPager();
}
} else if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null) {
path = new String[1];
path[0] = getPath(data.getData());
ImageBeen imageBeen = new ImageBeen(data.getData());
imageBeen.setPath(path[0]);
listOfImage.add(imageBeen);
initViewPager();
}
}
genarate images path using Image URI
//method to get the file path from uri
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
String path = null;
if(cursor!=null) {
if (cursor.moveToFirst()) {
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
}
return path;
}
This is image bean where stored image URI and Image path
public class ImageBeen {
private Uri fileUri;
private String path;
public ImageBeen(Uri fileUri)
{
this.fileUri=fileUri;
}
public String getPath() {
return path;
}
public void setPath(String path)
{
this.path=path;
}
public Uri getFileUri() {
return fileUri;
}
}
For display image use Picasso
compile 'com.squareup.picasso:picasso:2.5.2'
Picasso.with(context)
.load(imageBeen.getFileUri())
.placeholder(R.drawable.not_vailable)
.error(R.drawable.not_vailable)
.into(holder.image);
I use a Intent to get pictures path and open them into a File. I can open files allocated in "Camera" folder like "/storage/emulated/0/DCIM/Camera/IMG_20160817_232858.jpg", but I cannot open files in locations like "/storage/emulated/0/Pictures/1634894_.png". Using file.exists() it just says that it doesn't.
Need to say that I'm using API 23 and I request READ_EXTERNAL_STORAGE, so this souldn`t be a problem... But I can't access those files even with that.
What can be wrong?
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
File file = new File(picturePath);
if(file.exists()) {
} else {
}
cursor.close();
}
}
Updated: it doesn't happens with all the files from the same folder, just some of them, but they really exist since I can open them from the gallery.
Update2:
I use this Intent.
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
Update3:
Running time permissions:
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
SomeWork();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
}
else {
SomeWork();
}
Permissions in Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
The MediaStore will index images that are not accessible to you from the filesystem. There is no requirement for a DATA column to return a value that you can use.
Instead, stop trying to get a File, and use the Uri itself:
getContentResolver().openInputStream() to get an InputStream on it
DocumentFile.fromSingleUri() to get a DocumentFile for easy access to metadata (e.g., MIME type)
try{
// this works!!!
File csvfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/brcOrdersaved.csv");
final String filename = csvfile.toString();
if (!csvfile.exists()) {
// displayMsg(context, "No Saved Order: ");
return (false);
}
FileReader fr = new FileReader(filename);
BufferedReader reader = new BufferedReader(fr);
String csvLine = "";
final char Separator = ',';
final char Delimiter = '"';
final char LF = '\n';
final char CR = '\r';
boolean quote_open = false;
if (reader.equals(null)) {
displayMsg(context, "NULL");
return (false);//rww 11/13/2021
}
int i = 0;
while (!myendofcsvfile) {
csvLine = reader.readLine();
if (csvLine == null) {
myendofcsvfile = true;
}
// do stuff here
}
fr.close();
fileexists = true;
} catch (Exception e) {
String msg = "Can not Load Saved Order ";
fileexists = false;
return (fileexists);
}
I'm trying to do an application which is sending SMS, and MMS, so I need to retrieve the phone number and eventually an image.
My problem is, if I only the PICK_CONTACT case in onActivityResult, it's working fine, I got my contact phone number.
But if I'm adding the second part, PICK_IMAGE, when I'm clicking on my contact, I got a :
java.lang.IllegalArgumentException: Invalid column _data
But I can still taking images without any problems..
Both intent call
private static final int PICK_CONTACT = 3;
private static final int PICK_IMAGE = 4;
protected void onCreate(Bundle savedInstanceState) {
...
}
public void addImage() {
Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(choosePictureIntent,PICK_IMAGE );
}
public void addContact(){
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
onActivityResult Code
public void onActivityResult(int reqCode, int resultCode, Intent data){
super.onActivityResult(reqCode, resultCode, data);
Uri contactData = data.getData();
switch(reqCode) {
case (PICK_CONTACT):
if (resultCode == Activity.RESULT_OK) {
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (cur.moveToFirst()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
while (pCur.moveToNext()) {
phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
etPhoneNo.setText(phone);
}
pCur.close();
}
}
case (PICK_IMAGE) :
if (resultCode == Activity.RESULT_OK) {
try {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmpFactoryOptions.inSampleSize = 2;
bmpFactoryOptions.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(contactData), null, bmpFactoryOptions);
imageView.setImageBitmap(bmp);
} catch (FileNotFoundException e) {
Log.v("ERROR", e.toString());
}
ContentResolver cr = getContentResolver();
String [] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = cr.query(contactData, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
image_path = cursor.getString(column_index);
}
}
}
How can I resolve that?
I actually solved it ..
I just forgot break; :)
This question already has answers here:
Android contacts Display Name and Phone Number(s) in single database query?
(3 answers)
Closed 8 years ago.
I have started a new intent activity for result
Code:
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI);
startActivityForResult(contactPickerIntent, 1);
And now I want to get the phone and number:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
Uri contactUri = data.getData();
String[] pN = {Phone.NUMBER};
String[] pNa = {Phone.CONTACT_ID};//idk
Cursor cP = getContentResolver().query(contactUri, pN, null, null, null);
cP.moveToFirst();
Cursor cPa = getContentResolver().query(contactUri, pNa, null, null, null);
cPa.moveToFirst();
int numc = cP.getColumnIndex(Phone.NUMBER);
String num = cP.getString(numc);
int namec = cPa.getColumnIndex(Phone.CONTACT_ID);//idk
String name = cPa.getString(namec);//idk
Log.i("", name);
}
if (resultCode == RESULT_CANCELED) {
//DO OTHER STUFF
}
}
}
The phone number is fine BUT I fail to retrieve the contact's GIVEN NAME!
Uri uri = data.getData();
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
cursor.moveToFirst();
number = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
Try this code , it might help with some minor changes...
static final int PICK_CONTACT_=1;
Intent intent_1 = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent_1, PICK_CONTACT_);
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (PICK_CONTACT_) :
if (resultCode == Activity.RESULT_OK) {
Uri contactData = data.getData();
Cursor cursor = managedQuery(contactData, null, null, null, null);
if (cursor.moveToFirst()) {
String id =cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
String hasPhone =cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (hasPhone.equalsIgnoreCase("1")) {
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,
null, null);
phones.moveToFirst();
cNumber = phones.getString(phones.getColumnIndex("data_1"));
System.out.println("number is:"+cNumber);
}
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
}
break;
}
}