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
Related
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();
}
I need to record a phone call in my android application. I have tried with MediaRecorder with the AudioSource set to MIC, VOICE_COMMUNICATION, VOICE_CALL and other options. But none of them record the call. Can anyone please suggest any solution for record a phone call in android.
following is the code that I have tried. But it does not record the call. only record the voice before and after the call. Please suggest Any Solution.
Code to start recording
public void startRecording(){
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, RECORD_AUDIO);
} else {
setReorder();
}
}
public void setReorder(){
audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(output_formats[currentFormat]);
// recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// Do the file write
prepareAndStart();
} else {
// Request permission from the user
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE);
}
}
public void prepareAndStart() {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE);
} else {
startRec();
}
}
public void startRec(){
try{
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
Log.e("REDORDING :: ",e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.e("REDORDING :: ",e.getMessage());
e.printStackTrace();
}
}
// #SuppressLint("MissingSuperCall")
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 0:
// Re-attempt file write
setReorder();
case 1:
prepareAndStart();
case 2:
startRec();
}
}
Code to get file name for output file
private String getFilename() {
// String filepath = Environment.getExternalStorageDirectory().getPath();
String filepath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath();
File file = new File(filepath, AUDIO_RECORDER_FOLDER);
Log.d("FILEPATH", filepath);
if (!file.exists()) {
file.mkdirs();
Log.d( "!file.exists","created file");
}
Log.d("BEFORE RETURN", "created file EXISTS");
Log.d("BEFORE RETURN", file.getAbsolutePath());
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
// return (file.getAbsolutePath());
}
Code to stop recording
public void stopRecording(){
audioManager.setSpeakerphoneOn(false);
try{
if (null != recorder) {
recorder.stop();
Log.d("REDORDING STOP :: ", "recorder.stop();");
recorder.reset();
Log.d("REDORDING STOP :: ", "recorder.reset();");
recorder.release();
Log.d("REDORDING STOP :: ", "recorder.release();");
recorder = null;
}
}catch(RuntimeException stopException){
Log.e("REDORDING STOP :: ", "RuntimeException stopException");
Log.e("REDORDING STOP :: ",stopException.getMessage());
stopException.printStackTrace();
}
}
When the phone call starts Mic access is moved to the priority app which is the voice call itself and its handling app. Your app will no longer have access to the mic if it's an ordinary app. However if your app has an Accessibility service you can share the microphone
https://developer.android.com/guide/topics/media/sharing-audio-input
As far as I know, VOICE_COMMUNICATION is also just a mic with some filter on top, so the same mic sharing should work in this case
Lastly VOICE_CALL Now things get interesting here. This source requires Manifest.permission.CAPTURE_AUDIO_OUTPUT permission. If your app doesn't have it will crash. The problem is this permission is not provided to third-party app in any way. The accessibility trick will not help you here.
Now if you just want a recording accessiblity+mic works most of the time and depending on the situation your recording will turn out either fine or unlistenable. If you don't want rooted phone or custom ROM etc. this is the only way you can record a call.
If you can root or custom ROM your device then you can look into installing your app as system application in order to get the permissions you need.
Unfortunately, it is not possible on most unrooted Android phones to record phone calls using a regular app.
You would need to either:
A) Sign your app with the OEM certificate to get escalated privileges
B) Root the phone
C) Find a security exploit
I think there are some rare models that have a different configuration of audio pathing that can allow this, but there are very few of them.
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 creating a mobile app to do a screenshot at regular intervals. Then the image would be retrieved and sent by MMS.
My problem is that I work with a galaxy S6 edge with android 7.0 and therefore that has no memory card. The program runs on a kitkat phone with a memory card but does not work on the S6 Galaxy.
How can the image be stored in the internal memory?
What is the path to access the MMS application?
Thank you
In your manifest file give below permissions
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Give runtime permissions in your java file:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, EXTERNAL_PERMISSION_CODE);
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_PERMISSION_CODE);
}
Method for saving images to Internal memory/ SD card
(When you try to write to device's external memory, first the android tries to find the installed SD card on the device and writes to it. If, SD card is not available then the data gets written in device's internal memory:
private void saveImageToLog(){
String timeStampString = Calendar.getInstance().get(Calendar.MILLISECOND);
File appDirectory = new File( Environment.getExternalStorageDirectory() + "/MyAppImageLog" );
File photo = new File(appDirectory, "photo_" + timeStampString+ ".png");
if ( !appDirectory.exists() ) {
appDirectory.mkdir();
}
if (photo.exists()) {
photo.delete();
}
try {
Bitmap bmp = bitmapImage;
FileOutputStream fos = new FileOutputStream(photo.getPath());
bitmapImage.compress(Bitmap.CompressFormat.PNG, 0, fos);
fos.flush();
fos.close();
}catch (Exception e){
e.printStackTrace();
Log.v("log_tag", e.toString());
testInvalid = "";
}
}
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