42872


ファイルを作成しようとしていますが、Permission deniedとなり、作成が出来ません。  
ディレクトリを作成する場合mkdir（下記のコードではmkdirの必要が生じなくなっています）で、そこを通過してもファイルを作成する段階（createNewFile）でエラーになります。

デバック機器のOSはOreoVersionです。

ManifestやAppのストレージ権限と、考えられる権限は与えています。  
しかし、「アクセス拒否」となってしまいます。

参考書や複数のホームページ等を参考にしつつ、最低限必要そうな手は打っているつもりです。

どうして書き込みが出来ないのでしょうか？  
書き込みが出来ない現象において、ほかに確認・改善すべき箇所があるのでしょうか？  
ご指導のほど、よろしくお願いいたします。

Manifestに次の記述もしています。

[code]

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
[/code]

ソースコード

[code]

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //パーミッションチェック
            checkPermission();
    
            //FileAccessTest
            FileSave();
            FileLoad();
        }
    
        // この定数は0以上の値をアプリ内で適当に決めて良い
        private final int EXTERNAL_STORAGE_REQUEST_CODE = 1;
    
        // Permissionの確認
        @TargetApi(Build.VERSION_CODES.M)
        public void checkPermission() {
            // 既に許可している
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED) {
                return;
            }
            // 許可していない場合、パーミッションの取得を行う
            // 以前拒否されている場合は、なぜ必要かを通知し、手動で許可してもらう
            if (!shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                Toast.makeText(this, "ファイル書き込みのために許可してください", Toast.LENGTH_SHORT).show();
            }
            // パーミッションの取得を依頼
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_REQUEST_CODE);
        }
    }
    
    public class FileAccess {
        private static final String FILE_NAME = "test.xml";
        //書き出し
        public static boolean FileSave(){
            Boolean fRef = false;
            DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
    
            try {
                DocumentBuilder dbuilder = dbfactory.newDocumentBuilder();
                Document document = dbuilder.newDocument();
                Element root = document.createElement("Test");
                Element child = document.createElement("Item");
    
                //test
                Text text = document.createTextNode(String.valueOf("TestData"));
                child.appendChild(text);
    
                root.appendChild(child);
                document.appendChild(root);
    
                TransformerFactory tffactory = TransformerFactory.newInstance();
                Transformer transformer = tffactory.newTransformer();
                String path = Environment.getExternalStorageDirectory().toString();
                File dir = new File(path);
    
                if(!dir.exists()){
                    dir.mkdir();
                }
    
                File file = new File(path + "/" + FILE_NAME);
    
                if(!file.exists()){
                    file.createNewFile();　 //これがエラー
                }
    
                transformer.transform(new DOMSource(document), new StreamResult(file));
                //書き込み終了のメッセージ
                fRef = true;
            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }catch (TransformerConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (TransformerException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
            return fRef;
        }
    
        //読み込み
        public static boolean FileLoad() {
    
            try {
                String path = Environment.getExternalStorageDirectory().toString();
                File dir = new File(path);
                //File file = new File(path + "/" + FILE_NAME);
    
                String listXmlPath = path + "/" + FILE_NAME;
                String content = new Scanner(new File(listXmlPath)).useDelimiter("\\z").next();
                //XMLファイルをまとめて読み込み
                XmlPullParser xpp = Xml.newPullParser();
    
                xpp.setInput(new StringReader(content));
                //解析するXMLファイルの中身を渡す
                int eventType = xpp.getEventType();
                int element = 0;
    
                while(eventType != XmlPullParser.END_DOCUMENT){
                    switch(eventType){
                        case XmlPullParser.START_DOCUMENT:
                            Log.i("MainActivity", "ドキュメント開始");
                            break;
                        case XmlPullParser.START_TAG:
                            Log.i("MainActivity", xpp.getName() + "要素開始");
                            int attrCount = xpp.getAttributeCount();
    
                            for(int i = 0; i < attrCount; ++i){
                                Log.i("MainActivity", "    " +
                                    i + "番目の属性 = " + xpp.getAttributeName(i));
                            }
                            break;
                        case XmlPullParser.TEXT:
                            Log.i("MainActivity", "テキスト = (" + element + ") " + xpp.getText());
                            element = 0;
                            break;
                        case XmlPullParser.END_TAG:
                            Log.i("MainActivity", xpp.getName() + "要素終了");
                            break;
                    }
                    eventType = xpp.next();
                    //次のトークンに進む
                }
    
                Log.i("MainActivity", "ドキュメント終了");
            } catch (XmlPullParserException e) {
                Log.e("MainActivity", "XMLの解析失敗.");
            }catch(IOException e){
                Log.e("MainActivity", "XMLファイルの読み込みに失敗.");
            }
        return true;
        }
    }
    
[/code]


CC BY-SA 3.0
2018-04-02T01:07:07.797
42853
2018-04-02T12:21:12.167
2018-04-02T03:59:46.017
10845
10845
question
android java
Androidでストレージへのファイルの書き込みが出来ない（アクセス拒否）


`requestPermissions()` を呼ぶと、ユーザにダイアログが表示され、処理は一旦返ってきます。

この時点ではまだ権限がないので、アクセスできません。

ユーザがダイアログで選択すると、`onRequestPermissionsResult()`
が呼ばれますので、許可されたことを確認し、それ以降にアクセスしてください。

具体的には、以下のようになると思います。

  * `MainActivity` に implements を追加。
[code]     public class MainActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback {

    
[/code]

  * `onCreate()` 内からは `FileSave();`, `FileLoad();` を削除。

  * `onRequestPermissionsResult()` を実装。
[code]     @Override

    public void onRequestPermissionsResult(int requestCode,
            String[] permissions,
            int[] grantResults) {
        if (requestCode == EXTERNAL_STORAGE_REQUEST_CODE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 許可された。
                FileSave();
                FileLoad();
            }
        }
    }
    
[/code]

* * *

書き込みができないのは、read 権限しかリクエストしていないからだと思います。  
以下のような感じでいかがでしょう?

  * 権限のチェックを修正
[code]     if
(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)==
PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)==
PackageManager.PERMISSION_GRANTED) {

        return;
    }
    
[/code]

  * リクエストを修正
[code]     requestPermissions(new
String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_REQUEST_CODE);

    
[/code]

  * リクエストの結果確認を修正
[code]     if (grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED) {

    
[/code]


CC BY-SA 3.0
2018-04-02T10:38:23.900
42872
2018-04-02T12:21:12.167
2018-04-02T12:21:12.167
5288
5288
42853
answer