无法使用 Java 读取 mp3 文件 Android
Can't read mp3 files Android using Java
这是MainActivity.java:
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Dexter.withContext(this)
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
ArrayList<File> songs = fetchSongs(Environment.getExternalStorageDirectory());
String[] items = new String [songs.size()];
for (int i = 0; i < songs.size(); i++) {
items[i] = songs.get(i).getName().replace(".mp3", "");
}
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, items);
ListView listView = findViewById(R.id.listView);
listView.setAdapter(adapter);
}
@Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
permissionToken.continuePermissionRequest();
}
})
.check();
}
public ArrayList<File> fetchSongs (File file) {
ArrayList arrayList = new ArrayList();
File [] songs = file.listFiles();
if (songs != null) {
for (File song : songs) {
if (song.isDirectory() && !song.isHidden()) {
arrayList.addAll(fetchSongs(song));
} else {
if (song.getName().endsWith(".mp3") && !song.getName().startsWith(".")) {
arrayList.add(song);
}
}
}
}
return arrayList;
}
}
仅供参考,我 运行 在具有 Android 10.
的物理设备上执行此操作
public ArrayList<File> fetchSongs (File file)
函数中的 'file' 参数不为 null 并且是一个目录但在同一个函数中如果我 运行 file.listFiles()
那 returns null .
我下载了两个 mp3 文件。
我的 AndroidManifest.xml 文件已声明读取外部存储的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
我不知道这是否仅在您的设备上有 if (if (songs != null)songs != null) 外部 SD 卡时才有效,但我 运行 在我的设备自己的存储空间。
编辑:当我 运行 在另一个具有 Android 9 的物理设备上时,它 运行 完美。
非常感谢任何帮助。
谢谢
尝试将此添加到 AndroidManifest.xml 中的 <application>
标记内:
android:requestLegacyExternalStorage="true"
在 Android 10 及更高版本中,他们改变了外部存储的工作方式(分区存储),此代码片段允许您恢复到旧存储 APIs 以便拥有完整的访问外部存储
更新:对于 Android 11 及更高版本,使用 MediaStore API 或使用 getExternalFilesDirs()
作为您应用程序的特定目录(请注意,您需要移动歌曲从外部存储目录到应用程序特定目录),应用程序特定目录如下:
Android/data/com.companyname.appname
但为了 Android 10(API 级别 29)兼容性,如果级别为 30 或更高(Android 11 及更高)然后使用 getExternalFilesDirs()
,否则使用传统存储 APIs
这是MainActivity.java:
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Dexter.withContext(this)
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
ArrayList<File> songs = fetchSongs(Environment.getExternalStorageDirectory());
String[] items = new String [songs.size()];
for (int i = 0; i < songs.size(); i++) {
items[i] = songs.get(i).getName().replace(".mp3", "");
}
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, items);
ListView listView = findViewById(R.id.listView);
listView.setAdapter(adapter);
}
@Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
permissionToken.continuePermissionRequest();
}
})
.check();
}
public ArrayList<File> fetchSongs (File file) {
ArrayList arrayList = new ArrayList();
File [] songs = file.listFiles();
if (songs != null) {
for (File song : songs) {
if (song.isDirectory() && !song.isHidden()) {
arrayList.addAll(fetchSongs(song));
} else {
if (song.getName().endsWith(".mp3") && !song.getName().startsWith(".")) {
arrayList.add(song);
}
}
}
}
return arrayList;
}
}
仅供参考,我 运行 在具有 Android 10.
的物理设备上执行此操作public ArrayList<File> fetchSongs (File file)
函数中的 'file' 参数不为 null 并且是一个目录但在同一个函数中如果我 运行 file.listFiles()
那 returns null .
我下载了两个 mp3 文件。
我的 AndroidManifest.xml 文件已声明读取外部存储的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
我不知道这是否仅在您的设备上有 if (if (songs != null)songs != null) 外部 SD 卡时才有效,但我 运行 在我的设备自己的存储空间。
编辑:当我 运行 在另一个具有 Android 9 的物理设备上时,它 运行 完美。
非常感谢任何帮助。 谢谢
尝试将此添加到 AndroidManifest.xml 中的 <application>
标记内:
android:requestLegacyExternalStorage="true"
在 Android 10 及更高版本中,他们改变了外部存储的工作方式(分区存储),此代码片段允许您恢复到旧存储 APIs 以便拥有完整的访问外部存储
更新:对于 Android 11 及更高版本,使用 MediaStore API 或使用 getExternalFilesDirs()
作为您应用程序的特定目录(请注意,您需要移动歌曲从外部存储目录到应用程序特定目录),应用程序特定目录如下:
Android/data/com.companyname.appname
但为了 Android 10(API 级别 29)兼容性,如果级别为 30 或更高(Android 11 及更高)然后使用 getExternalFilesDirs()
,否则使用传统存储 APIs