Android 7.1.1无法在外部存储中创建文件或文件夹。 FileNotFoundException异常

时间:2017-09-05 19:57:33

标签: java android xml file

我正在尝试捕获文本文件中的传感器数据,我可以从“外部存储”中提取该文件。当我通过USB将它连接到PC时,我可以通过python脚本运行文本文件以进行绘图。我还没有实现传感器部件,因为我无法创建可以在创建后从手机复制到PC的文件。

我尝试创建一个文件夹并且它不会创建文件夹,我也尝试创建一个文件,它也会失败,然后它会抛出一个文件不存在的异常。我无所畏惧,因为我已将权限添加到清单文件中,如下所示。有什么我想念的吗?我已经做了很多搜索,似乎没有解决我的问题,并且developer.android.com网站没有解释任何关于添加我已经添加到清单文件中的行之外的权限。

我没有SD卡,所以使用SD卡不是解决我的问题的方法

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mike.project_final">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_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=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>


        </activity>
    </application>

    </manifest>

这是我到目前为止完成的整个代码,它抛出了错误。

    package com.example.mike.project_final;

    import android.content.Context;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.hardware.Sensor;
    import android.view.View;
    import android.widget.TextView;

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.PrintWriter;

    public class MainActivity extends AppCompatActivity implements SensorEventListener {



TextView xTV, yTV, zTV, writeTV;
SensorManager sManager;
Sensor sAccelerometer;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    xTV = (TextView) findViewById(R.id.xTV);
    yTV = (TextView) findViewById(R.id.yTV);
    zTV = (TextView) findViewById(R.id.zTV);
    writeTV = (TextView) findViewById(R.id.writeTV);
}

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

public void createFile(View view) {

    File root = android.os.Environment.getExternalStorageDirectory();
    File dir = new File (root.getAbsolutePath() + "/project_test");
    if (!dir.exists()){
        dir.mkdir();
        xTV.setText("Created");
    }
    else{
        xTV.setText("Exists");
    }
    File file = new File(dir, "myData.txt");

    try {
        FileOutputStream f = new FileOutputStream(file);
        PrintWriter pw = new PrintWriter(f);
        pw.println("Hi , How are you");
        pw.println("Hello");
        pw.flush();
        pw.close();
        f.close();
    } catch (Exception e) {
        writeTV.setText(e.toString());
    }
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy){
    //do nothing
}
@Override
public void onSensorChanged(SensorEvent event) {

}
}

如果需要,任何有关如何设置其余权限的帮助都将非常感谢!

编辑1: 权限问题已经解决了,谢谢。我现在有一个问题,我创建的文件夹不会创建为文件夹,而是创建为文件,如下图所示。我究竟做错了什么? https://i.imgur.com/srKXJc1g.png 很遗憾,我没有足够的声誉来发布图片。

1 个答案:

答案 0 :(得分:0)

我的回答有点晚了,但希望对您有所帮助。 从android 6开始,您需要在运行时在App中向用户请求权限,然后才能允许您的App修改外部存储。 (因为它被归类为“危险许可”。请阅读文档以了解更多https://developer.android.com/guide/topics/permissions/overview#permission-groups。)

那么您如何请求权限?好了,在这种情况下的代码类似于下面的代码(请在此处https://developer.android.com/training/permissions/requesting#java进行阅读以更好地理解);

 private final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 2;

 public checkWritePermissionAndCreateFile(){
 // Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // Permission is not granted
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
            } else {
                // No explanation needed; request the permission
                ActivityCompat.requestPermissions(thisActivity,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);

                // MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        } else {
            // Permission has already been granted
            // Carry out functionality that you needed permission for 
             createFile();                  
        }

@Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted
                createFile();
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission. 
            }
            return;
        }
        // other 'case' lines to check for other
        // permissions this app might request.
    }

}

}