In my app i want to get user permission to read and write data on external storage, i have put permission tag in my manifest as below. When installing the app for the first time it works. It asks for permission and the save of the files is working. If I unistall the app and reinstall it without any changes on the code the saving does not work! The files that I want to be saved from the app to the device are on the Assets folder. On a few questions here I read about runtime permissions! I was not able to find a way to add this on my code. Can anyone help me on how to add it on my code in order to make it functionable?
My manisfest is the below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hcghelp">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.MANAGE_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/Theme.HCGHelp">
<activity android:name=".NP_all"></activity>
<activity android:name=".GKL18_pre" />
<activity android:name=".GKL17_in" />
<activity android:name=".GKL17_pre" />
<activity android:name=".GKL16_in" />
<activity android:name=".GKL14_in" />
<activity android:name=".GKL10_in" />
<activity android:name=".GKL16_pre" />
<activity android:name=".GKL14_pre" />
<activity android:name=".GKL10_pre" />
<activity android:name=".GKL07_in" />
<activity android:name=".GKL07_pre" />
<activity android:name=".GKL02_in" />
<activity android:name=".GKL02_pre" />
<activity android:name=".GKL01_pre" />
<activity android:name=".GKL01_in" />
<activity android:name=".GKL_all" />
<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>
My code is the below:
public class GKL10_pre extends AppCompatActivity {
private Button button1;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gkl10_pre);
button1 = (Button) findViewById(R.id.B_GKL10_KEIMENO);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { opengkl10_pk();
}
});
button = (Button) findViewById(R.id.B_GKL10_FILES);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
copyAsset("file1.pdf");
copyAsset("file2.pdf");
copyAsset("file3.pdf");
copyAsset("file4.pdf");
}
});
}
private void copyAsset(String filename){
String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download";
File dir = new File(dirPath);
if(!dir.exists()) {
dir.mkdirs();
}
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(dirPath, filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
Toast.makeText(this, "Saved!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Failed!", Toast.LENGTH_SHORT).show();
} finally {
if(in != null){
try {
in.close();
} catch (IOException e){
e.printStackTrace();
}
}
if(out != null){
try {
out.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
When I run the debug I am getting the below for every file
W/System.err: at libcore.io.IoBridge.open(IoBridge.java:492)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
W/System.err: at com.example.hcghelp.GKL10_pre.copyAsset(GKL10_pre.java:84)
W/System.err: at com.example.hcghelp.GKL10_pre.access$000(GKL10_pre.java:28)
W/System.err: at com.example.hcghelp.GKL10_pre$2.onClick(GKL10_pre.java:56)
W/System.err: at android.view.View.performClick(View.java:7448)
W/System.err: at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
W/System.err: at android.view.View.performClickInternal(View.java:7425)
W/System.err: at android.view.View.access$3600(View.java:810)
W/System.err: at android.view.View$PerformClick.run(View.java:28305)
W/System.err: at android.os.Handler.handleCallback(Handler.java:938)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err: at android.os.Looper.loop(Looper.java:223)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7656)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
W/System.err: at libcore.io.Linux.open(Native Method)
W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err: at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7542)
W/System.err: at libcore.io.IoBridge.open(IoBridge.java:478)
W/System.err: ... 17 more
D/CompatibilityChangeReporter: Compat change id reported: 147798919; UID 10157; state: ENABLED```