我正在创建一个可以在设备的存储设备上写入数据( .txt,.csv )的应用。尽管我已在我的 AndroidManifest.xml 中授予了权限,但我仍然出现错误 permission denied
。我需要从设备(而不是文件浏览器)访问此数据,以使其他应用程序与之交互。
步骤1:我已授予在我的 AndroidManifest.xml 上写内容的权限。
步骤2:我创建了一个函数,用于从Fragment的OnCreateView方法中写入数据。
步骤3:我创建了文件并将其保存到设备的Downlads文件夹中。
我的第一个版本将数据保存在我的 本地应用程序目录 中。我可以通过Android Studio文件浏览器在 data / data / com.example.myapp 中找到保存的文件。但是它没有出现在我的设备上(我在模拟器和真实设备上找不到最近保存的文件)。
然后,我了解到无法从设备访问本地文件夹。我试图将目录更改为 下载 。在这种情况下,我的权限被拒绝,并且文件未保存(应保存在 storage / emulated / 0 / Downloads 中)。
我尝试添加读取权限,将我的API级别更改为24,更改目录路径...,但始终是相同的错误。
我的AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
我的函数写为:
File textFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "litchi_mission.csv");
try {
FileOutputStream fos = new FileOutputStream(textFile);
fos.write("this is a test".getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
下载文件夹的路径:
File textFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "litchi_mission.csv");
错误:
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Download/litchi_mission.csv (Permission denied)
W/System.err: at java.io.FileOutputStream.open(Native Method)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
我解决了这个错误。
步骤1:我在OnCreateView方法中添加了一个测试:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Add your own code
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
}
}
第2步:然后,我在片段末尾写了一个权限方法:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch(requestCode){
case 1000:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "Permission granted!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Permission denied!", Toast.LENGTH_LONG).show();
finish();
}
}
}
第3步:我将 write 方法更改为:
// Write and save file
// You can change the ArrayList<Point> to a string, I am just converting this list to a string here
private void saveTextAsFile(String filename, ArrayList<Point> listInter){
String fileName = filename + ".csv";
//create file
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
//write file
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write((Litchi.litchiHeader() + "\n").getBytes());
for (int i = 0; i < listInter.size(); i++){
Litchi point = new Litchi(listInter.get(i));
fos.write((point.toString() + "\n").getBytes());
}
fos.close();
Toast.makeText(getActivity(), "Litchi mission saved to :\n" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
步骤4:最后但并非最不重要的一点是,我在OnCreateView方法中调用了上一个方法:
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
// some code
saveTextAsFile("litchi_mission", listInter);
}