Cannot save pdf files after updating my phone to Android 11 - android

In one of my activities, I save an image in my App's directory subfolder and in the next activity I read the .png file and include it in a pdf file with some other data and save it in my App's directory, Everything worked fine until I updated my phone from Android 10 to 11. Now I get this error:
E/main: error java.io.FileNotFoundException: /storage/emulated/0/IranianMasonryBuildings/sjdnnd -- Fri Feb 12 11:49:36 GMT+03:30 2021.pdf: open failed: EPERM (Operation not permitted)
I tried many fixes online but none of them seem to work.
My manifest includes theses permissions and also the requestLegacyExternalStorage = true
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
android:requestLegacyExternalStorage="true"
compileSdkVersion and targetSdkVersion are set to 29, I tried to change the API level to 28 as mentioned in some answers to other questions but did not work.
This is how I try to create the pdf file:
private boolean isExternalStorageWritable(){
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
Log.i("State", "Yes, it is writable");
return true;
}else{
return false;
}
}
public boolean checkPermission(String permission){
int check = ContextCompat.checkSelfPermission(this, permission);
return (check == PackageManager.PERMISSION_GRANTED);
}
public void checkPermission(String permission, int requestCode)
{
if (ContextCompat.checkSelfPermission(Results.this, permission)
== PackageManager.PERMISSION_DENIED) {
// Requesting the permission
ActivityCompat.requestPermissions(Results.this,
new String[] { permission },
requestCode);
}
else {
/*Toast.makeText(Results.this,
"Permission already granted",
Toast.LENGTH_SHORT)
.show();*/
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == STORAGE_PERMISSION_CODE){
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/*Toast.makeText(Results.this,
"Storage Permission Granted",
Toast.LENGTH_SHORT)
.show();*/
}
else {
Toast.makeText(Results.this,
"Please grant access",
Toast.LENGTH_SHORT)
.show();
}
}
}
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
public void writeExternalStorage (){
String state;
state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) &&
checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
try {
//File storageDir2 = new File(Environment.getExternalStorageDirectory().toString(),
"/IranianMasonryBuildings/BluePrints");
File storageDir2 = new File(Environment.getExternalStorageDirectory().toString(),
"/IranianMasonryBuildings");
File f = new File(storageDir2, "BluePrint213.png");
Bitmap blueprint2 = BitmapFactory.decodeStream(new FileInputStream(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
PdfDocument myPdfDocument = new PdfDocument();
Paint myPaint = new Paint();
// Create a page description
PdfDocument.PageInfo myPageInfo1 = new PdfDocument.PageInfo.Builder(PageWidth,
PageHeight, PageNumber).create();
// start a page
PdfDocument.Page myPage1 = myPdfDocument.startPage(myPageInfo1);
Canvas canvas = myPage1.getCanvas();
myPaint = new Paint();
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(3);
canvas.drawRect(200, 250, 1900, 2600, myPaint);
myPdfDocument.finishPage(myPage1);
File storageDir = new File(Environment.getExternalStorageDirectory().toString(),
"/IranianMasonryBuildings");
storageDir.mkdirs(); // make sure you call mkdirs() and not mkdir()
boolean wasSuccessful = storageDir.mkdirs();
if (!wasSuccessful) {
//Toast.makeText(getApplicationContext(), "mkdirs was not Successful ",
Toast.LENGTH_LONG).show();
}
File file2 = new File(storageDir, ProjectName + " -- " + Today + ".pdf");
try {
myPdfDocument.writeTo(new FileOutputStream(file2));
Toast.makeText(this, "The results are saved in" + "IranianMasonryBuildings",
Toast.LENGTH_LONG).show();
} catch (IOException e) {
Log.e("main", "error " + e.toString());
Toast.makeText(this, "Error!" + e.toString(), Toast.LENGTH_LONG).show();
}
// close the document
myPdfDocument.close();
Any ideas what is causing the problem and how to fix?

Android 11 (API level 30) further enhances the platform, giving better protection to app and user data on external storage. This release introduces several enhancements, such as opt-in raw file path access for media, batch edit operations for media, and an updated UI for the Storage Access Framework.
Follow this link
https://developer.android.com/about/versions/11/privacy/storage

Related

open failed: EACCES (Permission denied) on first run

I'm trying to write/read a file into the external storage after requesting all permissions on runtime.
Manifest:
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
Runtime:
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE.
JavaCode:
public class FilesUtil {
public static String saveImageToFile(Bitmap image ,String employeeId){
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/AppName");
myDir.mkdirs();
String filename = String.format("EMPLOYEE_%s.png", employeeId);
File file = new File (myDir, filename);
if (file.exists()){
file.delete(); // here i'm checking if file exists and if yes then i'm deleting it but its not working
}
FileOutputStream out = null;
try {
out = new FileOutputStream(file,false);
image.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return filename;
}
public static String getImagePath(String employeeId){
String result = Environment.getExternalStorageDirectory().toString() + "/AppName/";
String filename = String.format("EMPLOYEE_%s.png", employeeId);
return result + filename;
}
}
Load File:
private Bitmap getCurrentPhoto() {
File image = new File(FilesUtil.getImagePath(getCurrentEmployeeId()));
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(), bmOptions);
return bitmap;
}
The first time that I run the app I get an open failed: EACCES (Permission denied) just on Android 6.0.1, However, in other versions of the Operative system, the feature is working fine. If I kill and Reopen the app on 6.0.1, the feature is working fine.
There is a bug on Android 6.0, the permissions are not being applied until all the application processes are killed. In other versions of the operating system when there is a change in the permissions settings, the App is Killed automatically and restarted from last Activity.
I avoid the bug using this on onRequestPermissionsResult and Restart the App.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length == permissions.length){
if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.restart_message)
.setPositiveButton(R.string.restart_button, (dialog, id) -> {
restartApp();
});
builder.create().show();
}
}
}

Permission denied but I have permission access

I already put a permission access on my manifest still not saving. I tried this yesterday and its saving my image and now I cant. I dont know what is the problem here. logcat says java.io.IOException: open failed: EACCES (Permission denied)
below is the code
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout content = (RelativeLayout) findViewById(R.id.dashBoard);
content.setDrawingCacheEnabled(true);
Bitmap bitmap = content.getDrawingCache();
File file = new File(Environment.getExternalStorageDirectory().getPath()+ imagename+ ".png");
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
content.invalidate();
Toast.makeText(getApplicationContext(), "SAVED", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
} finally {
content.setDrawingCacheEnabled(false);
}
}
});
here is the full logcat
https://www.dropbox.com/s/dlb6p5i1nd1kxua/Logcat.txt?dl=0
You need use real time permission after SDK API 23 required.
You can ask permission like this code.
if (Build.VERSION.SDK_INT >= 23) {
if (checkWritePermission()) {
// your code
} else {
requestStoragePermission();
}
} else {
// your code
}
You need to check permission and request put this method.
private boolean checkWritePermission() {
int result = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestStoragePermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(MainActivity.this, "EXTERNAL STORAGE permission allows us to save image/video. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_STORAGE_REQUEST_CODE);
}
}
Use onRequestPermissionsResult method for handle permission result
Don't forget to put permission on manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

tess-two won't initialise, even with correct permissions

Here's what I'm currently doing:
tess-two is set up in my Android project
I have permissions specified in the AndroidManifest.xml of my main app (not the tess-two AndroidManifest.xml):
I also check for permissions explicitly in my code:
int readPermission = ActivityCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE);
int writePermission = ActivityCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE);
// Check we have both read and write permissions
if (readPermission != PackageManager.PERMISSION_GRANTED
|| writePermission != PackageManager.PERMISSION_GRANTED)
{
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
this,
new String[] {READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE},
REQUEST_EXTERNAL_STORAGE
);
}
else
{
Log.d(TAG, "Read and write external permissions granted");
initTess();
}
Try to initialise the TessBaseAPI:
private void initTess()
{
// Check we have the eng.traineddata file in the correct place
mTessDataPath = getFilesDir() + "/tesseract/";
checkTessFile(new File(mTessDataPath + "tessdata/"));
// Initialise TessBaseAPI
mTess = new TessBaseAPI();
mTess.init(mTessDataPath, "eng");
}
private void checkTessFile(File dir)
{
// Check if directory already exists
if (dir.exists())
{
// Check if file already exists
String dataFilePath = mTessDataPath + "tessdata/eng.traineddata";
File datafile = new File(dataFilePath);
if (!datafile.exists())
{
// If file doesn't exist, copy it over from assets folder
copyTessFiles();
}
}
else
{
if (dir.mkdirs())
{
// If directory doesn't exist, but we can create it, copy file from assets folder
copyTessFiles();
}
}
}
private void copyTessFiles()
{
try
{
// Location we want the file to be at
String filepath = mTessDataPath + "tessdata/eng.traineddata";
// Get access to AssetManager
AssetManager assetManager = getAssets();
// Open byte streams for reading/writing
InputStream instream = assetManager.open("tessdata/eng.traineddata");
OutputStream outstream = new FileOutputStream(filepath);
// Copy the file to the location specified by filepath
byte[] buffer = new byte[1024];
int read;
while ((read = instream.read(buffer)) != -1)
{
outstream.write(buffer, 0, read);
}
outstream.flush();
outstream.close();
instream.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch (requestCode)
{
case REQUEST_EXTERNAL_STORAGE:
{
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
// Initialise Tesseract API
initTess();
}
return;
}
}
}
When I run the app, I get the following error in my logs:
E/Tesseract(native): Could not initialize Tesseract API with language=eng!
I have no idea where to go from here, so any help or advise would be hugely appreciated, thank you :)
Make sure you're using the right version of the training data files.

Image Save to SdCard for 6.0.1 Android Version

This code works correctly under 6.0.1 android version but if i run this application on 6.0.1 android devices , it will not save images to sd card.
What i need to update for 6.0.1 devices ?
public void SaveImages(int a ,String b)
{
Bitmap bitmap = null;
OutputStream output;
if(a==0)
{
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.image_0);
}
File filepath = Environment.getExternalStorageDirectory();
// Create a new folder in SD Card
File dir = new File(filepath.getAbsolutePath()
+ "/Wallpapers/");
dir.mkdirs();
// Create a name for the saved image
File file = new File(dir,b);
// Show a toast message on successful save
Toast.makeText(FullImageActivity.this, "Loading...",
Toast.LENGTH_SHORT).show();
Toast.makeText(FullImageActivity.this, "Image Saved to SD Card",
Toast.LENGTH_SHORT).show();
try {
output = new FileOutputStream(file);
// Compress into png format image from 0% - 100%
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
output.flush();
output.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
On Android 6.0+, you need to request runtime permission to write to external storage.
In order to request runtime permission to write to external storage:
public class MarshmallowPermission {
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2;
public MarshmallowPermission() {
}
public boolean checkPermissionForExternalStorage(Activity activity) {
if(Build.VERSION.SDK_INT >= 23) {
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
} else {
return true;
}
}
public void requestPermissionForExternalStorage(Activity activity) {
if(ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(activity,
"External Storage permission needed. Please allow in App Settings for additional functionality.",
Toast.LENGTH_LONG).show();
// user has previously denied runtime permission to external storage
} else {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
}
Then you can do
if(!marshmallowPermission.checkPermissionForExternalStorage(this)) {
marshmallowPermission.requestPermissionForExternalStorage(this);
} else {
// can write to external
}
And
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == MarshmallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE) {
if(marshmallowPermission.checkPermissionForExternalStorage(this)) {
// can write to external
} else {
// runtime permission denied, user must enable permission manually
}
}
}
Refer the following link,
How to save the image to SD card on button Click android. and
Saving image from image view to sd card : Android.
For detailed tutorial,
http://www.android-examples.com/save-store-image-to-external-storage-android-example-tutorial/

mhtml file not loading/displaying properly in webview for lollipop and marshmallow but on pre-lollipop devices

I have a .mhtml file in my database as byte array. I have written below code and its working fine in pre-lollipop devices. But it is not working on lollipop and marshmallow.
Code:-
String path = filepath.getAbsolutePath()+"/StudyWellAppv5/"+fname;
byte[] bytes = tblK.gethtmlFile();
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
webview.loadUrl("file://" + path);
}
catch(Exception e){ e.printStackTrace();}
Runtime permission code:-
/Permission to read and write from external storage
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
int permission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readpermission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED||readpermission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
getActivity(),
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
Error Log :-
"Blocked script execution in 'file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.", source: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml (1618)
06-16 13:48:42.571 1244-1244/com.samji.StudyWellAppv5 I/chromium: [INFO:CONSOLE(1618)] "Blocked script execution in 'file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.", source: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml (1618)
06-16 13:48:42.598 1244-1244/com.samji.StudyWellAppv5 I/chromium: [INFO:CONSOLE(0)] "Not allowed to load local resource: file:///C:/EC2C4CD1/1_files/image002.jpg", source: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml (0)
06-16 13:48:42.599 1244-1244/com.samji.StudyWellAppv5 I/chromium: [INFO:CONSOLE(0)] "Not allowed to load local resource: file:///C:/EC2C4CD1/1_files/image004.jpg", source: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml (0)
06-16 13:48:42.599 1244-1244/com.samji.StudyWellAppv5 I/chromium: [INFO:CONSOLE(0)] "Not allowed to load local resource: file:///C:/EC2C4CD1/1_files/image006.jpg", source: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml (0)
06-16 13:48:42.671 1244-1244/com.samji.StudyWellAppv5 I/chromium: [INFO:CONSOLE(0)] "Not allowed to load local resource: file:///C:/EC2C4CD1/1_files/image008.jpg", source: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml (0)
06-16 13:49:10.182 1244-1244/com.samji.StudyWellAppv5 I/chromium: [INFO:CONSOLE(0)] "Not allowed to load local resource: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml", source: file:///storage/emulated/0/StudyWellApp/2016-06-16%2001-48-42.mhtml (0)
Note:-This code is working perfectly on pre-lollipop devices. It is not working only on lollipop and marshmallow.
You have to get runtime permission for API 23 (marshmallow)
Example Code:
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_RUNTIME_PERMISSION = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//SomeStuffWhichNeedPermission(); dont call here directly wihtout permission in 6.0 do like below
checkPremission();
}
void SomeStuffWhichNeedPermission() {
// storing data code here now
String path = filepath.getAbsolutePath() + "/StudyWellAppv5/" + fname;
byte[] bytes = tblK.gethtmlFile();
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
webview.loadUrl("file://" + path);
} catch (Exception e) {
e.printStackTrace();
}
}
void checkPremission() {
//select which permission you want
final String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
// if in fragment use getActivity()
if (ContextCompat.checkSelfPermission(ActivityName.this, permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(ActivityName.this, permission)) {
} else {
ActivityCompat.requestPermissions(ActivityName.this, new String[]{permission}, REQUEST_CAMERA_PERMISSION);
}
} else {
// you have permission go ahead
SomeStuffWhichNeedPermission();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_RUNTIME_PERMISSION:
final int numOfRequest = grantResults.length;
final boolean isGranted = numOfRequest == 1
&& PackageManager.PERMISSION_GRANTED == grantResults[numOfRequest - 1];
if (isGranted) {
// you have permission go ahead
SomeStuffWhichNeedPermission();
} else {
// you dont have permission show toast
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}

Categories

Resources