permissions - Android 6 - Writing to external storage fails ON FIRST RUN ONLY -
i know question asked several times problem different. need write data external storage. know need ask permissions @ runtime on android 6. works fine far. 1 thing weird. granted permission seems work the second time start app.
my example looks this:
@override public void onrequestpermissionsresult(int requestcode, string[] permissions, int[] grantresults) { super.onrequestpermissionsresult(requestcode, permissions, grantresults); switch (requestcode) { case request_write_storage: { if (grantresults.length > 0 && grantresults[0] == packagemanager.permission_granted) { log.d(tag, "permission granted!"); write(); } else { log.d(tag, "no permission granted!"); } } } } @override public void onclick(view v) { boolean haspermission = (contextcompat.checkselfpermission(this, manifest.permission.write_external_storage) == packagemanager.permission_granted); if (!haspermission) { log.d(tag, "has no permission! ask!"); activitycompat.requestpermissions(this, new string[]{manifest.permission.write_external_storage}, request_write_storage); } else { log.d(tag, "permission given!"); write(); } } private void write(){ log.d(tag, "trying write"); // directory user's public pictures directory. file root = new file(environment.getexternalstoragepublicdirectory(environment.directory_pictures), "test"); if (! root.exists() && !root.mkdirs()) { log.e(tag, "directory not created"); return; } file testfile = new file(root, "test.tmp"); filewriter writer; try { stringbuilder sb = new stringbuilder(); sb.append("test test test"); writer = new filewriter(testfile, false); writer.append(sb.tostring()); writer.flush(); writer.close(); } catch (ioexception e) { e.printstacktrace(); } log.d(tag, "write successful"); }
pressing button calls onclick()
checking permissions. if granted calls write()
method - if not asks permission.
so when pressing button first time, permission popup opens, click "yes" , assumed, write test file. still, following error message , file or directory not created:
d/log: has no permission! ask! d/log: permission granted! d/log: trying write e/log: directory not created
if click again (with given permission) shows
d/log: permission given! d/log: trying write e/log: directory not created
in fact neither directory nor file exist yet. close app , start again , press button. console shows this:
d/log: permission given! d/log: trying write d/log: write successful
voila, now directory , file exist.
so why work second time start app? appears permissions refreshed on app start. ideas?
---- edit ----
related comment, separated exists()
, mkdirs()
.
still method looks this:
private void write(){ log.d(tag, "trying write"); // directory user's public pictures directory. file root = new file(environment.getexternalstoragepublicdirectory(environment.directory_pictures), "test"); if (! root.exists()){ if(!root.mkdirs()) { log.e(tag, "directory not created"); return; } else { log.e(tag, "directory created"); } } ...
still, first time app starts directory not created. next time start app, directory created. doesn't seem problem.
also, added method checking if environment.getexternalstoragepublicdirectory(environment.directory_pictures)
exists. 1 true, @ first start. whats failing mkdirs()
sub folder.
as posted here: https://stackoverflow.com/a/37135078/1565635 believe found solution - or @ least explanation.
it turns out seems bigger issue. changing permission write external storage changes linux gid process. in order change id process has restarted. next time app opens, new groupid set , permission granted. leads conclusion this not bug in fact bigger issue linux , android.
i "solved" asking permission first time app executed , restarting when permission given this:
packagemanager packagemanager = getpackagemanager(); intent intent = packagemanager.getlaunchintentforpackage(getpackagename()); componentname componentname = intent.getcomponent(); intent mainintent = intentcompat.makerestartactivitytask(componentname); startactivity(mainintent); system.exit(0);
a solution didn't try create service running in background (thus having process id) , giving permission. way service needs restarted not complete app. on down side might make more work communication between processes. if understand right, content provider might work, means more work.
--- edit ---
the user m66b (https://stackoverflow.com/a/32473449/1565635) found list of related gids. further information can found here: https://android.googlesource.com/platform/frameworks/base/+/master/data/etc/platform.xml
Comments
Post a Comment