我正在 Android 中创建一个音乐播放器应用程序。它工作正常但是每当我在歌曲列表中滚动时它开始崩溃并给出这个异常
Process: com.example.lenovo.musicplayer, PID: 31100
java.lang.SecurityException: External path: /storage/emulated/0/Android/data/com.android.providers.media/albumthumbs/1460104607336: Neither user 10294 nor current process has android.permission.WRITE_EXTERNAL_STORAGE.
at android.os.Parcel.readException(Parcel.java:1555)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:153)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:691)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1170)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:994)
at android.content.ContentResolver.openInputStream(ContentResolver.java:719)
at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:1110)
at com.example.lenovo.musicplayer.Adapter.getView(Adapter.java:119)
at android.widget.AbsListView.obtainView(AbsListView.java:2571)
at android.widget.ListView.makeAndAddView(ListView.java:1894)
at android.widget.ListView.fillDown(ListView.java:710)
at android.widget.ListView.fillGap(ListView.java:674)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5900)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:5378)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:825)
at android.view.Choreographer.doCallbacks(Choreographer.java:619)
at android.view.Choreographer.doFrame(Choreographer.java:578)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:811)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6102)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
当我在 list 文件中授予写权限时,这个问题就消失了,但我不明白的是为什么它在我不写的时候要求WriteExternalStoragePermission任何类型的存储。
据我了解,音乐播放器不需要写入外部存储权限。
这是歌曲列表 Activity 的代码
public class ActivitySongsList extends AppCompatActivity {
public static ArrayList<MusicBean>songsList;
ListView listView;
Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_songs_list);
toolbar= (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView= (ListView) findViewById(R.id.lv_songs);
songsList=getAudioList();
Adapter adapter=new Adapter(this,songsList);
listView.setAdapter(adapter);
getSupportActionBar().setTitle("Songs");
toolbar.setTitleTextColor(Color.parseColor("#ffffff"));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent=new Intent(ActivitySongsList.this,ActivityMusicDetails.class);
intent.putExtra("song",songsList.get(position));
intent.putExtra("position",String.valueOf(position));
startActivity(intent);
}
});
}
private ArrayList<MusicBean> getAudioList() {
ArrayList<MusicBean> musicBeanArrayList=new ArrayList<>();
try {
final Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID,MediaStore.Audio.Media.ARTIST,MediaStore.Audio.Media.TITLE}, null, null,
"LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC");
int count = mCursor.getCount();
int i = 0;
if (mCursor.moveToFirst()) {
do {
String song=mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String path=mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
long album_id=mCursor.getLong(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
String artist=mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
Uri sArtworkUri = Uri
.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, album_id);
musicBeanArrayList.add(new MusicBean(song,path,albumArtUri.toString(),String.valueOf(album_id),artist));
/*songs[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
mAudioPath[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));*/
i++;
} while (mCursor.moveToNext());
}
mCursor.close();
}catch (Exception e)
{
e.printStackTrace();
}
return musicBeanArrayList;
}
}
它在这一行异常崩溃
bitmap = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), uri);
在这段代码中,我获得了相应 mp3 文件的专辑封面。 但是这段代码也只是从外部存储读取,因此这也不应该请求写入权限,因为我只是在读取位图而不是写入它。
最佳答案
来自 the MediaProvider code ,处理“/media/external/audio/albumart”
内部 openFile(Uri uri, String mode)
try {
pfd = openFileAndEnforcePathPermissionsHelper(newUri, mode);
} catch (FileNotFoundException ex) {
// That didn't work, now try to get it from the specific file
pfd = getThumb(database, db, audiopath, albumid, null);
}
因此,如果找不到文件,它会调用 getThumb
getThumb 调用 makeThumbInternal
然后在特定条件下,它调用
writeAlbumArt(need_to_recompress, out, compressed, bm);
在最新版本中,writeAlbumArt 调用
final long identity = Binder.clearCallingIdentity();
写之前,应该可以解决问题。但是修复是在 2015 年 8 月 27 日提交的,因此只有 Marshmallow 有机会获得修复。
关于android - 音乐播放器请求写入外部存储权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36545864/
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我想知道Ruby用来在命令行打印这些东西的输出流:irb(main):001:0>a="test"=>"test"irb(main):002:0>putsatest=>nilirb(main):003:0>a=>"test"$stdout是否用于irb(main):002:0>和irb(main):003:0>?而且,在这两次调用之间,$stdout的值是否有任何变化?另外,有人能告诉我打印/写入这些内容的Ruby源代码吗? 最佳答案 是的。而且很容易向自己测试/证明。在命令行试试这个:ruby-e'puts"foo"'>test.
大家好,我正在尝试设置一个开发环境,并且我一直在关注以下教程:Linktotutorial我做得不是很好,除了最基本的版本控制内容外,我对终端命令没有任何实际经验。我点击了第一个链接并尝试运行source~/.bash_profile我得到了错误;mkdir:/usr/local/rbenv/shims:权限被拒绝mkdir:/usr/local/rbenv/versions:权限被拒绝现在每次我加载终端时都会出现错误。bash_profile的内容;exportPATH=/usr/local/rbenv/bin:$PATHexportRBENV_ROOT=/usr/local/rbe
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于
我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内