【问题标题】:Android Exception, produced whenever Music files are set as Alarm Defualt RingtonesAndroid 异常,每当音乐文件设置为闹钟默认铃声时产生
【发布时间】:2015-06-24 05:34:57
【问题描述】:

我将分享需要更正的异常。我在我的项目中从手机的外部存储器中提取了音乐文件。我尝试将其设置为 Android Alarm 应用程序的默认铃声。每当我设置它时,它就会显示在警报中,但它没有被播放。我猜是因为下面的异常。

E/DatabaseUtils﹕ Writing exception to parcel
    java.lang.SecurityException: External path: /storage/sdcard/Maid with the Flaxen Hair.mp3: Neither user 1000 nor current process has android.permission.READ_EXTERNAL_STORAGE.
            at android.app.ContextImpl.enforce(ContextImpl.java:1685)
            at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:1714)
            at com.android.providers.media.MediaProvider.checkAccess(MediaProvider.java:4615)
            at com.android.providers.media.MediaProvider.openFileAndEnforcePathPermissionsHelper(MediaProvider.java:4578)
            at com.android.providers.media.MediaProvider.openFile(MediaProvider.java:4502)
            at android.content.ContentProvider.openFile(ContentProvider.java:1157)
            at android.content.ContentProvider$Transport.openFile(ContentProvider.java:300)
            at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:232)
            at android.os.Binder.execTransact(Binder.java:404)
            at dalvik.system.NativeStart.run(Native Method)

即使我添加了 READ_EXTERNAL_STORAGE 权限并包含 conentProvider 的 grantUriPermission(),此错误仍然存​​在。

这是清单文件。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ctsprojects.com.alarmapp" >

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_MEDIA_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".songList"
            android:label="@string/title_activity_song_list"
            android:exported="true" >
        </activity>
        <activity
            android:name=".NextAlarm"
            android:label="@string/title_activity_next_alarm" >
        </activity>
    </application>

</manifest>

我使用代码设置铃声的活动。就这样吧。。

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Path;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Calendar;


public class songList extends Activity {

    private String[] mMusicList;
    ListView mListView;
    String s, path;

String[] pathhh;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_song_list);
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog()
                .penaltyDeath().build());
        mListView = (ListView) findViewById(R.id.listView);

        mMusicList = getMusic();

        ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, mMusicList);
        mListView.setAdapter(mAdapter);

        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                                    long arg3) {
                try {

                    /*playSong(mMusicList[arg2]);*/



                    path = pathhh[arg2];

                    s = (String) mListView.getItemAtPosition(arg2);
                    Log.d("songName", s);

              File k = new File(path);

                    System.out.println(k);
                    ContentValues values = new ContentValues();
                    values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
                    values.put(MediaStore.MediaColumns.TITLE, s);
                    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());
                    grantUriPermission("android.media.MediaPlayer", uri,
                            Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    getContentResolver().delete(uri, MediaStore.MediaColumns.DATA + "=\"" + k.getAbsolutePath() + "\"", null);
                    Uri newUri = getContentResolver().insert(uri, values);


                    try {
                        RingtoneManager.setActualDefaultRingtoneUri(songList.this, RingtoneManager.TYPE_ALARM, newUri);

                    } catch (Throwable t) {

                    }


                    //Intent a = new Intent(songList.this, NextAlarm.class);
                    //a.putExtra("song", s);
                    // startActivity(a);


                    finish();


                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }
        });


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_song_list, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private String[] getMusic() {
        final Cursor mCursor = getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.MediaColumns.TITLE, MediaStore.MediaColumns.DATA, MediaStore.Audio.AudioColumns.ALBUM}, null, null,
                "LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC");


        int count = mCursor.getCount();

        String[] songs = new String[count];
        int i = 0;
        String[] pathh= new String[count];
        if (mCursor.moveToFirst()) {
            do {
                songs[i] = mCursor.getString(0);
                pathh[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));

                i++;
            } while (mCursor.moveToNext());
        }
        pathhh = pathh;

        mCursor.close();

        return songs;
    }


}

在上述活动中。我正在从外部 SD 卡中取出歌曲。将它们填充到 listView 中。点击一首歌,我就有了设置默认闹钟铃声的代码。这就是代码的作用。

我有一个列表视图,其中填充了所有歌曲。我的工作是从列表中单击一首歌曲并将其设置为铃声。我需要从 listView 本身获取路径和文件名。有什么办法吗?

【问题讨论】:

  • 添加你的清单文件,你在使用 proguard 吗?
  • 我已经添加了 Manifest 文件。我没有使用 proguard。
  • @MitBhatt 我在我的代码中做了同样的事情。我可以将其设置为我的默认闹钟铃声。按照我的意愿工作正常。但它不会播放。我收到上述错误。
  • 你能展示你的歌曲列表活动吗?

标签: android


【解决方案1】:

共享清单文件。 检查权限是否添加正确。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

【讨论】:

  • 我已经编辑了我的帖子并包含了 Manifest 文件。
【解决方案2】:

您必须将清单文件中的android:exported="true" 添加到您作为内容提供者的活动中。

更多详情

http://developer.android.com/guide/topics/manifest/activity-element.html#exported

【讨论】:

  • 你试过了吗,如果可行请接受这个答案。
  • 我添加了这一行。您可以看到我在活动 SongList 中添加了它,其中我有设置闹钟铃声的代码。我再次编辑了清单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多