I want to delete a picture from gallery or photo apps from device according to its URI. I tried several approach around internet but no way found.
I called below method
deleteMethod(getPath(selectedImageUri));
These two method defination is here.
private void deleteMethod(String file_dj_path) {
File fdelete = new File(file_dj_path);
if (fdelete.exists()) {
if (fdelete.delete()) {
System.out.println("file Deleted :" + file_dj_path);
Toast.makeText(getApplicationContext(),
"file Deleted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),
"file not Deleted", Toast.LENGTH_SHORT).show();
System.out.println("file not Deleted :" + file_dj_path);
}
}
}
public String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
if (cursor != null) {
//HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
//THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else return null;
}
I add permission in manifest. Like,
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
My provider looks like:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path path="Android/data/com.***.calculator/"
name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
i got uri like this:
:/storage/emulated/0/DCIM/Camera/IMG_20180804_181447.jpg
Am i missing anything?
Update:
I added runtime permission before run the code. After i run the code it always goes "file not Deleted" consists else block.
You also need to check if you have the permission and if not acquire it on RUNTIME. Asking for the permissions in your manifest file is not enough. You could use these two methods to see if you have permission to write and if not acquire it:
protected boolean checkPermission() {
int result1 = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result1 == PackageManager.PERMISSION_GRANTED ) {
return true;
} else {
return false;
}
}
protected void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "Write External Storage permission allows us to do store images. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
}
}
Change like this
String path = selectedImageUri.getPath()
deleteMethod(path);
then deleteMethod inside
File file = new File(new URI(path));
if (fdelete.exists()) {
if (fdelete.delete()) {
System.out.println("file Deleted :" + uri.getPath());
} else {
System.out.println("file not Deleted :" + uri.getPath());
}
}
Well, since you say you also take the permission to write on runtime, perhaps you should use the setWritable() method after you have established the file exists and before trying to delete it.
After Android 6.0, some permissions are granted at runtime. You can use this code.
also, check https://developer.android.com/about/versions/marshmallow/android-6.0-changes
public boolean hasStoragePermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission error");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
Following is a code I currently use to delete a downloaded apk programmatically.
final File file = new File(Environment.getExternalStorageDirectory().toString() + "/" + giftapk);
if (file.exists()) {
if (file.delete()) {
System.out.println("file Deleted :" + file);
} else {
System.out.println("file not Deleted :" + file);
}
}
Related
I have build sample app for user to write some text and save it on internal storage.
Format TXT or pdf. I have tried on android Kitkat sdk 19 and It's working fine but when I tried on the latest android 9 I got denied could not save the text in internal storage
Edit : I wonder If have to manually create My files folder
What I'm I missing ?
AndroidManifest
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSaveTextBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
mText = mResultEt.getText().toString().trim();
if(mText.isEmpty()){
Toast.makeText(MainActivity.this, "write text First...", Toast.LENGTH_SHORT).show();
}
else{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED){
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions,WRITE_EXTERNAL_STORAGE_CODE);
}else {
saveToTxtFile(mText);
}
}else {
saveToTxtFile(mText);
}
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case WRITE_EXTERNAL_STORAGE_CODE: {
if (grantResults.length > 0 && grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
//permission granted save data
saveToTxtFile(mText);
} else {
//permission denied
Toast.makeText(this, "Storage Permission required to store", Toast.LENGTH_SHORT).show();
}
}
break;
}
}
private void saveToTxtFile(String mText){
//get current time for file name
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(System.currentTimeMillis());
try{
//path tp storage
File path = Environment.getExternalStorageDirectory();
//create folder named "My file"
File dir = new File( path + "/My Files/");
dir.mkdirs();
//file name
String fileName = "MyFile_" + timestamp + ".txt";
File file = new File (dir, fileName);
//used to store characater in file
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(mText);
bw.close();
//show file name and path where file saved
Toast.makeText(this, fileName+"is saved to\n" +dir, Toast.LENGTH_SHORT).show();
}catch (Exception e){
//if anything goes wrong
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
As suggested both Shashanth and kashyap answers.
This is just a workaround but it works.
I have added
android:requestLegacyExternalStorage="true"
to my <application> element in the AndroidManifest.xml file.
And changed the line
File path = Environment.getExternalStorageDirectory();
to
File path = new File(getExternalFilesDir(null).getAbsolutePath());
In your MainActivity you should check if permission is granted or not, then use != operator.
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {}
this line should be-
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){}
I had an issue with my app. To use an option, I need to grant the external storage access. I found the perfect code for this there :
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
Source : Storage permission error in Marshmallow
The problem is, the code is perfectly working but I do not understand how to prevent my own codes to continuing if access is not granted (or wait for the user to click on "allow" before continuing my codes).
My codes :
isStoragePermissionGranted();
File outputFile = new File("");
InputStream is = getResources().openRawResource(((Sound) adapter.getItem(index)).getMpsound());
try {
byte[] buffer = new byte[is.available()];
is.read(buffer);
File outputDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
outputFile = new File(outputDir, getResources().getResourceEntryName(((Sound) adapter.getItem(index)).getMpsound()) + ".mp3");
OutputStream os = new FileOutputStream(outputFile);
os.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("audio/*");
share.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", outputFile));
share.putExtra(Intent.EXTRA_TEXT, "\"" + ((Sound) adapter.getItem(index)).getTitre_show() + "\" shared by my app !");
startActivity(Intent.createChooser(share, "Share Sound File"));
return true;
For now, everything is executed and the app try to share the file even is the access is not granted. So it doesn't work. And if I go back, the popup asking to allow access is there, waiting for an answer.
How can I achieve this ?
Changing this line
isStoragePermissionGranted();
into this should work.
if(isStoragePermissionGranted())
I am trying to store a String to a file which should be stored on the device
I have the following code that stores the String into a variable called exportstring:
final JSONArray jsonArray1 = jsonArray;
JSONObject export = jsonArray1.getJSONObject(index);
String exportString = export.toString();
writeToFile(exportString);
I then have a function called writeToFile
private void writeToFile(String content) {
try {
File file = new File(Environment.getExternalStorageDirectory() + "/test.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter writer = new FileWriter(file);
writer.append(content);
writer.flush();
writer.close();
} catch (IOException e) {
}
}
when I run it, I get a message coming up saying "The file was saved"
but when I open a file manager, I do not see it anywhere.
where is the file saved to?
or have I done something wrong here?
To store the file in Downloads folder, change:
File file = new File(Environment.getExternalStorageDirectory() + "/test.txt");
to:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/test.txt");
UPDATE: Before trying to save the file you should make sure you have the required permissions, in this case the permission to write to storage. Below is a short example of how to do that:
protected boolean checkPermission() {
int result1 = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result1 == PackageManager.PERMISSION_GRANTED ) {
return true;
} else {
return false;
}
}
protected void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "Write External Storage permission allows us to do store files. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 100:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("permissionCheck", "Permission Granted, do what you want to do when user grants the permission here!!!");
} else {
Log.d("permissionCheck", "Permission Denied, do what you want to do when user denies the permission here...");
}
break;
}
}
Include the code above to your activity (or any activity before the one you currently are at) and before trying to store the string to the file do the following:
if(!checkPermission()){
Log.d("permissionCheck", "Need to get the permissions");
requestPermission();
}else{
Log.d("permissionCheck", "Already have the permissions");
}
To see the logs in logcat :
I am coding an Android app (in Java) which uses OCR to convert handwriting into digital text. I am trying to take the String generated by the OCR function in my code and write it to a text file (the OCR portion is currently working). I would then like to create a folder (in phone's external storage, for example My Files on Samsung) and add the text file to this folder, which contains only the files the user has created (which the user should be able to access and share).
I have conducted some research on writing to phone's external storage (including other StackOverflow questions) but no tutorial has worked for me.
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
public File writeFolder ()
{
File file = null;
if (isExternalStorageWritable())
{
// Get the directory for the user's public directory.
file = new File(Environment.getExternalStorageDirectory() + File.separator + "OCR Documents");
}
if (!file.mkdirs())
Log.e(LOG_TAG, "Directory not created");
else
System.out.println(file.getAbsolutePath());
return file;
}
The code above is what I have, however after testing it, the AbsolutePath is null. It does not seem to be creating a folder on the phone's external storage. How would I go about this so that a folder is created and I can add files to that folder?
Your code to create the directory is fine.
But there's a chance you're missing permissions due to newer versions of Android requiring a User's consent before you can write files to the external storage.
First, make sure you have this permission in your Manifest.xml:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Afterwards, since WRITE_EXTERNAL_STORAGE is listed as a Dangerous Permission, as seen here: https://developer.android.com/guide/topics/permissions/overview#normal-dangerous , you'll also need to explicitly request the permission from the user.
Finally, to request the permission:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed; request the permission
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
}
You'll also need to handle the response of the request:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
The above code was copied from: https://developer.android.com/training/permissions/requesting
You should read that link more thoroughly since it provides a good explanation of what you need to explain to the user, since users are typically very wary when Apps ask for permissions to modify files in their storage.
You can try this,
private void getWirtePermissionAndCreateDir() {
if (Build.VERSION.SDK_INT < 23) {
createDir();
} else {
final String[] PERMISSIONS_STORAGE = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//Asking request Permissions
ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, 9);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
boolean writeAccepted = false;
switch (requestCode) {
case 9:
writeAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (writeAccepted) {
createDir();
} else {
Toast.makeText(MainActivity.this, "You don't assign permission.", Toast.LENGTH_LONG).show();
}
}
private void createDir(){
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "OCR Documents");
file.mkdirs();
Toast.makeText(MainActivity.this, file.getAbsolutePath(), Toast.LENGTH_LONG).show();
}
You have to add getWirtePermissionAndCreateDir() instead of writeFolder() in activity body.
Below function will create folder and then create file in that folder and if folder already exists then simply create file.
private FileOutputStream fos;
//Function: create a file in a folder
private boolean createFileInFolder(String fileName, String folderName) {
if (isExternalStorageWritable()) {
String path = Environment.getExternalStorageDirectory() + "/" + folderName;
File folder = new File(path);
if (!folder.exists()) {
folder.mkdirs();
}
txtFile = new File(path, fileName);
try {
fos = new FileOutputStream(txtFile);
return true;
} catch (IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
}
} else
return false;
}
//Function: IsExternalStorageWritable?
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
You may need to check permissions so also define these functions.
private boolean permission;
private final int MY_PERMISSIONS_REQUEST = 10;
//Function: checkPermission
private void checkPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST);
} else {
permission = true;
}
}
//Function: Permission Request Results
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
permission = true;
} else {
permission = false;
}
return;
}
}
}
In your manifest file don't forget to add this line.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I am using this code in async to create directory if not exists in android with permissions. My code sucessfully works in android 5.1 but when i deployed app in android 7.0 the directory not created automatically
File sdcard = Environment.getExternalStorageDirectory() ;
File folder = new File(sdcard.getAbsoluteFile(), "Quoteimages");
if(!folder.exists()){
folder.mkdir();
}
Manifest file is
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
Link to detail of application apk App apk detail link
Now what should i do i want to create folder write images from url to it and then read them. This work for me in android 5.1 but not in Android version 7 .
You need to implement runtime permissions for android versions above lollipop
Maybe this piece of code will help you:
private static final int PERMS_REQUEST_CODE = 123;
//...........................................................................................................
private boolean hasPermissions(){
int res = 0;
//string array of permissions,
String[] permissions = new String[]
{android.Manifest.permission.WRITE_EXTERNAL_STORAGE};
for (String perms : permissions){
res = checkCallingOrSelfPermission(perms);
if (!(res == PackageManager.PERMISSION_GRANTED)){
return false;
}
}
return true;
}
private void requestPerms(){
String[] permissions = new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
requestPermissions(permissions,PERMS_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
boolean allowed = true;
switch (requestCode){
case PERMS_REQUEST_CODE:
for (int res : grantResults){
// if user granted all permissions.
allowed = allowed && (res == PackageManager.PERMISSION_GRANTED);
}
break;
default:
// if user not granted permissions.
allowed = false;
break;
}
if (allowed){
//user granted all permissions we can perform our task.
ListItem listItem = new ListItem();
Glide.with(getApplicationContext()).asBitmap().load(listItem.getImgurl()).into(new SimpleTarget<Bitmap>(){
#Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
FileOutputStream fileOutputStream = null;
File file = getDisc();
if(!file.exists()&& !file.mkdirs()){
Toast.makeText(getApplicationContext(),"Can't create directory to save image", Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat simpleDataFormat = new SimpleDateFormat("yyyymmsshhmmss");
String date = simpleDataFormat.format(new Date());
String name = "img"+date+".jpg";
String file_name = file.getAbsolutePath()+"/"+name;
File new_file= new File(file_name);
try {
fileOutputStream=new FileOutputStream(new_file);
resource.getHeight();
resource.getWidth();
resource.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
Toast.makeText(getApplicationContext(),"SAVED", Toast.LENGTH_LONG).show();
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
refreshGallery(new_file);
}
public void refreshGallery(File file){
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);
}
private File getDisc(){
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(file, "FolderNamerYourChoice");
}
});
}
else {
// we will give warning to user that they haven't granted permissions.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(this, "Storage Permissions denied.", Toast.LENGTH_SHORT).show();
}
}
}