質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.98%

androidstudioでEACCES (Permission denied)というエラー

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 4,173

arama

score 9

androidstudioを使っていて、加速度をファイルに保存したいというのが本題で以下のようにコードを書いたのですが
open failed: EACCES (Permission denied)
といわれてしまいました。
どうすればよいでしょうか。
一応調べて以下のようにはmanifestには書いてあります。
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

</manifest>

該当のソースコード

public class MainActivity extends Activity implements SensorEventListener {

private SensorManager manager;
private TextView values;
//textview初期化
TextView x_textView;
TextView y_textView;
TextView z_textView;
//加速度
double acc_x;
double acc_y;
double acc_z;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
x_textView =  (TextView)findViewById(R.id.xtext);
y_textView = (TextView)findViewById(R.id.ytext);
z_textView = (TextView)findViewById(R.id.ztext);
manager.registerListener(this,manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_FASTEST);
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
// Listenerの登録解除
manager.unregisterListener(this);
}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// Listenerの登録
List<Sensor> sensors = manager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if(sensors.size() > 0) {
Sensor s = sensors.get(0);
manager.registerListener(this, s, SensorManager.SENSOR_DELAY_UI);
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}

@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
//加速度取得
acc_x = event.values[SensorManager.DATA_X];
acc_y = event.values[SensorManager.DATA_Y];
acc_z = event.values[SensorManager.DATA_Z];
//加速度表示 PC
System.out.println("x=" + acc_x);
System.out.println("y=" + acc_y);
System.out.println("z=" + acc_z);
//加速度表示 recon
x_textView.setText("x=" + String.valueOf(acc_x));
y_textView.setText("y=" + String.valueOf(acc_y));
z_textView.setText("z=" + String.valueOf(acc_z));

try {
//出力先を作成する
FileWriter fw = new FileWriter("Environment.getExternalStorageDirectory().getPath()+\"test.csv", false);  //※1
PrintWriter pw = new PrintWriter(new BufferedWriter(fw));

//内容を指定する
pw.print("あああ");
pw.print(",");
pw.print("いいい");
pw.print(",");
pw.print("ううう");
pw.println();

pw.print("001");
pw.print(",");
pw.print("002");
pw.print(",");
pw.print("003");
pw.println();

//ファイルに書き出す
pw.close();

//終了メッセージを画面に出力する
System.out.println("出力が完了しました。");

} catch (IOException ex) {
//例外時処理
System.out.println("出力に失敗しました。");
ex.printStackTrace();
}

}

}

試したこと

課題に対してアプローチしたことを記載してください

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

コンパイルに用いているSDK(compileSdkVersion)がAPI 23(Android 6.0)以上ならば、Runtime Permissionという仕組みによって、アプリ実行時に機能へのアクセス許可を得なければ、その機能を利用することができないようになりました。ストレージの読み書きもこの対象に含まれています。AndroidManifest.xmlへのuses-permissionの記述は引き続き必要ですが、それに加えて処理が必要になったということです。

最近のAndroidアプリで、例えばカメラを使おうとしたときに「xxxに写真の撮影と動画の記録を許可しますか」のようなダイアログが出てくる場面に出会ったことがあるでしょう。あれを自分で実装しなければならないということです。

下記サイトで詳しく説明されているので、一読してはどうかと思います。
https://techbooster.org/android/application/17223/

簡易的に実装するなら、こんな感じになろうかと思います。

    private static final int REQUEST_EXTERNAL_STORAGE_CODE = 0x01;
    private static String[] mPermissions = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };

    private static void verifyStoragePermissions(Activity activity) {
        int readPermission = ContextCompat.checkSelfPermission(activity, mPermissions[0]);
        int writePermission = ContextCompat.checkSelfPermission(activity, mPermissions[1]);

        if (writePermission != PackageManager.PERMISSION_GRANTED ||
                readPermission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    activity,
                    mPermissions,
                    REQUEST_EXTERNAL_STORAGE_CODE
            );
        }
    }

読み書きを行うタイミングで

verifyStoragePermissions(this);

のようにして呼び出せば、その時点で一度も許可を得たことがなければ、許可を求めるダイアログが出ます。二度目以降は(Androidの設定画面で権限を不許可に設定しない限りは)出てきません。

余談ですが、AndroidアプリでSystem.out.println()を用いても、端末の画面には表示は行われません。これはどういう意図で用いたのでしょうか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/15 18:08

    わかりやすい説明ありがとうございます!
    出来ました。ありがとうございました。
    System.out.println()はreconjetで開発をしているのですが、自分はメガネをかけているのでreconjetをかけてoutputを見る手間を省くためにやっています。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る