Please help me... I'm getting
java.io.FileNotFoundException : /storage/'my external storage'/Music/'file name' : open failed: EACCES (Permission denied)
when I'm modifying music's id3 tags which are located in my sd card with jaudiotagger.
I already wrote read/write permissions on manifest file, and I wrote requesting method, permission request result callback method, and a part that modify tags when button clicked like this.
private void requestExternalStoragePermissions() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission granted to write your External storage", Toast.LENGTH_SHORT).show();
start();
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1 : {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0&&grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
start();
}
else {
Toast.makeText(this, "Permission denied to access your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
savebutton.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View view){
try{
AudioFile f = AudioFileIO.read(file);
Tag tag = f.getTag();
tag.setField(FieldKey.TITLE,editText1.getText().toString());
tag.setField(FieldKey.ALBUM,editText2.getText().toString());
tag.setField(FieldKey.ARTIST,editText3.getText().toString());
tag.setField(FieldKey.ALBUM_ARTIST,editText4.getText().toString());
tag.setField(FieldKey.YEAR,editText5.getText().toString());
tag.setField(FieldKey.DISC_NO,editText6.getText().toString());
tag.setField(FieldKey.TRACK,editText7.getText().toString());
tag.setField(FieldKey.LYRICS,editText8.getText().toString());
f.commit();
Toast.makeText(getApplicationContext(), "Tag Saved", Toast.LENGTH_SHORT).show();
} catch(Exception e){
e.printStackTrace();
}
}
});
How can I fix this?
In Android 4.4 and higher, editing files on the sd card is not possible anymore. I had the same issue..
The only workaround is to copy the file to the internal storage, modify it and move it back.
Related
I'm trying to write a program that will need tot save to external storage. Right now I cant seem to save to the external storage.
I included the necessary permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
My code is a simple test for writing to external storage.
final Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String path = Environment.getExternalStorageDirectory() + "/Pictures/" + "test.jpg";
File file = new File(path);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
I have run this code on an emulator and a physical device. In neither case do I see a file saved to the Pictures Folder. Really need help with this.
Since Android M+ you need to request permission not only in Manifest but at runtime also
private void requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat
.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
} else {
//your permission was already granted then write to storage
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
// here you write to the storage for the first time
} else {
// Permission Denied
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
I struct at first page, I am not able to open Dialog soon after permission granted(Write). First time I asked Permission and I granted Permission,in onRequestPermissionsResult() I opened Dialog, here App is closed with Unfortunately APP has crashed issue. When reopen App the issue not here, It is running normally.I got issue in Monitor
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState .I Searched lot but different answers I've seen.Please help me ,I am not getting why app is crashed first time.
Here is my code:
llAddPhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!tvAddPhotoOrNext.getText().toString().equals("Next")) { // When Image not gone selected
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//First checking if the app is already having the permission
if (isReadStorageAllowed()) {
//If permission is already having then showing the toast
Toast.makeText(AddUserProfilePic.this, "You already have the permission", Toast.LENGTH_LONG).show();
//Existing the method with return
showFourButtonsBSDialog();
}else {
//If the app has not the permission then ask for the permission
checkPermissions();
}
} else
showFourButtonsBSDialog();
} else { // When image gone selected.
mSetProfilePicByAPI();
}
}
});
#SuppressLint("InlinedApi")
private void checkPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PICKIMAGE);
} else {
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_PICKIMAGE:
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
showFourButtonsBSDialog();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
/* BottomSheetDialog */
private void showFourButtonsBSDialog() {
MoreOptionsDialogFragment mTBFragment = new MoreOptionsDialogFragment(); // ThreeButtonsFragment
Bundle mTextNamesArgs = new Bundle(); //Send buttons names
mTextNamesArgs.putStringArray("buttons_names",new String[]{"Take Photo","Choose from library",
"Photo from Facebook","Photo from Instagram"});
mTBFragment.setArguments(mTextNamesArgs);
mTBFragment.show(getSupportFragmentManager(),mTBFragment.getTag());
}
private boolean isReadStorageAllowed() {
//Getting the permission status
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
//If permission is granted returning true
if (result == PackageManager.PERMISSION_GRANTED)
return true;
//If permission is not granted returning false
return false;
}
What are your compile SDK and target SDK versions? Make sure them to be 23 or higher.
https://developer.android.com/guide/topics/permissions/requesting.html
I am trying to create a folder on my sdcard using the following code but it fails. This is my code written in onCreate():
File test = new File(Environment.getExternalStorageDirectory(),"my_directory");
if(!test.exists())
{
try
{
if (test.mkdir())
{
Log.d("xxx", "directory created");
}
else
{
Log.d("xxx", "directory creation failed");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
else
{
Log.d("xxx","directory already present");
}
When I run the above code does not give any exception it just prints the
directory creation failed log.
I have also given the following permission,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I am using Xiaomi Redmi note 3 and Android version is 6.0.1.
Try this code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkPermission()) {
//do your work
} else {
requestPermission();
}
}
}
protected boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == 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();
} 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) {
//do your work
} else {
Log.e("value", "Permission Denied, You cannot use local drive .");
}
break;
}
}
I know it just for API 21 (couse i wanted the same at my app, till now i do not know how to get on the sdcard)
you also need this in your manifest!!
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Environment.getExternalStorageDirectory() declares the internal storage.
the exact path is: storage/emulated/0
you get it with:
Log.i(TAG, "path is:" + Environment.getExternalStorageDirectory().toString());
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/
I have this code for creating directory for saving pictures:
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "myphoto");
if (!storageDir.mkdirs()) {
if (!storageDir.exists()){
Log.d("photo", "failed to create directory");
return null;
}
}
}
return storageDir;
storeDir returns "/storage/emulated/0/Pictures/myphoto/" below android 6 and on android 6 it returns null.
I have permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
buildToolVersion 23
targetSdkVersion 23
How to fix?
As #CommonsWare answered, there is run-time permission asking concept on Android M, so in new approach, permissions are not asked when installing the app but when trying to use specific feature of phone which requests permission, at run-time. User later can disable permission from phone settings->app->yourapp->permissions as well. So you have to check before doing something with that permission, and ask user:
int REQUEST_WRITE_EXTERNAL_STORAGE=1;
////...
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
//RUNTIME PERMISSION Android M
if(PackageManager.PERMISSION_GRANTED==ActivityCompat.checkSelfPermission(context,Manifest.permission.WRITE_EXTERNAL_STORAGE)){
storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "myPhoto");
}else{
requestPermission(context);
}
}
return storageDir;
////...
private static void requestPermission(final Context context){
if(ActivityCompat.shouldShowRequestPermissionRationale((Activity)context,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example if the user has previously denied the permission.
new AlertDialog.Builder(context)
.setMessage(context.getResources().getString(R.string.permission_storage))
.setPositiveButton(R.string.tamam, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_EXTERNAL_STORAGE);
}
}).show();
}else {
// permission has not been granted yet. Request it directly.
ActivityCompat.requestPermissions((Activity)context,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_EXTERNAL_STORAGE);
}
}
///...
#Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
switch (requestCode) {
case UtilityPhotoController.REQUEST_WRITE_EXTERNAL_STORAGE: {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context,
getResources().getString(R.string.permission_storage_success),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context,
getResources().getString(R.string.permission_storage_failure),
Toast.LENGTH_SHORT).show();
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
return;
}
}
}
You are running this on an Android 6.0+ environment and you have a targetSdkVersion of 23.
In that case, WRITE_EXTERNAL_STORAGE is part of the Android 6.0 runtime permission system. Either revise your app to participate in this system, or drop your targetSdkVersion below 23.
You must get permission for this work like:
for do it impliment this code:
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23
);
}
}
good luck!!!
Try this code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkPermission()) {
//do your work
} else {
requestPermission();
}
}
}
protected boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
protected void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, 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();
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{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) {
//do your work
} else {
Log.e("value", "Permission Denied, You cannot use local drive .");
}
break;
}
}