setDataSource() IO exception - java

I'm having a certain problem when playing an mp3 file specified by the user with MediaPlayer.
try {
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(getApplicationContext(), audio);
mPlayer.prepare();
mPlayer.start(); }
catch (IOException e) {
numberText.setText("IO EXCEPTION");
e.printStackTrace();
}
the problem is in mPlayer.setDataSource(getApplicationContext(), audio)
Here I get the specified mp3 from the user
setAudio.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,1);
}
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
audioPath = intent.getData().getPath();
audio = Uri.parse(audioPath);
}
}
}
});
The error log shows this
setDataSource: SecurityException! uri=content://com.android.providers.downloads.documents/document/1545
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.downloads.DownloadStorageProvider from ProcessRecord{7b8354b 23595:com.example.m1tr0s0ul4s.thatawkwardcall/u0a137} (pid=23595, uid=10137) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3372)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:4819)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2527)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1486)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1092)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:932)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:859)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:987)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:961)
at com.example.m1tr0s0ul4s.thatawkwardcall.AcceptCall.onCreate(AcceptCall.java:55)
at android.app.Activity.performCreate(Activity.java:5966)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2408)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2517)
at android.app.ActivityThread.access$800(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:189)
at android.app.ActivityThread.main(ActivityThread.java:5529)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:956)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:751)
10-20 17:31:13.041 23595-23595/com.example.m1tr0s0ul4s.thatawkwardcall
E/MediaPlayer: Unable to create media player
I have literally no idea what is going on :/ please help

In case you are already requesting for Runtime Permissions try this code:
if (Build.VERSION.SDK_INT < 19) {
intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, 1);
} else {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, 1);
}
If you're not then you must check for Runtime Permissions in Marshmallow and above.
Add this code to your Manifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Now in your onClick of setAudio you need to check if the user has given you permissions to access the storage of the device
setAudio.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 11);
} else {
//You already have the permission, just go ahead.
if (Build.VERSION.SDK_INT < 19) {
intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, 1);
} else {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, 1);
}
}
}
When you request permission the user action is returned in onRequestPermissionResult(..). Here's how you could handle the user action.
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 11) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//The External Storage READ Permission is granted to you... Continue your left job...
if (Build.VERSION.SDK_INT < 19) {
intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, 1);
} else {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, 1);
}
} else{
//permission denied
}
}

audioPath = intent.getData().getPath();
audio = Uri.parse(audioPath);
intent.getData() already returns an Uri object, so you're potentially throwing away data required to read the specific file like the scheme, host or query properties.

Related

How to check if app has ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION and other storage permissions on lower Androids

Is there a way to check if my device already has the following permissions with one line or how should I check this?
I am supporting SDK versions from 21 to 30 so I cannot use :
if (!Environment.isExternalStorageManager()) {
Because it requires API level 30, but my min is 21.
This is how I am asking for permissions:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
Uri uri = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
startActivityForResult(intent, 2296);
} catch (Exception ex){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivity(intent);
}
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
}
So is there a permission check that would work for all of these?
The answer for me here was to change Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q to Build.VERSION.SDK_INT > Build.VERSION_CODES.Q and then check permission with !Environment.isExternalStorageManager().
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
if(!Environment.isExternalStorageManager()){
try {
Uri uri = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
startActivity(intent);
} catch (Exception ex){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivity(intent);
}
}
} else {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
}

I am trying to select PDF file on button click but I am getting an error

I am trying to select PDF file on button click but I'm getting following message on samsung device :
all apps associated with this action have been turned off blocked or
are not installed.
private void selectPDFFiles(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.parse("package:" + getPackageName()));
startActivity(intent);
return;
}
intent = new Intent();
intent.setType("application/pdf");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent,"select PDF "), 1);
}
Try below code
private void selectPDFFiles(){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
startActivityForResult(intent, 555);
}
And you can get file in activity result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 555:
if (resultCode == RESULT_OK) {
// Get the Uri of the selected file
Uri uri = data.getData();
String uriString = uri.toString();
File myFile = new File(uriString);
String path = myFile.getAbsolutePath();
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
Update
Also try below code
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("application/pdf");
startActivityForResult(intent, 555);
I hope this can help You!
Thank You.

Unable to upload image first time, it works in the second time

I am uploading any type of file from my code but the problem is when I run my code for the first time and try to upload an image, the image not being uploaded in that time. If I upload a file first, e.g. a PDF file, it is being uploaded successfully and after that when I upload an image, it is uploaded successfully as well. I don't understand anything about the problem. Please help.
Here is the code for uploading an image/file.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
showFileChoser();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
Toast.makeText(getActivity(), "App requires Phone permission.\nPlease allow that in the device settings.", Toast.LENGTH_LONG).show();
}
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, STORAGE_PERMISSION_CODE);
}
} else {
showFileChoser();
}
And the showFileChoser function.
private void showFileChoser() {
Intent intent = new Intent();
intent.setType("*/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select document"), PICK_DOCUMENT);
}
The onActivityResult.
// Handling the ima chooser activity result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PDF_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
// uploadMultipart();
try {
execMultipartPost();
} catch (Exception e) {
e.printStackTrace();
}
}
}
And onRequestPermissionsResult is...
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(getActivity(), "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(getActivity(), "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
The file uploading function is the following.
private void execMultipartPost() throws Exception {
RequestBody requestBody;
pBar.setVisibility(View.VISIBLE);
final SessionManager session = new SessionManager(getActivity());
final HashMap<String, String> loggedDetail = session.getLoggedDetail();
HashMap<String, String> params = new HashMap<String, String>();
String api_token = loggedDetail.get("api_token");
if (filePath != null) {
String path = FilePath.getPath(getActivity(), filePath);
requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("identity_file", path)
.addFormDataPart("training", edtTraining.getText().toString())
.addFormDataPart("user_id", loggedDetail.get("id"))
.addFormDataPart("experience", experience)
.addFormDataPart("skills", edtSkills.getText().toString())
.addFormDataPart("address_file", "")
.addFormDataPart("cv_file", "")
.addFormDataPart("dbs_file", "")
.build();
}
}
As far as I can assume, you are calling the requestPermissions function from a Fragment. As you are using ActivityCompat.requestPermissions for asking permission from the user, the onRequestPermissionsResult is not being invoked in the Fragment. Here is a similar problem which indicates the Fragment's onRequestPermissionsResult not being called and the calling Activity's onRequestPermissionsResult is being called instead. I assume this is what happens in your case as well.
Now to get rid of this problem, you need to use
requestPermissions(new String[]{Manifest.permission.CAMERA}, STORAGE_PERMISSION_CODE);
instead of
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, STORAGE_PERMISSION_CODE);
Do not use ActivityCompat.requestPermissions in your Fragment, as this will invoke the onRequestPermissionResult of your calling Activity which is launching the Fragment.
Hope that helps.

How to ask permission to make phone call from Android from Android version Marshmallow onwards?

I am trying to make a phone call from Android, and I've set run time permissions as well. And it asks whether to allow making phone calls. But when I press allow, the app crashes:
This is how I implemented it:
private static final int REQUEST_PHONE_CALL = 1;
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "+918511812660"));
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE},REQUEST_PHONE_CALL);
}
else
{
startActivity(intent);
}
}
else
{
startActivity(intent);
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_PHONE_CALL: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startActivity(intent);
}
else
{
}
return;
}
}
}
This is what I obtain in logcat:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=#android:requestPermissions:,
request=1, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }}
to activity {com.devpost.airway/com.devpost.airway.activities.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String android.content.Intent.toString()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:3733)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3776)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String android.content.Intent.toString()' on a null object reference
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1485)
at android.app.Activity.startActivityForResult(Activity.java:3930)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:75)
at android.app.Activity.startActivityForResult(Activity.java:3890)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:856)
at android.app.Activity.startActivity(Activity.java:4213)
at android.app.Activity.startActivity(Activity.java:4181)
at com.devpost.airway.activities.MainActivity.onRequestPermissionsResult(MainActivity.java:140)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6582)
at android.app.Activity.dispatchActivityResult(Activity.java:6460)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3729)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3776)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
What is possibly causing this?
I would better suggest to use ACTION_DIAL rather than ACTION_CALL while constructing Intent to call a particular number . Using ACTION_DIAL , you will need no call permissions in your app, as ACTION_DIAL opens the dialer with the number already entered, and further allows the user to decide whether to actually make the call or modify the phone number before calling or not call at all.
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + "Your Phone_number"));// Initiates the Intent
startActivity(intent);
The stack trace seems to indicate that your permissions flow is working ok, but the call to startActivity from onRequestPermissionsResult() is crashing. Is the Intent you're passing to startActivity set correctly? I can't see it being set in that part of the code.
Note also that ContextCompat.checkSelfPermission handles the SDK version checking on your behalf, so you should be able to use
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE},REQUEST_PHONE_CALL);
}
else
{
startActivity(intent);
}
by itself, without the wrapping SDK version check code.
You need to create your Intent in onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_PHONE_CALL: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "+918511812660"));
startActivity(intent);
}
else
{
}
return;
}
}
}
add new method
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
add this in Global
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE};
and write below code in onCreate
if(!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
It is better to not use phone_call permission for that action. Google Play console will alert you that you should avoid asking for unnecessary permission from the user. This is a better approach:
/**
* Make a phone call. Send to the phone app
*
* #param phoneNumber the phone number to call
*/
private fun performPhoneCall(phoneNumber: String) {
val intent = Intent(Intent.ACTION_DIAL)
intent.data = Uri.parse("tel:$phoneNumber")
try {
context.startActivity(intent)
} catch (ex: Exception) {
displayErrorMessage()
}
}
Change your onRequestPermissionsResult to below, you basically need to create the intent first and then call it on permission granted. That's where you are doing it wrong.
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_PHONE_CALL : {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "+918511812660"));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
startActivity(intent);
}
}
}
}
}
private void makePhoneCall() {
String number = items;
if (number.trim().length() > 0) {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL);
} else {
String dial = "tel:" + number;
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse(dial)));
}
} else {
Toast.makeText(MainActivity.this, "Enter Phone Number", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CALL) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
makePhoneCall();
} else {
Toast.makeText(this, "Permission DENIED", Toast.LENGTH_SHORT).show();
}
}
}

Open gallery app from Android Intent

I'm looking for a way to open the Android gallery application from an intent.
I do not want to return a picture, but rather just open the gallery to allow the user to use it as if they selected it from the launcher (View pictures/folders).
I have tried to do the following:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
However this is causing the application to close once I select a picture (I know this is because of the ACTION_GET_CONTENT), but I need to just open the gallery.
Any help would be great.
Thanks
This is what you need:
ACTION_VIEW
Change your code to:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setType("image/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I hope this will help you. This code works for me.
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
ResultCode is used for updating the selected image to Gallery View
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK
&& null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
if (cursor == null || cursor.getCount() < 1) {
return; // no cursor or no record. DO YOUR ERROR HANDLING
}
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if(columnIndex < 0) // no column index
return; // DO YOUR ERROR HANDLING
String picturePath = cursor.getString(columnIndex);
cursor.close(); // close cursor
photo = decodeFilePath(picturePath.toString());
List<Bitmap> bitmap = new ArrayList<Bitmap>();
bitmap.add(photo);
ImageAdapter imageAdapter = new ImageAdapter(
AddIncidentScreen.this, bitmap);
imageAdapter.notifyDataSetChanged();
newTagImage.setAdapter(imageAdapter);
}
You can open gallery using following intent:
public static final int RESULT_GALLERY = 0;
Intent galleryIntent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent , RESULT_GALLERY );
If you want to get result URI or do anything else use this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case QuestionEntryView.RESULT_GALLERY :
if (null != data) {
imageUri = data.getData();
//Do whatever that you desire here. or leave this blank
}
break;
default:
break;
}
}
Tested on Android 4.0+
Following can be used in Activity or Fragment.
private File mCurrentPhoto;
Add permissions
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
Add Intents to open "image-selector" and "photo-capture"
//A system-based view to select photos.
private void dispatchPhotoSelectionIntent() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
this.startActivityForResult(galleryIntent, REQUEST_IMAGE_SELECTOR);
}
//Open system camera application to capture a photo.
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(App.Instance.getPackageManager()) != null) {
try {
createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (mCurrentPhoto != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCurrentPhoto));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
Add handling when getting photo.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_IMAGE_SELECTOR:
if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = App.Instance.getContentResolver().query(data.getData(), filePathColumn, null, null, null);
if (cursor == null || cursor.getCount() < 1) {
mCurrentPhoto = null;
break;
}
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
if(columnIndex < 0) { // no column index
mCurrentPhoto = null;
break;
}
mCurrentPhoto = new File(cursor.getString(columnIndex));
cursor.close();
} else {
mCurrentPhoto = null;
}
break;
case REQUEST_IMAGE_CAPTURE:
if (resultCode != Activity.RESULT_OK) {
mCurrentPhoto = null;
}
break;
}
if (mCurrentPhoto != null) {
ImageView imageView = (ImageView) [parent].findViewById(R.id.loaded_iv);
Picasso.with(App.Instance).load(mCurrentPhoto).into(imageView);
}
super.onActivityResult(requestCode, resultCode, data);
}
As you don't want a result to return, try following simple code.
Intent i=new Intent(Intent.ACTION_PICK);
i.setType("image/*");
startActivity(i);
if somebody still getting the error, even after adding the following code
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
then you might be opening the intent in another class (by calling) due to this the app will crash when you click the button.
SOLUTION FOR THE PROBLEM
Put intent in the class file which is connected to the button's layout file.
for example- activity_main.xml contains the button and it is connected to MainActivity.java file. but due to fragmentation, you are defining the intent in some other class(lets says Activity.java) then your app will crash unless you place the intent in MainActivity.java file. I was getting this error and it is resolved by this.

Categories