...但是能解決的還是解決下吧.
問(wèn)題現(xiàn)象及問(wèn)題定位
NotificationCompat.Builder.setSound(URI)的時(shí)候,發(fā)現(xiàn)沒(méi)有發(fā)出任何聲音,但是卻顯示出了一個(gè)錯(cuò)誤.
問(wèn)題分析
將系統(tǒng)鈴聲設(shè)置為系統(tǒng)通知鈴聲需要兩個(gè)操作
- 通過(guò)
RingtoneManager.ACTION_RINGTONE_PICKER,
獲取"/system/media/audio/notifications"路徑下的音樂(lè)的URI
- 調(diào)用RingtoneManager.setActualDefaultRingtoneUri()歇盼,傳入相應(yīng)的uri和需要設(shè)置的鈴聲類型即可胳蛮。
如果你使用的是file: Uri,在targetSdkVersion>=24(Android 7.0以上)的時(shí)候是不適用的.因?yàn)锳ndroid 7.0的Uri會(huì)檢查播放的聲音是否是file:Uri禁用值
問(wèn)題的解決方法
只需要在調(diào)用聲音的前面加一句黑代碼 就可以完美解決
grantUriPermission("com.android.systemui", soundUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
這里的soundUri就是你調(diào)取系統(tǒng)聲音的Uri
貼碼
說(shuō)那么多沒(méi)用的,不如擼一把代碼.為了方便大家直接使用做了一個(gè)簡(jiǎn)單的demo,方便大家參考.
也可以從github上直接下載下來(lái),RingStom
- 布局activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="@+id/buttonRingtone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="設(shè)置來(lái)電鈴聲"
/>
<Button
android:id="@+id/buttonAlarm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="設(shè)置鬧鐘鈴聲"
/>
<Button
android:id="@+id/buttonNotification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="設(shè)置通知鈴聲"
/>
</LinearLayout>
- 相關(guān)的java代碼
public class MainActivity extends AppCompatActivity {
/* 3個(gè)按鈕 */
private Button mButtonRingtone;
private Button mButtonAlarm;
private Button mButtonNotification;
/* 自定義的類型 */
public static final int CODE_RINGSTONE = 0;
public static final int CODE_ALARM = 1;
public static final int CODE_NOTIFICATION = 2;
/**
* 來(lái)電鈴聲文件夾
* /system/media/audio/ringtones 系統(tǒng)來(lái)電鈴聲
* /sdcard/music/ringtones 用戶來(lái)電鈴聲
*/
private String strRingtoneFolder = "/system/media/audio/ringtones";
// private String strRingtoneFolder = "/sdcard/music/ringtones";
/**
* 鬧鐘鈴聲文件夾
* /system/media/audio/alarms 系統(tǒng)鬧鐘鈴聲
* /sdcard/music/alarms 用戶鬧鐘鈴聲
*/
private String strAlarmFolder = "/system/media/audio/alarms";
// private String strAlarmFolder = "/sdcard/music/alarms ";
/**
* 鬧鐘鈴聲文件夾
* /system/media/audio/notifications 系統(tǒng)通知鈴聲
* /sdcard/music/notifications 用戶通知鈴聲
*/
private String strNotificationFolder = "/system/media/audio/notifications";
// private String strNotificationFolder = "/sdcard/music/notifications";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtonRingtone = (Button) findViewById(R.id.buttonRingtone);
mButtonAlarm = (Button) findViewById(R.id.buttonAlarm);
mButtonNotification = (Button) findViewById(R.id.buttonNotification);
mButtonRingtone.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (hasFolder(strRingtoneFolder)) {
// 打開(kāi)系統(tǒng)鈴聲設(shè)置
Intent intent = new Intent(
RingtoneManager.ACTION_RINGTONE_PICKER);
// 類型為來(lái)電RINGTONE
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
RingtoneManager.TYPE_RINGTONE);
// 設(shè)置顯示的title
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
"設(shè)置來(lái)電鈴聲");
// 當(dāng)設(shè)置完成之后返回到當(dāng)前的Activity
startActivityForResult(intent, CODE_RINGSTONE);
}
}
});
mButtonAlarm.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (hasFolder(strAlarmFolder)) {
// 打開(kāi)系統(tǒng)鈴聲設(shè)置
Intent intent = new Intent(
RingtoneManager.ACTION_RINGTONE_PICKER);
// 設(shè)置鈴聲類型和title
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
RingtoneManager.TYPE_ALARM);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
"設(shè)置鬧鐘鈴聲");
// 當(dāng)設(shè)置完成之后返回到當(dāng)前的Activity
startActivityForResult(intent, CODE_ALARM);
}
}
});
mButtonNotification.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (hasFolder(strNotificationFolder)) {
// 打開(kāi)系統(tǒng)鈴聲設(shè)置
Intent intent = new Intent(
RingtoneManager.ACTION_RINGTONE_PICKER);
// 設(shè)置鈴聲類型和title
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
RingtoneManager.TYPE_NOTIFICATION);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,
" 設(shè)置通知鈴聲");
// 當(dāng)設(shè)置完成之后返回到當(dāng)前的Activity
startActivityForResult(intent, CODE_NOTIFICATION);
}
}
});
}
/**
* 當(dāng)設(shè)置鈴聲之后的回調(diào)函數(shù)
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) {
return;
}
// 得到我們選擇的鈴聲
Uri pickedUri = data
.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (pickedUri != null) {
switch (requestCode) {
case CODE_RINGSTONE:
// 將我們選擇的鈴聲設(shè)置成為默認(rèn)來(lái)電鈴聲
RingtoneManager.setActualDefaultRingtoneUri(this,
RingtoneManager.TYPE_RINGTONE, pickedUri);
break;
case CODE_ALARM:
// 將我們選擇的鈴聲設(shè)置成為默認(rèn)鬧鐘鈴聲
RingtoneManager.setActualDefaultRingtoneUri(this,
RingtoneManager.TYPE_ALARM, pickedUri);
break;
case CODE_NOTIFICATION:
// 將我們選擇的鈴聲設(shè)置成為默認(rèn)通知鈴聲
/**
* 敲黑板:黑代碼解決Android 7.0 調(diào)用系統(tǒng)通知無(wú)法播放聲音的問(wèn)題
*/
grantUriPermission("com.android.systemui", pickedUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
RingtoneManager.setActualDefaultRingtoneUri(this,
RingtoneManager.TYPE_NOTIFICATION, pickedUri);
break;
}
}
}
/**
* 檢測(cè)是否存在指定的文件夾,如果不存在則創(chuàng)建
*
* @param strFolder
* 文件夾路徑
*/
private boolean hasFolder(String strFolder) {
boolean btmp = false;
File f = new File(strFolder);
if (!f.exists()) {
if (f.mkdirs()) {
btmp = true;
} else {
btmp = false;
}
} else {
btmp = true;
}
return btmp;
}
}