当前位置: 首页 > 知识库问答 >
问题:

对于以Android11为目标的应用程序,requestLegacyExternalStorage标志将被忽略

双浩涆
2023-03-14

在运行Android11+的设备上使用应用程序的开发者必须使用范围存储,以给用户更好的访问控制他们的设备存储。要在5月5日之后在Android 11或更新版本上发布应用程序,您必须:

更新您的应用程序以使用更隐私友好的最佳实践,如存储访问框架或媒体存储API更新您的应用程序以声明清单文件中的所有文件访问(MANAGE_EXTERNAL_STORACTA)权限,并从5开始在播放控制台中完成所有文件访问权限声明。对于针对Android 11的应用程序,将完全从您的应用程序中删除所有文件访问权限,requestLegacyExternalStorage标志将被忽略。必须使用所有文件访问权限才能保留广泛访问权限。

未经允许使用而请求访问所有文件访问权限的应用程序将从Google Play中删除,您将无法发布更新。

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

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:resizeableActivity="false"
            android:requestLegacyExternalStorage="true"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.YMusic">
            <activity android:name="com.developer_ashu.ymusic.PlaySong"
                android:launchMode="singleTop"
                android:screenOrientation="portrait"
                android:parentActivityName="com.developer_ashu.ymusic.MainActivity">
    
            </activity>
            <activity android:name="com.developer_ashu.ymusic.MainActivity"
                android:screenOrientation="portrait">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <receiver android:name=".Notification.NotificationReceiver"/>
        </application>
    
    </manifest>



MainActivity.java
public class MainActivity extends AppCompatActivity {
    ListView listView;
    MediaPlayer mediaPlayer;
   ArrayList<song_info> listSongs = new ArrayList<song_info>();
   private MySongAdapter mySongAdapter ;
    private  String[] itemsAll;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);


        Dexter.withContext(this)
                .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                .withListener(new PermissionListener() {
                    @Override public void onPermissionGranted(PermissionGrantedResponse response) {
                      loadSongs();
                    }
                    @Override public void onPermissionDenied(PermissionDeniedResponse response) {


                    }
                    @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
                        token.continuePermissionRequest();
                     }
                }).check();
    }

  private void loadSongs(){
        Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
      String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
      Cursor cursor = getContentResolver().query(uri,null,selection,null,null);
      if (cursor != null){
          while(cursor.moveToNext()){
              String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
              String author = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
              String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));

              listSongs.add(new song_info(title,author,url));
          }
      }
      mySongAdapter = new MySongAdapter(listSongs);
      listView.setAdapter(mySongAdapter);
  }

    private class MySongAdapter extends BaseAdapter {
        ArrayList<song_info> myListSongs;

        public MySongAdapter(ArrayList<song_info> myListSongs) {
            this.myListSongs = myListSongs;
        }

        @Override
        public int getCount() {
            return myListSongs.size();
        }

        @Override
        public Object getItem(int position) {
            return myListSongs.get(position);
        }

        @Override
        public long getItemId(int position) {
            return (long) position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textView,textView1;
            Button button;
            LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
            View view = inflater.inflate(R.layout.my_layout,parent,false);
            song_info song = myListSongs.get(position);
            textView = view.findViewById(R.id.textView1);
            textView1 = view.findViewById(R.id.textView2);
            button = view.findViewById(R.id.button);
            textView.setText(song.Title);
            textView1.setText(song.Author);
            button.setOnClickListener(v -> {
                if ( button.getText().equals("STOP")){
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    button.setText("PLAY");
                }
                else   {
                    mediaPlayer = new MediaPlayer();
                    try {
                        Log.v("MainActivity.this",song.songUrl);
                        mediaPlayer.setDataSource(song.songUrl);
                        // After this line it throws an error if I remove requestLegacyStorage from manifest
//                        Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied) -- this is the error
                        mediaPlayer.prepare();
                        mediaPlayer.start();
                        button.setText("STOP");

                    }catch (Exception e){
                        Toast.makeText(getApplicationContext(), "Error in playingSong", Toast.LENGTH_SHORT).show();
                    }
                }
            });
            return view;
        }
    }
}




song_info.java
public class song_info {
    String Title = null;
    String Author = null;
    String songUrl = null;

    public song_info(String title, String author, String songUrl) {
        Title = title;
        Author = author;
        this.songUrl = songUrl;
    }
}

共有1个答案

程禄
2023-03-14

如果您的targetSdk不是30,您可以继续使用该标志Android:RequestLegacyExternalStorage=“true”,您不必做任何事情。但是开发人员应该在11月达到targetSdk=30。
我分享了来自谷歌的答案:

“您可以在5月5日之后继续使用requestLegacyExternalStorage,因为您的目标不是Android 11。您不需要在5月5日之前做任何事情。”

在我们的应用程序中,targetSdk=29,我们使用RequestLegacyExternalStorage。如果你处于同样的状况,你现在不必做任何事情。

 类似资料:
  • 问题内容: 操作系统 :debian 8.0.0-amd64,ubuntu-15.04,16.04 码头工人 :1.xx 程序: 我更改为添加一个私有Docker注册表,然后重新启动了docker服务,最后尝试提取一些映像。 一个输出显示一无所知DOCKER_OPTS环境变种。 题: 根据Docker文档,使用私有注册表的方式是通过中的DOCKER_OPTS进行。为什么这样做之后在这种环境下不生效

  • 当我在Google Play上提出我的应用程序时,这向我展示了问题 您的应用程序当前以API级别25为目标,并且必须至少以API级别26为目标,以确保其基于针对安全性和性能优化的最新API构建。将应用程序的目标API级别更改为至少26 注意,我使用Unity 您已将sdk更新为最新版本 请帮助我如何在Unity中将API级别更改为至少26 谢啦

  • 问题内容: 使用JNA的文档说: 使目标库可用于Java程序。有两种方法可以执行此操作:首选方法是将系统属性设置为目标库的路径。此属性类似于但仅适用于JNA加载的库。 这到底是什么意思?如何设置系统属性?我的应用程序需要参考 谢谢 问题答案: 在命令行上调用Java虚拟机时,可以使用参数“ -D”来设置系统属性: 当从例如配置文件中读取代码时,也可以在应用程序启动时在代码中以编程方式进行设置: 我

  • 我有一个作为字符串接收的HTML文档,然后使用jSoup解析它。此HTML文档(字符串形式)包含

  • 我收到了一个用于为嵌入式linux设备构建c /c应用程序的SDK。这对我来说都是新的,所以我的一些术语可能是错误的。 我按照他们的指示和SDK安装在我的linux(ubuntu)系统在 /opt/.他们使用的编译器似乎是arm-poky-linux-gnueabi-gcc。SDK的一部分设置了一些环境变量,如用于编译C/C的$CC和CPP。环境变量运行类似arm-poky-linux-gnuea

  • 是否可以使用JavaFX更改应用程序图标,还是必须使用Swing来完成?