String path = "/storage/emulated/0/Recordings/Call/Two.mp3";
File file = new File(path);
if(file.exists()) {
File file2 = new File(file.getAbsolutePath());
file2.delete();
Toast.makeText(this, "File deleted.", Toast.LENGTH_SHORT).show();
finish();
}else
{
Toast.makeText(this, "File not exists", Toast.LENGTH_SHORT).show();
}
File is not getting deleted. But the toast is showing as File Deleted.I trapped on this issue almost 2 days, any help will be highly appreciated. Thanks in advance.
I used the below permission in the manifest.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
Solution # 1
For Android 11 or higher, you can delete file using MediaStore Api (without MANAGE_EXTERNAL_Storage)
In onCreate()
String path = "/storage/emulated/0/Recordings/Call/Two.mp3";
private ActivityResultLauncher<Intent> deleteResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
MediaScannerConnection.scanFile(getApplicationContext(), new String[]{path}, null, (path, uri) -> {
Log.d("onScanCompleted", uri.getPath());
});
}
});
you delete function,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Uri fileUri = Uri.fromFile(new File(path));
ArrayList<Uri> arrayList = new ArrayList<>();
arrayList.add(fileUri);
PendingIntent pendingIntent = MediaStore.createDeleteRequest(getContentResolver(), arrayList);
deleteResultLauncher.launch(new IntentSenderRequest.Builder(pendingIntent).build().getFillInIntent());
}
Solution 2
With MANAGE_EXTERNAL_Storage, just add MediaScannerConnection
String path = "/storage/emulated/0/Recordings/Call/Two.mp3";
File file = new File(path);
if (file.exists()) {
File file2 = new File(file.toString());
file2.delete();
MediaScannerConnection.scanFile(getApplicationContext(), new String[]{path}, null, (path, uri) -> {
Log.d("onScanCompleted", uri.getPath());
});
Toast.makeText(this, "File deleted.", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(this, "File not exists", Toast.LENGTH_SHORT).show();
}
Related
I have a file at /sdcard/myfolder/filename.txt
I access this file in my source code as follows:
File fileMyTextFile = new File("/sdcard/myfolder/file.txt");
At one point I check to see if the file exists before opening it to read it's data:
try {
if (fileMyTextFile.exists()) {
...
}
} catch (FileNotFoundException e) {
Log.d("MyApp", "file not found");
e.printStackTrace();
}
I keep getting the FileNotFoundException when my code reaches this point. This same code works without any changes in my other phones which have a lower version of android so I think this has to be something to do with app permissions.
I have declared these in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I also have
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:requestLegacyExternalStorage="true"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
....
In MainActivity.java I have also done this:
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, MY_PERMISSIONS_REQUEST );
How do I access my custom files in android 13?
For Android 13 the request all files permissions has to be shown at runtime. The following code is of course not the full thing, but the main thing needed is to request the request all files permission in the onCreate
In MainActivity:
public static final int STORAGE_PERMISSION = 0,
ALL_FILES_PERMISSION = 2;
private void checkForExternalPermission() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
requestAllFilesAccess(this);
}
}
public void requestAllFilesAccess(#NonNull final OnPermissionGranted onPermissionGranted) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Grant all files permissions!");
alertDialogBuilder.setMessage("You need to grant all files permission");
alertDialogBuilder.setCancelable(false);
alertDialogBuilder.setPositiveButton("Grant", (dialog, id) -> {
permissionCallbacks[ALL_FILES_PERMISSION] = onPermissionGranted;
try {
Intent intent =
new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
} catch (Exception e) {
Log.e("MainActivity", "Failed to initial activity to grant all files access", e);
Toast.makeText(this, "Failed to grant permissions", Toast.LENGTH_SHORT).show();
}
this.finish();
})
.setNegativeButton("Cancel", (dialog, id) -> dialog.cancel());
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
I have confirmed that the permissions are correct for Camera access, however on the later OS versions (perhaps API 25 and above) the camera does not open, it just gives the errror in debug console;
W/System.err: java.io.IOException: Permission denied
This is the method;
public void cameraClicked(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File tempFile = new File(Environment.getExternalStorageDirectory().getPath()+ "/photoTemp.png");
try {
tempFile.createNewFile();
Uri uri = Uri.fromFile(tempFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(takePictureIntent, 2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It does work on Android 7 and below.
EDIT - The following code is now opening the camera correctly, however once the photo is taken it progresses to the next screen but does not show the captured image... Just a black image.
public void cameraClicked(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String path=this.getExternalCacheDir()+"file.png";
File file=new File(path);
Uri uri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider",file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(takePictureIntent, 2);
}
W/System.err: java.io.IOException: Permission denied
This happened because you create file to external storage over Android8/9/10.
If your targetSdk is 23 or higher, you should request permissions
dynamically. to know more : Requesting Permissions at Run Time
to get File path you can use
Context.getExternalFilesDir()/Context.getExternalCacheDir() for
example String path=Context.getExternalCacheDir()+"file.text"; File
file=new File(path) it doesnt need permission if the filepath is
"Android/data/app package/file name"
As in the Android Documentation, you need to write to the external storage, you must request the WRITE_EXTERNAL_STORAGE permission in your manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
If you use API 23 (Marshmallow) and above, you need to Requesting Permissions at Run Time because it's a Dangerous Permission.
if (ContextCompat.checkSelfPermission(
CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
PackageManager.PERMISSION_GRANTED) {
// You can use the API that requires the permission.
performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
// In an educational UI, explain to the user why your app requires this
// permission for a specific feature to behave as expected. In this UI,
// include a "cancel" or "no thanks" button that allows the user to
// continue using your app without granting the permission.
showInContextUI(...);
} else {
// You can directly ask for the permission.
// The registered ActivityResultCallback gets the result of this request.
requestPermissionLauncher.launch(
Manifest.permission.REQUESTED_PERMISSION);
}
Reference source link
reference
make file to external
Edit answer
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case 0:
if (resultCode == Activity.RESULT_OK){
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
SaveImage(thumbnail);
}
break;
}
}
private static void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().getAbsolutePath();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
String fname = "Image-"+ Math.random() +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I also faced this issue before, seems like adding this inside the Application tag under AndroidManifest.xml file solve the problem for me:
<application
...
android:requestLegacyExternalStorage="true">
</application>
I'm trying to create a folder in the Downloads directory on the SDcard of an Android device. I have declared <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in the manifest.
Here's my code:
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
Log.e("file writer", "Directory not writeable");
Toast.makeText(this, "Not writeable.",
Toast.LENGTH_SHORT).show();
}
File dir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "myfolder");
dir.mkdirs();
if (!dir.mkdirs()) { Log.e("file writer", "Directory not created"); }
I get the "directory not created" error and there's obviously no folder where I intend there to be one.
for getting permission in Android 6+ you should ask user, try this
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an expanation 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, we can request the permission.
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_WRITE_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an app-defined int constant. The callback method gets the result of the request.
}
}
Have you tried this?
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
Log.e("file writer", "Directory not writeable");
Toast.makeText(this, "Not writeable.",
Toast.LENGTH_SHORT).show();
}else{
File dir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "myfolder");
dir.mkdirs();
if (!dir.mkdirs()) { Log.e("file writer", "Directory not created"); } }
Try this code
File rootPath = new File(Environment.getExternalStorageDirectory(), "Download/myfolder");
if (!rootPath.exists())
rootPath.mkdirs();
Hope it work
The question is pretty common and I have googled it but it still wont work. I'm simply trying to save a text file using the below code:
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
Toast.makeText(getApplicationContext(), "Access denied", Toast.LENGTH_LONG).show();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/data";
File dir = new File(path);
dir.mkdirs();
File file = new File(path + "/savedFile.txt");
String saveText = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
try {
fos.write(saveText.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_LONG).show();
break;
and in my manifest I have declared:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
However everytime I try and run the code the app crashes with the error 'Unfortunately, APP_NAME has stopped." Can anyone tell me what is wrong with my code?
if ((checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)&& Build.VERSION.SDK_INT >= 23 ) {
Log.v(TAG,"Permission is granted");
return true;}
else{
ActivityCompat.requestPermissions(this, new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
Toast.makeText(getApplicationContext(), "Access denied", Toast.LENGTH_LONG).show();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/data";
File dir = new File(path);
dir.mkdirs();
File file = new File(path + "/savedFile.txt");
String saveText = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
try {
fos = new FileOutputStream(file);
OutputStreamWriter ow = new OutputStreamWriter(fos);
ow.write(saveText.getBytes());
ow.append(saveText.getText());
ow.close();
fos.close();
Toast.makeText(getBaseContext(),
"Done writing SD 'mysdfile.txt'",Toast.LENGTH_SHORT).show();
}} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
}
You need to use something like this code.Because you need to specify runtime permissions.Marshmallow needs you to check the permissions first to use respective resources.
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen
I am trying to programmatically change a ringtone in API 23.
I have looked at a lot of examples on Stack Overflow and they all seem to "work" (i.e. not crash) but they do not "work" as in the mp3 doesn't become the ringtone - instead the ringtone becomes simply zero noise. So obviously /something/ happened. (no crash, now no ringtone noise)
I have split this off into a small side project to try to isolate it because it's driving me up the wall - I hope maybe you guys can see something I can't!
I have:
placed the mp3 in \res\raw
I have verified I can play the mp3 fine with this code
MediaPlayer mPlayer = MediaPlayer.create(me, R.raw.meepmeep);
mPlayer.start();
added <uses-permission android:name="android.permission.WRITE_SETTINGS"/> to the manifest
managed the api 22 permission scenario in java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(this)) {
new AlertDialog.Builder(this)
.setMessage("Please Assign Meep Meep Write Permissions")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(intent);
} catch (Exception e) {
Log.e("MainActivity", "error starting permission intent", e);
}
}
})
.show();
return;
}
used a method to carefully fetch the mp3 path from the assets folder
public String LoadFile(String fileName, boolean loadFromRawFolder) throws IOException
{
InputStream iS;
if (loadFromRawFolder)
{
int rID = resources.getIdentifier("meep.example.com.meep:raw/"+fileName, null, null);
iS = resources.openRawResource(rID);
}
else
{
iS = resources.getAssets().open(fileName);
}
byte[] buffer = new byte[iS.available()];
iS.read(buffer);
ByteArrayOutputStream oS = new ByteArrayOutputStream();
oS.write(buffer);
oS.close();
iS.close();
return oS.toString();
}
tried to carefully copy the file to the local storage (as a desperate attempt to get it to work as well as tried to assign it from the raw assets lib
String path = "";
try {
LoadFile("meepmeep", true);
} catch (IOException e) {
//display an error toast message
Toast toast = Toast.makeText(me, "File: not found!", Toast.LENGTH_LONG);
toast.show();
}
//copy file to device
File newSoundFile = new File(path);
//Uri mUri = Uri.parse("android.resource://meep.example.com.meep/R.raw.meepmeep");
Uri mUri = MediaStore.Audio.Media.getContentUriForPath(newSoundFile.getAbsolutePath());
ContentResolver mCr = getContentResolver();
AssetFileDescriptor soundFile;
try {
soundFile= mCr.openAssetFileDescriptor(mUri, "r");
try {
byte[] readData = new byte[1024];
FileInputStream fis = soundFile.createInputStream();
FileOutputStream fos = new FileOutputStream(newSoundFile);
int i = fis.read(readData);
while (i != -1) {
fos.write(readData, 0, i);
i = fis.read(readData);
}
fos.close();
} catch (IOException io) {
}
} catch (FileNotFoundException e) {
soundFile=null;
}
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, newSoundFile.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "Meep Meep");
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.MediaColumns.SIZE, newSoundFile.length());
values.put(MediaStore.Audio.Media.ARTIST, "RoadRunner");
//values.put(MediaStore.Audio.Media.DURATION, 230);
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
//Insert it into the database
Uri uri = MediaStore.Audio.Media.getContentUriForPath(newSoundFile.getAbsolutePath());
Uri newUri = mCr.insert(uri, values);
try {
RingtoneManager.setActualDefaultRingtoneUri(
me,
RingtoneManager.TYPE_RINGTONE,
newUri
);
}
catch (Throwable t){
setMessage("meepmeep error");
}
setMessage("meepmeep set");
}
but nothing seems to work. It always fails becuase either soundFile= mCr.openAssetFileDescriptor(mUri, "r"); returns null or if I decline to use that code block and try to change ringtone direct from \res\raw\ folder then it simply gives a blank sound for ringtone.
I am totally stuck for ideas?