I know about the runtime permissions and I've taken that into consideration but it still doesn't work. I have added these lines to manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
this is my onCreate method:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new);
if (shouldAskPermissions()) {
askPermissions();
}
generateNoteOnSD(this,fileName,msg);
readFile(fileName);
}
this is for asking and granting permission
protected static boolean shouldAskPermissions() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}
@TargetApi(23)
protected void askPermissions() {
String[] permissions = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
};
/* int requestCode = 200;
requestPermissions(permissions, requestCode);*/
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
this, permissions, 1);
}
}
and these are the writing and reading methods
public static void generateNoteOnSD(Context context, String sFileName, String sBody) {
try {
File root = new File(String.valueOf(Environment.getExternalStorageDirectory()));
Log.e("file path is ", String.valueOf(Environment.getExternalStorageDirectory()));
if (!root.exists()) {
root.mkdirs();
}
File gpxfile = new File(root, sFileName);
String separator = System.getProperty("line.separator");
FileWriter writer = new FileWriter(gpxfile.getAbsoluteFile(), true);
writer.append(separator); // this will add new line ;
//FileWriter writer = new FileWriter(gpxfile);
writer.append(sBody);
writer.flush();
writer.close();
Toast.makeText(context, "Saved", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void readFile(String file1){
//Find the directory for the SD Card using the API
//*Don't* hardcode "/sdcard"
File sdcard = Environment.getExternalStorageDirectory();
//Get the text file
File file = new File(sdcard,file1);
//Read text from file
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {
//You'll need to add proper error handling here
}
//Find the view by its id
Log.e("text",text.toString());
}
EDIT This is my stacktrace:
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/CrowdSensingData: open failed: EACCES (Permission denied)
W/System.err: at libcore.io.IoBridge.open(IoBridge.java:487)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
W/System.err: at java.io.FileWriter.<init>(FileWriter.java:58)
W/System.err: at enis.example.com.alarmmanagertest.FileAndServerHandlingActivity.generateNoteOnSD(FileAndServerHandlingActivity.java:128)
W/System.err: at enis.example.com.alarmmanagertest.ActivityRecognitionService.handleDetectedActivities(ActivityRecognitionService.java:107)
W/System.err: at enis.example.com.alarmmanagertest.ActivityRecognitionService.onStart(ActivityRecognitionService.java:122)
W/System.err: at android.app.Service.onStartCommand(Service.java:459)
W/System.err: at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3209)
W/System.err: at android.app.ActivityThread.-wrap17(ActivityThread.java)
W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1586)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:111)
W/System.err: at android.os.Looper.loop(Looper.java:207)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5728)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
W/System.err: at libcore.io.Posix.open(Native Method)
W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
W/System.err: at libcore.io.IoBridge.open(IoBridge.java:473)
If the permissions are not granted yet you should not call methods which need them immediately. Call them in onRequestPermissionsResult instead. This guarantees that they only get executed as soon as the permissions are granted by the user.
if (shouldAskPermissions()) {
askPermissions();
} else {
generateNoteOnSD(this,fileName,msg);
readFile(fileName);
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
generateNoteOnSD(this,fileName,msg);
readFile(fileName);
}
}
}
}
Edit: Furthermore, include ContextCompat.checkSelfPermission in your shouldAskPermissions() method.
Edit 2: Here's an implementation for shouldAskPermissions()
protected boolean shouldAskPermissions() {
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
return false;
}
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
return (permission != PackageManager.PERMISSION_GRANTED);
}