Я создаю приложение, в котором хочу прочитать данные из внешнего хранилища (то есть получить список файлов и папок, похожих на проводник). Я написал код, который отлично работает на реальном устройстве, но в эмуляторе android только дает путь и имя внешнего хранилища из
Environment.getExternalStorageDirectory()
Но когда я пытаюсь перечислить файлы и папки с помощью функции file.listFiles () в java, он возвращает ноль, даже если в нем есть папки и файлы Этот каталог прекрасно работает на реальном устройстве, я дал разрешение и все, я хочу, чтобы он работал на эмуляторе, потому что у меня не всегда есть доступ к устройству android. Я использую его на процессоре amd с включенной функцией hyper-v на windows
Это мои данные эмулятора
Name: Pixel_2_API_R
CPU/ABI: Google Play Intel Atom (x86)
Path: C:\Users\Rohan\.android\avd\Pixel_2_API_R.avd
Target: google_apis_playstore [Google Play] (API level R)
Skin: pixel_2
SD Card: 512M
fastboot.chosenSnapshotFile: runtime.network.speed: full
hw.accelerometer: yes
hw.device.name: pixel_2
hw.lcd.width: 1080
image.androidVersion.codename: R
hw.initialOrientation: Portrait
image.androidVersion.api: 29
tag.id: google_apis_playstore
hw.mainKeys: no
hw.camera.front: emulated
avd.ini.displayname: Pixel 2 API R
hw.gpu.mode: auto
hw.ramSize: 1536
PlayStore.enabled: true
fastboot.forceColdBoot: no
hw.cpu.ncore: 4
hw.keyboard: yes
hw.sensors.proximity: yes
hw.dPad: no
hw.lcd.height: 1920
vm.heapSize: 256
skin.dynamic: yes
hw.device.manufacturer: Google
hw.gps: yes
hw.audioInput: yes
image.sysdir.1: system-images\android-R\google_apis_playstore\x86\
showDeviceFrame: yes
hw.camera.back: virtualscene
AvdId: Pixel_2_API_R
hw.lcd.density: 420
hw.arc: false
hw.device.hash2: MD5:55acbc835978f326788ed66a5cd4c9a7
fastboot.forceChosenSnapshotBoot: no
fastboot.forceFastBoot: yes
hw.trackBall: no
hw.battery: yes
hw.sdCard: yes
tag.display: Google Play
runtime.network.latency: none
disk.dataPartition.size: 6442450944
hw.sensors.orientation: yes
avd.ini.encoding: UTF-8
hw.gpu.enabled: yes
Это мой код (отлично работает на реальном устройстве)
package com.example.instantshare.UI.Activities;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.StatFs;
import com.example.instantshare.R;
import com.example.instantshare.UI.Models.FileItem;
import com.example.instantshare.UI.UIComponents.FileListRecyclerViewAdapter;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
public class FilePickerActivity extends AppCompatActivity {
private static final String TAG = "FilePickerActivity";
private final int REQUEST_CODE = 1;
private static final ArrayList<FileItem> list = new ArrayList<>();
private static Context context;
private static String headerPath = ""; // Holds the string shown in the header which contains the current path the user is viewing
private static String actualPath = ""; // Holds the file path (Not shown to user)
private static String currentFolder = "";
private static int folderState = 0; // Holds how much directories the user has clicked on if (1) taken to selection of internal storage and sd card
// View variables
static RecyclerView fileListRecyclerView;
static TextView folderNameTextView,filePathTextView;
static LinearLayout filePathHolder;
static Animation fadeUp,fadeInLeft,fadeOutRight,fadeIn;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_picker);
init();
StatFs statfs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
Log.d(TAG, "onCreate: " + (statfs.getAvailableBytes() / 100000));
}
}
// Called initially to link all the ui and load all the variables
private void init(){
fileListRecyclerView = findViewById(R.id.file_list_recycler_view);
filePathTextView = findViewById(R.id.file_path_text_view);
folderNameTextView = findViewById(R.id.folder_name_text_view);
filePathHolder = findViewById(R.id.file_path_linear_layout);
fadeUp = AnimationUtils.loadAnimation(this,R.anim.fade_up);
fadeInLeft = AnimationUtils.loadAnimation(this,R.anim.fade_in_left);
fadeOutRight = AnimationUtils.loadAnimation(this,R.anim.fade_out_right);
fadeIn = AnimationUtils.loadAnimation(this,R.anim.fade_in);
context = FilePickerActivity.this;
if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_EXTERNAL_STORAGE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
}
}
}
else {
readFileInit();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_CODE:
{
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
readFileInit();
}
else{
finish();
}
}
}
}
// Code to show Internal storage and sd card if mounted
private void readFileInit(){
headerPath = "";
actualPath = "";
currentFolder = "";
list.clear();
FileItem internalStorage = new FileItem("Internal Storage","","internal_storage","internal_storage", Environment.getExternalStorageDirectory().getAbsolutePath(),"",true,false,false);
list.add(internalStorage);
filePathTextView.setText(headerPath);
folderNameTextView.setText(currentFolder);
try {
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){
File storage = Environment.getExternalStorageDirectory();
FileItem externalStorage = new FileItem(storage.getName(),"","external_storage","external_storage", storage.getAbsolutePath(),"",true,false,false);
Log.d(TAG, "readFileInit: " + externalStorage.getPath());
list.add(externalStorage);
}
}
catch (Exception e){
e.printStackTrace();
}
Log.d(TAG, "readFileInit: " + list.toString());
setupRecyclerView(list);
fileListRecyclerView.startAnimation(fadeUp);
}
public static void clickedItem(FileItem fileItem){
if (fileItem.getStorage() || fileItem.getDirectory()){
currentFolder =fileItem.getName();
folderState++;
headerPath = headerPath.trim();
headerPath += fileItem.getName() + "/";
if (fileItem.getName().equals("Internal Storage") || fileItem.getName().toLowerCase().equals("sdcard") ){
actualPath += fileItem.getPath() + "/";
}
else{
actualPath += fileItem.getName() + "/";
}
filePathTextView.setText(headerPath);
filePathTextView.startAnimation(fadeUp);
folderNameTextView.setText(currentFolder);
folderNameTextView.startAnimation(fadeUp);
File directory = new File(actualPath);
Log.d(TAG, "clickedItem: Path: " + fileItem.getPath() + "/");
File[] files = directory.listFiles();
Log.d(TAG, "clickedItem: " + Arrays.toString(files));
list.clear();
try {
if(files != null){
for(int i = 0; i < files.length; i++){
FileItem list_item = new FileItem();
File file = files[i];
Log.d(TAG, "clickedItem: " + file.getName());
list_item.setName(file.getName());
list_item.setDirectory(file.isDirectory());
list_item.setFile(file.isFile());
list_item.setStorage(false);
String[] date = new Date(file.lastModified()).toString().split(" ");
String dateToSet = date[1] + " " + date[2] + " " + date[0] + " " + date[5];
list_item.setLastModified(dateToSet);
list_item.setPath(file.getAbsolutePath());
if(file.isDirectory()){
list_item.setExtension("");
}
else{
if(file.getName().contains(".")){
String[] splittedValue = file.getName().split("\\.");
Log.d(TAG, "clickedItem: 1 " + Arrays.toString(splittedValue));
list_item.setExtension(splittedValue[splittedValue.length - 1]);
}
else{
list_item.setExtension(file.getName());
}
}
list_item.setType(getFileType());
list.add(list_item);
}
}
setupRecyclerView(list);
fileListRecyclerView.startAnimation(fadeIn);
}
catch (Exception e){
e.printStackTrace();
}
}
else{
return;
}
}
private static String getFileType(){
return "";
}
@Override
public void onBackPressed() {
Log.d(TAG, "onBackPressed: " + folderState);
if(folderState > 1){
folderState--;
renderView();
}
else if(folderState == 1){
readFileInit();
folderState--;
}
else{
super.onBackPressed();
}
}
private static void renderView(){
String[] newPathArr = headerPath.split(">",-1);
String[] newPathArr1 = actualPath.split("/",-1);
headerPath = "";
actualPath = "";
currentFolder="";
Log.d(TAG, "renderView: " + Arrays.toString(newPathArr));
Log.d(TAG, "renderView: " + Arrays.toString(newPathArr1));
for(int i = 0; i < newPathArr.length - 2; i++){
headerPath += newPathArr[i] + "/";
if(i == newPathArr.length - 3){
currentFolder = newPathArr[i];
}
}
for (int i = 0; i < newPathArr1.length - 2; i++){
actualPath += newPathArr1[i] + "/";
}
Log.d(TAG, "renderView: " + actualPath);
File file = new File(actualPath);
filePathTextView.setText(headerPath);
filePathTextView.startAnimation(fadeUp);
folderNameTextView.setText(currentFolder);
folderNameTextView.startAnimation(fadeUp);
File[] files = file.listFiles();
list.clear();
try {
if(files != null){
for(int i = 0; i < files.length; i++){
FileItem list_item = new FileItem();
File file1 = files[i];
Log.d(TAG, "clickedItem: " + file.getName());
list_item.setName(file1.getName());
if (folderState == 0){
list_item.setStorage(true);
list_item.setDirectory(false);
list_item.setFile(false);
}
else{
list_item.setDirectory(file1.isDirectory());
list_item.setFile(file1.isFile());
list_item.setStorage(false);
}
String[] date = new Date(file1.lastModified()).toString().split(" ");
String dateToSet = date[1] + " " + date[2] + " " + date[0] + " " + date[5];
list_item.setLastModified(dateToSet);
list_item.setPath(file.getAbsolutePath());
if(file.isDirectory()){
list_item.setExtension("");
}
else{
if(file.getName().contains(".")){
String[] splittedValue = file.getName().split("\\.");
Log.d(TAG, "clickedItem: 1 " + Arrays.toString(splittedValue));
list_item.setExtension(splittedValue[splittedValue.length - 1]);
}
else{
list_item.setExtension(file.getName());
}
}
list_item.setType(getFileType());
list.add(list_item);
}
}
setupRecyclerView(list);
fileListRecyclerView.startAnimation(fadeIn);
}
catch (Exception e){
e.printStackTrace();
}
}
private static void setupRecyclerView(ArrayList<FileItem> list){
FileListRecyclerViewAdapter fileListRecyclerViewAdapter = new FileListRecyclerViewAdapter(context,list);
fileListRecyclerView.setAdapter(fileListRecyclerViewAdapter);
fileListRecyclerView.setLayoutManager(new GridLayoutManager(context,3));
}
}
AndroidManifest. xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.instantshare">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".UI.Activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".UI.Activities.FilePickerActivity"></activity>
</application>
</manifest>