问题
I am developing an application: I am trying to set an audio file as a ringtone.
I saw many posts, but no one actually helped me, so I decided to ask this question.
I use this code when the Button is clicked:
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("audio/*");
startActivityForResult(Intent.createChooser(intent, "Choose Sound File"), Audio);
}
in onActivityResult
I am trying to get the file path and then set the audio file as ringtone using the code below:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Audio && requestCode==RESULT_OK) {
Uri s1 = data.getData();
String s = s1.getPath();
if(s!=null){
try {
k = new File(new URI(s)); //(File k;)
} catch (URISyntaxException e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "My Song title");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg");
values.put(MediaStore.Audio.Media.ARTIST, "Some Artist");
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 uri = MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath());
Uri newUri = getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(
MainActivity.this,
RingtoneManager.TYPE_RINGTONE,
newUri);
}
}
}
Unfortunately this code doesn't work.
I would appreciate your answers. Sorry for my bad English.
回答1:
I saw many posts but anyone showed what i should actually have to do. So i decided to create this complete answer , in which i have the solution of my problem...
Here is my MainActivity.java
which i used
import java.io.File;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
Button b;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
b = (Button) findViewById(R.id.button2);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent1 = new Intent();
intent1.setAction(Intent.ACTION_GET_CONTENT);
intent1.setType("audio/*");
startActivityForResult(
Intent.createChooser(intent1, "Choose Sound File"), 6);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == 6) {
Uri i = data.getData(); // getData
String s = i.getPath(); // getPath
File k = new File(s); // set File from path
if (s != null) { // file.exists
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "ring");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.MediaColumns.SIZE, k.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(k
.getAbsolutePath());
getContentResolver().delete(
uri,
MediaStore.MediaColumns.DATA + "=\""
+ k.getAbsolutePath() + "\"", null);
Uri newUri = getContentResolver().insert(uri, values);
try {
RingtoneManager.setActualDefaultRingtoneUri(
MainActivity.this, RingtoneManager.TYPE_RINGTONE,
newUri);
} catch (Throwable t) {
}
}
}
}
}
Lastly, its really important to add those permissions in your AndroidManifest.xml
for example if you don't add the permission to write external storage your app will crash like mine.. xD
What you need:
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
You can try my app on Google Play : BackAtel Audio Manager
Hope that helps.... my problem is now solved!! i hope that i solved your problem too :))
回答2:
I had the same problem and couldn't find an answer anywhere.
This is the code i used.
@SuppressLint("SdCardPath")
public class Content extends Activity {
int selectedSoundId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content);
final MediaPlayer player = new MediaPlayer();
final Resources res = getResources();
//just keep them in the same order, e.g. button01 is tied to back to you
final int[] buttonIds = { R.id.Button01, R.id.Button02, R.id.Button03, R.id.Button04, R.id.Button05, R.id.Button06,R.id.button1};
final int[] soundIds = { R.raw.deargod, R.raw.donttalk, R.raw.lookat, R.raw.stop, R.raw.text,R.raw.john, R.raw.sherlock, };
View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
//find the index that matches the button's ID, and then reset
//the MediaPlayer instance, set the data source to the corresponding
//sound effect, prepare it, and start it playing.
for(int i = 0; i < buttonIds.length; i++) {
if(v.getId() == buttonIds[i]) {
selectedSoundId = soundIds[i];
AssetFileDescriptor afd = res.openRawResourceFd(soundIds[i]);
player.reset();
try {
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
player.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
player.start();
break;
}
}
}
};
//set the same listener for every button ID, no need
//to keep a reference to every button
for(int i = 0; i < buttonIds.length; i++) {
Button soundButton = (Button)findViewById(buttonIds[i]);
registerForContextMenu(soundButton);
soundButton.setOnClickListener(listener);
// new code to prevent crash is below.
if(soundButton!= null)
{
selectedSoundId = soundIds[1];
}
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Save as...");
menu.add(0, v.getId(), 0, "Ringtone");
menu.add(0, v.getId(), 0, "Notification");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if(item.getTitle()=="Ringtone"){function1(item.getItemId());}
else if(item.getTitle()=="Notification"){function2(item.getItemId());}
else {return false;}
return true;
}
public void function1(int id){
if
(savering(selectedSoundId)){
// Code if successful
Toast.makeText(this, "Saved as Ringtone", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
}
public void function2(int id){
if
(savenot(selectedSoundId)){
// Code if successful
Toast.makeText(this, "Saved as Notification", Toast.LENGTH_SHORT).show();
}
else
{
// Code if unsuccessful
Toast.makeText(this, "Failed - Check your SDCard", Toast.LENGTH_SHORT).show();
}
}
//Save into Ring tone Folder
public boolean savering(int ressound){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=50;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
}
String path="/sdcard/sounds/";
String filename="Sherlock"+".mp3";
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
} catch (IOException e) {
// TODO Auto-generated catch block
}
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, "SHRingtone");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.ARTIST, "Sherlock ");
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);
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 true;
}
//Save in Notification Folder
@SuppressLint("SdCardPath")
public boolean savenot(int ressound){
byte[] buffer=null;
InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
int size=50;
try {
size = fIn.available();
buffer = new byte[size];
fIn.read(buffer);
fIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
}
String path="/sdcard/sounds/";
String filename="Sherlock"+".mp3";
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
} catch (IOException e) {
// TODO Auto-generated catch block
}
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, "SHNotification");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.ARTIST, "sherlock ");
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);
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_NOTIFICATION, newUri);
return true;
}
}
回答3:
setting audio as a ringtone is the same as setting tone in alarm heres the code:
ContentValues values = new ContentValues(4);
long current = System.currentTimeMillis();
values.put(MediaStore.MediaColumns.DATA, path+audioname );
values.put(MediaStore.MediaColumns.TITLE, path+audioname );
values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/3gpp");
//new
values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
///new
// values.put(MediaStore.Audio.Media.DATA, audiofile.getAbsolutePath());
// ContentResolver contentResolver = getContentResolver();
//Insert it into the database
this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(path+audioname), values);
//RingtoneManager.setActualDefaultRingtoneUri(Activity.this,
// RingtoneManager.TYPE_RINGTONE, newUri);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+path+audioname
+ Environment.getExternalStorageDirectory())));
// sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+editText1)));
//Toast.makeText(this, "New Alarm Sound " + editText1 +format, Toast.LENGTH_LONG).show();
}
using this code it allows your sound to be put in specific sd card folders and
then setting it as ringtone and alarmtone:
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
or you can follow a complete tutorial regarding this problem.
来源:https://stackoverflow.com/questions/21765447/set-a-selected-audio-file-as-ringtone