【问题标题】:Setting mp3 from RAW folder as a android ringtone, notification and alarm sound将 RAW 文件夹中的 mp3 设置为安卓铃声、通知和闹钟声音
【发布时间】:2017-03-14 03:40:25
【问题描述】:

我的第一个(铃声)应用程序的最后一块,我遇到了一些麻烦,根据一些教程并在朋友的帮助下,我想出了一个代码,可以将 RAW 文件夹中的 mp3 作为 android 铃声,通知, 和警报声。我在模拟器上进行了测试,它可以工作,但是当我在我的 S6edge+ 上测试它时,什么也没发生,有人可以告诉我这段代码可能有什么问题,或者是否有人可以为我指出更好的编码解决方案

这是代码:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setSong(this, RingtoneManager.TYPE_RINGTONE, R.raw.test, "TestR");
    setSong(this, RingtoneManager.TYPE_NOTIFICATION, R.raw.test, "TestN");
    setSong(this, RingtoneManager.TYPE_ALARM, R.raw.test, "TestA");
}


/**
 * In this method, we need to copy the mp3 file to the sd card location from
 * where android picks up ringtone files
 * After copying, we make the mp3 as current ringtone
 *
 * @param context
 * @param type
 * @param songId
 * @param ringtoneTitle
 * @return
 */

public static boolean setSong(Context context, int type, int songId, String ringtoneTitle) {
    byte[] buffer = null;
    InputStream fIn = context.getResources().openRawResource(
            songId);
    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/ringtones/";

    String filename = ringtoneTitle + ".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) {
        return false;
    } catch (IOException e) {
        return false;
    }

    context.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, ringtoneTitle);
    values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*");
    values.put(MediaStore.MediaColumns.SIZE, k.length());

    // This method allows to change Notification and Alarm tone also. Just
    // pass corresponding type as parameter
    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());

    String selection = MediaStore.MediaColumns.DATA + " =?";
    String[] selectionArgs = {k.getAbsolutePath()};
    Uri newUri = null;

    // Check if record exist
    Cursor c = context.getContentResolver().query(uri, null, selection, selectionArgs, null);
    if (c != null) {
        if (c.getCount() > 0) {
            // Record exist
            // Update record
            while (c.moveToNext()) {
                int idIndex = c.getColumnIndex(MediaStore.Audio.Media._ID);
                int dataIndex = c.getColumnIndex(MediaStore.Audio.Media.DATA);
                String strId = c.getString(idIndex);
                String songPath = c.getString(dataIndex);
                newUri = MediaStore.Audio.Media.getContentUriForPath(songPath);
                String condition = MediaStore.Audio.Media._ID + " =?";
                String[] selectionArg = {strId};
                context.getContentResolver().update(uri, values, condition, selectionArg);
            }

        } else {
            // Record does not exist, create new
            newUri = context.getContentResolver().insert(uri, values);
        }
    }

    if (newUri != null) {
        RingtoneManager.setActualDefaultRingtoneUri(context, type,
                newUri);
        return true;
    }

    return false;
}

}

当然,我有权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>`

和原始文件夹中的 test.mp3 文件

【问题讨论】:

  • 检查棉花糖的权限
  • 我已经尝试过了,并且还实现了运行时权限。我收到以下错误:java.lang.IllegalArgumentException:您无法将设置保存在安全设置中。 ——

标签: android notifications mp3 android-6.0-marshmallow ringtone


【解决方案1】:

从 Android 6.0(API 级别 23)开始,用户在应用运行时授予应用权限,而不是在安装应用时。这种方法简化了应用程序安装过程,因为用户在安装或更新应用程序时不需要授予权限。它还使用户可以更好地控制应用程序的功能;例如,用户可以选择让相机应用程序访问相机而不是设备位置。用户可以通过进入应用程序的设置屏幕随时撤销权限。

您需要在应用程序中处理运行时权限。 请参阅以下链接以获取教程。 Runtime Permission in Android

【讨论】:

  • 我不这么认为,我从 Google Play 下载了一个应用程序并在同一部手机上运行它,它在设置铃声时没有要求任何权限,所以不可能是这样的
  • 我已经尝试过了,并且还实现了运行时权限。我收到以下错误:java.lang.IllegalArgumentException: You cannot keep your settings in the secure settings.
  • 您的应用程序无权访问WRITE_SETTINGS 权限。您需要通过启动设置屏幕要求用户明确授予权限。您可以使用Settings.ACTION_MANAGE_WRITE_SETTINGS 操作启动屏幕Reference
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多