Android 6.0写入外部SD卡
我试着在Android 6.0上的外部SD卡上写东西,但我不能在上面写 我对stackoverflow进行了研究,发现了很多东西,但都不管用。这是我的密码Android 6.0写入外部SD卡,android,android-6.0-marshmallow,android-permissions,Android,Android 6.0 Marshmallow,Android Permissions,我试着在Android 6.0上的外部SD卡上写东西,但我不能在上面写 我对stackoverflow进行了研究,发现了很多东西,但都不管用。这是我的密码 String extPath = System.getenv("SECONDARY_STORAGE") + "/Android/data/com.gvm.externalstorage.externalstoragetest/"; File file = new File(extPath,"myFiles"); if
String extPath = System.getenv("SECONDARY_STORAGE") + "/Android/data/com.gvm.externalstorage.externalstoragetest/";
File file = new File(extPath,"myFiles");
if (!file.exists()) {
boolean dirResult = file.mkdirs();
Log.e("Directory Exist", dirResult + " Directory created");
} else {
Log.e("Directory Exist", "Exist");
Log.e("Direcotry Path",file.getAbsolutePath());
}
//String displayname = fileName.replace("%20", " ");
File outputFile = new File(file, "mytest5.txt");
outputFile.createNewFile();
此代码适用于Android 5.0,但不适用于Android 6.0
然后我也尝试了这个路径,这给了我权限错误,我已经为运行时权限设置了所有权限和托管代码
/mnt/media_rw/6AC9-083B
File write failed: java.io.IOException: open failed: EACCES (Permission denied)
如果有人能帮助我,这将是伟大的,因为我正在尝试这一点,因为过去3天
谢谢,
Anvesh从API 23+(6.0)您需要请求读/写权限,即使它们已经在您的清单(称为)中
来自文档
从Android 6.0(API级别23)开始,用户向
应用程序运行时,而不是安装应用程序时。这
这种方法简化了应用程序安装过程,因为用户不需要
安装或更新应用程序时需要授予权限。它也
让用户能够更好地控制应用程序的功能;例如
用户可以选择让摄像头应用程序访问摄像头,但不允许
到设备位置。用户可以随时撤销权限
时间,转到应用程序的设置屏幕
java
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
从API 23+(6.0)中,您需要请求读/写权限,即使这些权限已经存在于您的清单(称为)中
来自文档
从Android 6.0(API级别23)开始,用户向
应用程序运行时,而不是安装应用程序时。这
这种方法简化了应用程序安装过程,因为用户不需要
安装或更新应用程序时需要授予权限。它也
让用户能够更好地控制应用程序的功能;例如
用户可以选择让摄像头应用程序访问摄像头,但不允许
到设备位置。用户可以随时撤销权限
时间,转到应用程序的设置屏幕
java
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
我认为你应该首先检查你的应用程序权限,以确保你的存储权限已打开 如果没有存储权限: 请检查您是否在AndroidManifest中使用此权限
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
致以最良好的祝愿。我希望这能帮助你我认为你应该首先检查你的应用程序权限,以确保你的存储权限已打开 如果没有存储权限: 请检查您是否在AndroidManifest中使用此权限
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
致以最良好的祝愿。我希望这能对你有所帮助。经过长期的努力,我找到了一个解决办法。在Android 6.0中,它不会始终使用以下命令为您提供SD卡路径:
System.getenv("SECONDARY_STORAGE")
还是这个
Environment.getExternalStorageDirectory()
所以我用这个来检索外部SD卡路径
File[] fs = context.getExternalFilesDirs(null);
String extPath = "";
// at index 0 you have the internal storage and at index 1 the real external...
if (fs != null && fs.length >= 2)
{
extPath = fs[1].getAbsolutePath();
Log.e("SD Path",fs[1].getAbsolutePath());
}
其余的一切将保持不变,以供许可和所有
感谢那些帮助我的人 经过长时间的努力,我想出了一个解决办法。在Android 6.0中,它不会始终使用以下命令为您提供SD卡路径:
System.getenv("SECONDARY_STORAGE")
还是这个
Environment.getExternalStorageDirectory()
所以我用这个来检索外部SD卡路径
File[] fs = context.getExternalFilesDirs(null);
String extPath = "";
// at index 0 you have the internal storage and at index 1 the real external...
if (fs != null && fs.length >= 2)
{
extPath = fs[1].getAbsolutePath();
Log.e("SD Path",fs[1].getAbsolutePath());
}
其余的一切将保持不变,以供许可和所有
感谢那些帮助我的人 @Anvesh我正在使用的另一种可靠方法:
/**
* Get external storage path use reflect on android 6.0 device.
* Source code:
* https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/storage/StorageVolume.java
*
* @param removable the sdcard can remove or not, true means external sdcard, false means
* internal sdcard.
* @return path of sdcard we want
*/
public static String getStoragePath(boolean removable) {
WinZipApplication application = WinZipApplication.getInstance();
Context mContext = application.getApplicationContext();
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean mRemovable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (removable == mRemovable) {
return path;
}
}
} catch (Exception e) {
return null;
}
return null;
}
/**
*获取外部存储路径使用android 6.0设备上的反射。
*源代码:
* https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/storage/StorageVolume.java
*
*@param removable SD卡是否可以移除,true表示外部SD卡,false表示外部SD卡
*内部SD卡。
*@我们想要的SD卡的返回路径
*/
公共静态字符串getStoragePath(布尔可移动){
WinZipApplication application=WinZipApplication.getInstance();
Context mContext=application.getApplicationContext();
StorageManager mStorageManager=(StorageManager)mContext.getSystemService(Context.STORAGE\u服务);
类storageVolumeClazz=null;
试一试{
storageVolumeClazz=Class.forName(“android.os.storage.StorageVolume”);
方法getVolumeList=mStorageManager.getClass().getMethod(“getVolumeList”);
方法getPath=storageVolumeClazz.getMethod(“getPath”);
方法isRemovable=storageVolumeClazz.getMethod(“isRemovable”);
对象结果=getVolumeList.invoke(MSTorAgerManager);
最终整数长度=Array.getLength(结果);
for(int i=0;i
@Anvesh我正在使用的另一种可靠方法:
/**
* Get external storage path use reflect on android 6.0 device.
* Source code:
* https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/storage/StorageVolume.java
*
* @param removable the sdcard can remove or not, true means external sdcard, false means
* internal sdcard.
* @return path of sdcard we want
*/
public static String getStoragePath(boolean removable) {
WinZipApplication application = WinZipApplication.getInstance();
Context mContext = application.getApplicationContext();
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean mRemovable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (removable == mRemovable) {
return path;
}
}
} catch (Exception e) {
return null;
}
return null;
}
/**
*获取外部存储路径使用android 6.0设备上的反射。
*源代码:
* https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/storage/StorageVolume.java
*
*@param removable SD卡是否可以移除,true表示外部SD卡,false表示外部SD卡
*内部SD卡。
*@我们想要的SD卡的返回路径
*/
公共静态字符串getStoragePath(布尔可移动){
WinZipApplication application=WinZipApplication.getInstance();
Context mContext=application.getApplicationContext();
StorageManager mStorageManager=(StorageManager)mContext.getSystemService(Context.STORAGE\u服务);
类storageVolumeClazz=null;
试一试{
storageVolumeClazz=Class.forName(“android.os.storage.StorageVolume”);
方法getVolumeList=mStorageManager.getClass().getMethod(“getVolumeList”);
方法getPath=storageVolumeClazz.getMethod(“getPath”);
方法isRemovable=storageVolumeClazz.getMethod(“isRemovable”);
对象结果=GetVolume