I'm able to play a ringtone using the following code
rone = RingtoneManager.getRingtone(this.getContext(), Uri.parse(one));
rone.play();
How do I check if the audio file pointed by uri exists? When the user deletes a file from their phone, I'm not able to play the ringtone and it crashes.
getRingtone() will return null if the ringtone does not exist.
Always check that a returned value is not null, this is a good practice whenever you call methods that might return null value. This will prevent a whole lot of NullPointerException
Try to use getRingtonePosition() method instead of getRingtone():
final RingtoneManager rm = new RingtoneManager(preference.getContext());
final Uri loadedRingtoneUri = Uri.parse(ringtoneUriString);
final int pos = rm.getRingtonePosition(loadedRingtoneUri);
// if loaded ringtone uri is valid, use it or use default
final Ringtone ringtone = RingtoneManager.getRingtone(preference.getContext(),
(pos != -1) ? loadedRingtoneUri :
Settings.System.DEFAULT_RINGTONE_URI);
Related
I'm developing a test with Espresso to test the profile image change function. I added the following lines in the #Before method in the test.
I create an intent with the image Uri, with my file provider, to return ever that my app goes to the gallery to pick an image.
Intent resultData = new Intent();
String filename = "img1.jpg";
String path = "mnt/sdcard/" + filename;
File f = new File(path);
Context context =InstrumentationRegistry.getInstrumentation().getContext();
Uri contentUri = getUriForFile(context, "com.otsuka.ikigai.fileprovider", f);
resultData.setData(contentUri);
Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK,resultData);
intending(not(isInternal())).respondWith(result);
The code of the activity that changes user image, calls the following method when it receives the intent,(I must not change it).
mProfileImage = CommonBitmapUtils.rotate(this, data.getData());
profileEdited = true;
imgUserPhoto.setImageBitmap(mProfileImage);
And I'm getting the following error:
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
Caused by this line in the function rotate of the CommonBitmapUtils class:
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
The cursor has 0 rows don't know why.
Solved it by setting the following path. Without file providers and permissions.
I got the path by debugging the app without testing, and copying the value.
resultData.setData(Uri.parse("content://media/external/images/media/142583"));
I'm having trouble getting capture.captureImage to work. Using Cordova 3.5.0, org.apache.cordova.file-1.3.0, org.apache.cordova.media-capture-0.3.3. Debugging in Eclipse shows that
that.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
in onActivityResult returns uri = content://media/external/images/media/nnnn but
OutputStream os = that.cordova.getActivity().getContentResolver().openOutputStream(uri)
throws a FileNotFoundException
It appears that the issue is that the uri returned by the insert method is not properly resolved by openOutputStream. What worked for me was instead of calling openOutputStream, do the following:
String dfname = getRealPathFromURI(uri);
File df = new File(dfname);
File dfolder = df.getParentFile();
if(!dfolder.exists()) dfolder.mkdirs();
if(!df.exists()) df.createNewFile();
FileOutputStream os = new FileOutputStream(df);
private String getRealPathFromURI(Uri contentURI) {
Cursor cursor = this.cordova.getActivity().getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
return contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}
You'll need to import java.io.FileOutputStream, if not already done. I thank Isaac Zais for his answer that pointed me in the right direction and for the getRealPathFromURI code.
It would be great if a Cordova developer could explain if this is a bug in org.apache.cordova.media-capture or somewhere else or if there is a way to get this to work without having to modify the latest version of the plugin.
Tested on Samsung Galaxy S5, Android 4.4.4.
I don't have enough reputation to comment on your answer, but dp22193's patch works great! Please see https://issues.apache.org/jira/browse/CB-7768 for the bug report and the patch attached to it.
I have a little bit strange question: this time everything works, but I can't understand why.
AFAIK it's possible to mount more than one sd card. Everything will be mounted to /mnt directory. (is it true?)
On my device there is only one sd card which mounted to /mnt/sdcard. And in my application I open files from it. I'm using next code:
private void open() {
// get file extension
String extension = "";
int dotIndex = downloadedFile.lastIndexOf('.');
if (dotIndex != -1) {
extension = downloadedFile.substring(dotIndex + 1, downloadedFile.length());
}
// create an intent
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
Uri data = Uri.fromFile(new File(downloadedFile));
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (type == null || type.length() == 0) {
// if there is no acceptable mime type
type = "application/octet-stream";
}
intent.setDataAndType(data, type);
// get the list of the activities which can open the file
List resolvers = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolvers.isEmpty()) {
(new AlertDialog.Builder(context)
.setMessage(R.string.AttachmentUnknownFileType)
.setNeutralButton(R.string.NeutralButtonText, null)
.create()).show();
} else {
context.startActivity(intent);
}
}
Actually downloadedFile variable has value like file:///sdcard/mydir/myfile.txt. But the code works. Why? How Android understand what /sdcard/... is the same as /mnt/sdcard/...?
And main question: what happened if sd card will be mounted to other dir (for exmaple, /mnt/another-sd/ or even /media/sd)? What if more than one sd cards will be mounted: how android understand what card to use?
Thank you for any help! Have a good day!
It's simple android configueres the mounting over a settings file on phone boot so if there are mor sdcards Android will simply prefer one of them to set as
/sdcard/
so when the mount settings change your code is simply useless you can only hope the settings being untouched .
Every company that procuces Android smartphones use the "sdcard" path even custom roms like use it
I try the following code and it doesn't set the ringtone. The logcat entry for "ff" says null so I guess the URI isnt being concatenated properly?, I cant seem to figure out where in my code I am going wrong.
String filepath =Environment.getExternalStorageDirectory().toString()+"//media//audio//ringtones//bluemoon.mp3";
File ringtoneFile = new File(filepath);
ContentValues content = new ContentValues();
content.put(MediaStore.MediaColumns.DATA,ringtoneFile.getAbsolutePath());
content.put(MediaStore.MediaColumns.TITLE, "test");
content.put(MediaStore.MediaColumns.SIZE, 215454);
content.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg");
content.put(MediaStore.Audio.Media.ARTIST, "artist");
content.put(MediaStore.Audio.Media.DURATION, 230);
content.put(MediaStore.Audio.Media.IS_RINGTONE, true);
content.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
content.put(MediaStore.Audio.Media.IS_ALARM, false);
content.put(MediaStore.Audio.Media.IS_MUSIC, false);
Log.i("BOOM", "the absolute path of the file is :"+ringtoneFile.getAbsolutePath());
Uri uri = MediaStore.Audio.Media.getContentUriForPath(
ringtoneFile.getAbsolutePath());
Uri newUri = getApplicationContext().getContentResolver().insert(uri, content);
Uri ringtoneUri = newUri;
Log.i("ff","the ringtone uri is :"+ringtoneUri);
RingtoneManager.setActualDefaultRingtoneUri(getApplicationContext(),
RingtoneManager.TYPE_RINGTONE,newUri);
Its possible data is not accurate for the file and its causing a problem. You may need to change:
audio/mpeg to audio/mp3
and duration to the actual duration of the file.
Another thing you may want to fix is your ringtone file declaration statement, try changing it to match this:
File k = new File(path, "mysong.mp3");
Also, I have a feeling your path is broken too..
Environment.getExternalStorageDirectory().toString()+"//media//audio//ringtones//bluemoon.mp3"
why with the two "//"?
It should be (for example):
../sdcard/media/ringtone
I just cannot seem to figure this one out: how do I respond to the ACTION_VIEW and ACTION_SEND intents? I have them in my Manifest file (and they appear in the drop down list of apps). What I need to do is respond to these intents and retrieve a bitmap of the corresponding image.
Right now here is what works:
Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
Bitmap mBitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
Then I take that uri and fetch a bitmap. However, if I respond when the email app downloads and image getExtras() is null and I get an error.
Basically I need to know what to put in here to fill a variable, mBitmap:
if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_VIEW.equals(action))
{
Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
Bitmap mBitmap = (getExtras() == null) ? what goes here :
BitmapFactory.decodeStream(cr.openInputStream(uri))
}
getIntent().getData() will contain the Uri for which the Intent is targeted.