Below I have the coding for hiow to set audio as your ringtone. This works fine however I wanna know how could I alter this such that it well save just the audio so that it can be played with my other songs
public boolean save1(int type) {
byte[] buffer = null;
InputStream fIn = getBaseContext().getResources().openRawResource(
R.raw.song);
int size = 0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
return false;
}
String path = Environment.getExternalStorageDirectory().getPath()
+ "/media/audio/";
String filename = "New song";
FileOutputStream save;
try {
save = new FileOutputStream(path + filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + path + filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, filename);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
if (RingtoneManager.TYPE_RINGTONE == type) {
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
} else if (RingtoneManager.TYPE_NOTIFICATION == type) {
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
} else if (RingtoneManager.TYPE_ALARM == type) {
values.put(MediaStore.Audio.Media.IS_ALARM, true);
}
Uri uri = MediaStore.Audio.Media.getContentUriForPath(k
.getAbsolutePath());
Uri newUri = MainActivity.this.getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(MainActivity.this, type,
newUri);
this.getContentResolver()
.insert(MediaStore.Audio.Media.getContentUriForPath(k
.getAbsolutePath()), values);
return true;
}
To move raw folder file to sdcard or phone storage below code will work:
private void CopyRAWtoPhone(int id, String path) throws IOException {
InputStream in = getResources().openRawResource(id);
FileOutputStream out = new FileOutputStream(path);
byte[] buff = new byte[1024];
int read = 0;
try {
while ((read = in.read(buff)) > 0) {
out.write(buff, 0, read);
}
} finally {
in.close();
out.close();
}
}
where first Variable id will be your raw file id and String path will be your phone storage path.
Related
I use the following code to save a music and select it as alarm music, but it does not work. where is the problem from?
(Files are saved but not selected as ringtone)
holder.btn_alarm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int resId = getMusicId(position, ringTonesDao);
File file = saveMusic(resId);
setForAlarm(file);
}
});
This code receives the music ID in the software.
public int getMusicId(int position, RingTonesDao ringTonesDao) {
long id = ringTonesList.get(position).getId();
String musicAddress = ringTonesDao.checkMusicAddress(id);
int resId = context.getResources().getIdentifier(musicAddress, "raw", context.getPackageName());
return resId;
}
This code, after receiving the music ID, saves it in the internal memory of the mobile and returns the saved file as the output of the method.
public File saveMusic(int resId) {
File dir;
String folderName = "Ringtones";
if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
dir = new File(Environment.getExternalStorageDirectory(), folderName);
} else {
dir = context.getCacheDir();
}
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, resId + ".mp3");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
try {
InputStream inputStream = context.getResources().openRawResource(resId);
OutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
return file;
}
This code receives the file and sets it as an alert song.
public void setForAlarm(File file) {
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "alarm" + file.getName());
values.put(MediaStore.MediaColumns.SIZE, file.length());
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
values.put(MediaStore.Audio.Media.DURATION, 230);
values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
Uri uri = MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath());
Uri newUri = context.getContentResolver().insert(uri, values);
String[] columns = {MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.IS_ALARM
};
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns, MediaStore.Audio.Media.DATA + " = '" + file.getAbsolutePath() + "'", null, null);
if (cursor != null) {
int idColumn = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
int fileColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
int ringtoneColumn = cursor.getColumnIndex(MediaStore.Audio.Media.IS_ALARM);
while (cursor.moveToNext()) {
String audioFilePath = cursor.getString(fileColumn);
if (cursor.getString(ringtoneColumn) != null && cursor.getString(ringtoneColumn).equals("1")) {
Uri hasUri = MediaStore.Audio.Media.getContentUriForPath(audioFilePath);
newUri = Uri.withAppendedPath(hasUri, cursor.getString(idColumn));
}
}
cursor.close();
}
RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_ALARM, newUri);
}
I am using the following code, but it doesn't seem to change the ringtone. What am I doing wrong, or is there an easier way to set an mp3 to ringtone? I have a uri that parses the location, and I call the following function. I know the uri is correct because it functions correctly with a file share method I have.
private void setRingtone(Uri uri) {
AssetFileDescriptor openAssetFileDescriptor;
((AudioManager) getActivity().getSystemService(AUDIO_SERVICE)).setRingerMode(2);
File file = new File(Environment.getExternalStorageDirectory() + "/appkeeda", mp3s[position]);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
ContentResolver contentResolver = getActivity().getContentResolver();
try {
openAssetFileDescriptor = contentResolver.openAssetFileDescriptor(uri, "r");
} catch (FileNotFoundException e2) {
openAssetFileDescriptor = null;
}
try {
byte[] bArr = new byte[1024];
FileInputStream createInputStream = openAssetFileDescriptor.createInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
for (int read = createInputStream.read(bArr); read != -1; read = createInputStream.read(bArr)) {
fileOutputStream.write(bArr, 0, read);
}
fileOutputStream.close();
} catch (IOException e3) {
e3.printStackTrace();
}
ContentValues contentValues = new ContentValues();
contentValues.put("_data", file.getAbsolutePath());
contentValues.put("title", "nkDroid ringtone");
contentValues.put("mime_type", "audio/mp3");
contentValues.put("_size", Long.valueOf(file.length()));
contentValues.put("artist", Integer.valueOf(R.string.app_name));
contentValues.put("is_ringtone", Boolean.valueOf(true));
contentValues.put("is_notification", Boolean.valueOf(false));
contentValues.put("is_alarm", Boolean.valueOf(false));
contentValues.put("is_music", Boolean.valueOf(false));
try {
//Toast.makeText(this, new StringBuilder().append("Ringtone set successfully"), Toast.LENGTH_LONG).show();
RingtoneManager.setActualDefaultRingtoneUri(getActivity().getBaseContext(), 1, contentResolver.insert(MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath()), contentValues));
} catch (Throwable th) {
//Toast.makeText(this, new StringBuilder().append("Ringtone feature is not working"), Toast.LENGTH_LONG).show();
}
}
Solution: This tutorial worked for me: http://blog.nkdroidsolutions.com/set-default-ringtone-raw-folder-programmatically-android/
I am using Xamarin Forms and using Dependency Service to set ringtone from mp3 places in asset folder. Here is my code:
AssetManager assets = Forms.Context.Assets;
fileName = "Artist.mp3";
System.IO.Stream inputStream;
System.IO.Stream outputStream;
try
{
inputStream = assets.Open("Sounds/" + fileName);
**_ outputStream = Forms.Context.OpenFileOutput(fileName, FileCreationMode.Private); _**
byte[] buffer = new byte[65536 * 2];
int read;
while ((read = inputStream.Read(buffer, 0, (int)inputStream.Length)) != -1)
{
outputStream.Write(buffer, 0, read);
}
inputStream.Close();
inputStream = null;
outputStream.Flush();
outputStream.Close();
outputStream = null;
Java.IO.File newSoundFile = new Java.IO.File(basepath + "/Sounds/" + fileName);
if (newSoundFile.Exists())
{
ContentValues values = new ContentValues();
values.Put(MediaStore.MediaColumns.Data, newSoundFile.AbsolutePath);
values.Put(MediaStore.MediaColumns.Title, "Test Ringtone");
values.Put(MediaStore.MediaColumns.MimeType, "audio/*");
values.Put(MediaStore.MediaColumns.Size, newSoundFile.Length());
values.Put(MediaStore.Audio.Media.InterfaceConsts.Artist, "Artist MP3");
values.Put(MediaStore.Audio.Media.InterfaceConsts.Duration, 2300);
values.Put(MediaStore.Audio.Media.InterfaceConsts.IsRingtone, true);
values.Put(MediaStore.Audio.Media.InterfaceConsts.IsNotification, false);
values.Put(MediaStore.Audio.Media.InterfaceConsts.IsAlarm, false);
values.Put(MediaStore.Audio.Media.InterfaceConsts.IsMusic, false);
Android.Net.Uri uri = MediaStore.Audio.Media.GetContentUriForPath(newSoundFile.AbsolutePath);
Forms.Context.ContentResolver.Delete(uri, MediaStore.MediaColumns.Data + "=\"" + newSoundFile.AbsolutePath + "\"", null);
Android.Net.Uri newUri = Forms.Context.ContentResolver.Insert(uri, values);
try
{
RingtoneManager.SetActualDefaultRingtoneUri(Forms.Context, RingtoneType.Ringtone, newUri);
}
catch (Exception e)
{
}
}
}
catch (Exception e)
{
}
I am getting below exception in the line outputStream = Forms.Context.OpenFileOutput(fileName, FileCreationMode.Private)
System.NotSupportedException: Specified method is not supported.
at Android.Runtime.InputStreamInvoker.get_Length () [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/source/monodroid/src/Mono.Android/src/Runtime/InputStreamInvoker.cs:55
You are implementing Stream.CopyTo manually. Just use it.
using (var inputStream = assets.Open("Sounds/" + fileName))
using (var outputStream = Forms.Context.OpenFileOutput(fileName, FileCreationMode.Private))
{
inputStream.CopyTo(outputStream);
}
I am trying to make my Android app save a mp3 from the app to the sd card so it may be of use later, but it is not saving the file anywhere in the phone. In my AndroidManifest file, I have a permission to write external storage.
Here is the code I have thus far:
public void onClick(View v) {
int ressound = R.raw.hodor1;
saveas(ressound);
}
public boolean saveas(int ressound){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
//1st part
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
Log.e(TAG, "IOException first part");
return false;
}
String soundname = "hodor1";
String filename = soundname +".mp3";
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
File fullPath = new File(path, filename);
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
//second part
FileOutputStream save;
try {
save = new FileOutputStream(fullPath);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
Log.e(TAG, "FileNotFoundException in second part");
return false;
} catch (IOException e) {
Log.e(TAG, "IOException in second part");
return false;
}
//not working
//sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, soundname);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.ARTIST, "Elvis");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
Uri newUri = this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
// set as ringtone
//savetype = RingtoneManager.TYPE_RINGTONE;
//RingtoneManager.setActualDefaultRingtoneUri(this, savetype, newUri);
return true;
}
Commonsware answered my post the most accurately. Environment.getExternalStoragePublicDirectory() should be used along with the proper programming techniques like Logging and using the two parameter File constructor.
This has been changed from the original post.
Basically what is happening is I have gotten this to display the ringtone in the ringtone list on the phone. It also selects it. In this code it plays the ringtone after it has been selected (I have taken it out to reduce the size). It seems to be playing the phones default ringtone. Any ideas why? Thanks
private void ringtone(int p){
File newSoundFile = new File("/sdcard/media/ringtone", "raven.wav");
Uri mUri = Uri.parse("android.resource://com.fs.hh/"+R.raw.raven);
ContentResolver mCr = getContentResolver();
AssetFileDescriptor soundFile;
try {
soundFile= mCr.openAssetFileDescriptor(mUri, "r");
} catch (FileNotFoundException e) {
soundFile=null;
}
try {
byte[] readData = new byte[1024];
FileInputStream fis = soundFile.createInputStream();
FileOutputStream fos = new FileOutputStream(newSoundFile);
int i = fis.read(readData);
while (i != -1) {
fos.write(readData, 0, i);
i = fis.read(readData);
}
fos.close();
soundFile.close();
} catch (IOException io) {
}
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, newSoundFile.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "my ringtone");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
values.put(MediaStore.MediaColumns.SIZE, newSoundFile.length());
values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
Uri uri = MediaStore.Audio.Media.getContentUriForPath(newSoundFile.getAbsolutePath());
mCr.delete(uri, MediaStore.MediaColumns.DATA + "=\"" + newSoundFile.getAbsolutePath() + "\"", null);
Uri newUri = mCr.insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(Soundboard.this, RingtoneManager.TYPE_RINGTONE, newUri);
}
I have also tried adding a / after ringtone and making it get the byte size. Neither have worked.
I have also tried this piece of code instead and it causes the same problem. It shows up selected in the notification section, but the sound being played is not the correct sound. It sounds like a default ringer.
private boolean setRingtone(int p){
int ressound = whichSound(p); //The R.raw.sound
String fileTitle = fileTitle(p); // sound
String soundTitle = soundTitle(p); // Sound
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path="/sdcard/media/notification";
String filename=fileTitle+".wav";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, soundTitle);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
values.put(MediaStore.Audio.Media.ARTIST, "HH");
values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, false);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
Uri newUri= this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
RingtoneManager.setActualDefaultRingtoneUri(
this,
RingtoneManager.TYPE_NOTIFICATION,
newUri
);
return false;
}
Here is what finally fixed it.
private boolean setRingtone(int p){
int ressound = whichSound(p);
String fileTitle = fileTitle(p);
String soundTitle = soundTitle(p);
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=0;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
String path=Environment.getExternalStorageDirectory().getPath()+"/media/ringtone/";
String filename=fileTitle+".wav";
boolean exists = (new File(path)).exists();
if (!exists){new File(path).mkdirs();}
FileOutputStream save;
try {
save = new FileOutputStream(path+filename);
save.write(buffer);
save.flush();
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
return false;
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));
File k = new File(path, filename);
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, soundTitle);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
values.put(MediaStore.Audio.Media.ARTIST, "");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, false);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
Uri uri = MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath());
getContentResolver().delete(uri, MediaStore.MediaColumns.DATA + "=\"" + k.getAbsolutePath() + "\"", null);
Uri newUri = getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE, newUri);
return false;
}
In the path String by adding Environment.getExternatStorageDirectory().getPath() instead of just the sdcard it was actually able to play the sound and work properly.
Uri mUri = Uri.parse("android.resource://com.packange.name/"+R.raw.raven);
"com.packange.name" should be the name of your package, I assume you havenĀ“t called it like that. Hardcode your package name, or call getPackageName() from a proper context.
Update: You can get an uri out of your newSoundFile object, just do Uri.fromFile( newSoundFile ).