Not able to get files from any Android folder - java

I am new in android and was trying to test something. I have this simple app, where I just want to read files from any android folder. Till now, I just checked how the paths are there which I came to know from the following
context.getExternalFilesDir(null);
&
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
The paths obtained are like
/storage/emulated/0/ then rest of the folders
I have done everything, asked for permission in the manifest file, and in the app too. I check that even though the permission is granted and folder path is also correct but the File.listFiles() is givingme null pointer exception.
Please take a look at the code below:
Permission in manfest file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Code to get permission and try checking the files
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},101);
Toast.makeText(getApplicationContext(),
"No permission yet",
Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(),
"Permission already granted",
Toast.LENGTH_SHORT).show();
File dcimPath = new File("/storage/emulated/0/bluetooth"); //This path is correct
File[] files = dcimPath.listFiles(); // gives null pointer exception
Log.i("files length ",files.length+"");
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == 101){
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(getApplicationContext(),
"Permission granted",
Toast.LENGTH_SHORT).show();
File dcimPath = new File("/storage/emulated/0/bluetooth/");
File[] files = dcimPath.listFiles(); //gives error
Log.i("files length ",files.length+"");
}
else{
Toast.makeText(getApplicationContext(),
"Permission denied",
Toast.LENGTH_SHORT).show();
}
}
}
ERROR
Caused by: java.lang.NullPointerException: Attempt to get length of null array

Try adding this line to the Android Manifest File
android:requestLegacyExternalStorage="true"
This is used to read Shared Storage apart from the app's private storage. Read this if you are curious to know more...
Hope this helps. Feel free to ask for clarifications...

Related

Storage Permission Issue In android 10+ devices

i am trying to create a video player ,So I am trying to add the videos to the list
Storage permission is required to fetch the videos, so I took the permission with the below code.
But playstore was reject My app for this MANAGE EXTERNAL STORAGE permission.
But without this permission, I can't get storage permission on Android 10+ device.
To change the name of the video, delete the video and download the video permission is required , so please help me , please tell me how to get storage permission (/storage/Media/Videos , /storage/Download/)
My storage permission code :-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
android:requestLegacyExternalStorage="true"
Main activity code :-
private boolean checkPermission() {
if (SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int result = ContextCompat.checkSelfPermission(PermissionActivity.this, READ_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(PermissionActivity.this, WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
}
private void requestPermission() {
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s",getApplicationContext().getPackageName())));
startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, 2296);
}
} else {
//below android 11
ActivityCompat.requestPermissions(PermissionActivity.this, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2296) {
if (SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
// perform action when allow permission success
} else {
Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
}
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0) {
boolean READ_EXTERNAL_STORAGE = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean WRITE_EXTERNAL_STORAGE = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (READ_EXTERNAL_STORAGE && WRITE_EXTERNAL_STORAGE) {
// perform action when allow permission success
} else {
Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
}
}
break;
}
}
So please tell me how to take storage permission in Android10+ Devices and also below Android 10 devices with out using MANAGE EXTERNAL STORAGE permission , Please Help Me
Permissions have changed in Android 10+:
External storage access scoped to app files and media
By default, apps targeting Android 10 and higher are given scoped access into external storage, or scoped storage. Such apps can see the following types of files within an external storage device without needing to request any storage-related user permissions [..]
Source: Privacy changes in Android 10
On devices that run Android 10 or higher, you don't need any storage-related permissions to access and modify media files that your app owns, including files in the MediaStore.Downloads collection
Source: Storage Permissions
If you have
android:requestLegacyExternalStorage="true"
in application tag in manifest file then you are done for an Android Q/10 device.
It will behave as it behaved on before 10.
I do not understand why you would have any problem on Android 10.
On Android 11+ you should be able to see media files in the usual public directories.

Why won't my app ask or allow location permissions?

I have been stuck on this issue for some time. I am trying to make my app request 2 permissions at once, as so:
ibTakePicture.setOnClickListener(new View.OnClickListener() {
//this get image and location and then display both
#Override
public void onClick(View v) {
ActivityCompat.requestPermissions(
HomePageActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CAMERA},
REQUEST_CODE_MULTIPLE_PERMISSION
);
}
});
So the idea is when the button is clicked the user is prompted to give location and camera permissions, so I can then store the location and photo somewhere. The camera functions work fine, but I am still stuck on getting the location. here is my onRequestPermissionsResult:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
getCurrentLocation();
dispatchTakePictureIntent();
} else {
Toast.makeText(
HomePageActivity.this,
"Location and Camera permissions must be granted for this app to work.",
Toast.LENGTH_LONG
).show();
}
}
}
I am pretty sure it's just a problem with these methods, any help would be massively appreciated.
I have tried other ways, such as in my previous question Java Android - Requesting multiple permissions but one doesn't get requested
When requesting ACCESS_FINE_LOCATION you also need to ask for ACCESS_COARSE_LOCATION.
To handle this potential user behavior, don't request the
ACCESS_FINE_LOCATION permission by itself. Instead, request both the
ACCESS_FINE_LOCATION permission and the ACCESS_COARSE_LOCATION
permission in a single runtime request. If you try to request only
ACCESS_FINE_LOCATION, the system ignores the request if you app target Android 12 or above.
Blockquote
AndroidManifest.xml
<manifest ... >
<!-- Always include this permission -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Include only if your app benefits from precise location access. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
Java code
ActivityCompat.requestPermissions(HomePageActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CAMERA},
REQUEST_CODE_MULTIPLE_PERMISSION
);
You can find more info on google docs - Request location permission

Unable to open captured image: open failed: EACCES (Permission denied)

I am working on this project for an app that can capture an image and then perform Text Recognition on the image using Google ML Toolkit. It is for my personal use only so I don't really care about "respecting the user's choice not to allow permissions", if I could I would ask them all at startup instead of asking when I need them.
Right now I basically request Camera Access at startup (which works fine) and then I show the camera feed to the user in the center of the screen. Then, the user can click on a "capture" button in order to capture the current frame and save it to a certain path. Then, I would like to decode the file in that path into bitmap format, display it to the user and then use the ML Toolkit.
However, I get an error, which I think is a permission error from the READ_EXTERNAL_STORAGE permission. Since the error I get says "Unable to decode stream: java.io.FileNotFoundException: /mnt/sdcard/Pictures/CameraXPhotos/1642088145797.jpg: open failed: EACCES (Permission denied)"
From what I understood I have to manually request permissions. From Android Developers it is stated that: "Any app that declares the WRITE_EXTERNAL_STORAGE permission is implicitly granted this (READ_EXTERNAL_STORAGE) permission." So I theoretically just need to ask for the WRITE_EXTERNAL_STORAGE permission. So I do the following:
onCreate{
button_capture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, STORAGE_WRITE_PERMISSION_CODE);
capturePhoto();
}
});
}
public void checkPermission(String permission, int requestCode){
if (ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_DENIED) {
// Requesting the permission
ActivityCompat.requestPermissions(MainActivity.this, new String[] { permission }, requestCode);
}
else {
Toast.makeText(MainActivity.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 == CAMERA_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Camera Permission Granted", Toast.LENGTH_SHORT) .show();
} else {
Toast.makeText(MainActivity.this, "Camera Permission Denied", Toast.LENGTH_SHORT) .show();
}
}
else if (requestCode == STORAGE_WRITE_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Storage Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Storage Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
But once I click on the capture button, it doesn't ask for permissions and crashes with the error "open failed: EACCES (Permission denied)" because of the line in my code in the capturePhoto() method where I try to open a file from its absolute path. I don't really understand why, with methods checkPermission() and onRequestPermissionsResult() I am handling permissions correctly right?
Is it because the capturePhoto() method runs in parallel of the checkPermissions() method and therefore does not wait for the permissions to be given?
I hope my issue is understanble, this is my first question so if I did anything wrong in my question feel free to point it out to me!
Could it be that it is because in my checkPermission() method I check if the permission was denied but not if it was not granted in the first place?
EDIT: Thank you for your comments #blackapps. The code that lets the user capture a picture is the following:
private void capturePhoto() {
File photoDir = new File("/mnt/sdcard/Pictures/CameraXPhotos");
if(!photoDir.exists())
photoDir.mkdir();
Date date = new Date();
String timestamp = String.valueOf(date.getTime());
String photoFilePath = photoDir.getAbsolutePath() + "/" + timestamp + ".jpg";
File photoFile = new File(photoFilePath);
imageCapture.takePicture(
new ImageCapture.OutputFileOptions.Builder(photoFile).build(),
getExecutor(),
new ImageCapture.OnImageSavedCallback() {
#Override
public void onImageSaved(#NonNull ImageCapture.OutputFileResults outputFileResults) {
Toast.makeText(MainActivity.this, "Photo has been taken", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(#NonNull ImageCaptureException exception) {
Toast.makeText(MainActivity.this, "Error taking photo: " + exception.getMessage(), Toast.LENGTH_SHORT).show();
}
}
);
Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
getTextFromImage(bitmap);
image_result.setImageBitmap(bitmap);
// return photoFilePath;
}

Ask Same Android Studio Permissions Over And Over

I need to access the user's location, and the permission for it is crucial for my app.
I tried this code but it did not ask for permission the second time (and so forward):
while(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
}
If the permission is really crucial to continue in the app, as far as I know, the only think you can do is just to finish the app when you get in the permissions callback that this permission has not been granted.
This way the next time the app is opened it will ask again for the location permission.
We check for permissions at the main activity and show a toast that says that the permissions are required and finish the main activity in one app which makes no sense using it without location. And the app is published in the google play store.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (permissions.length > 0 && requestCode == REQUEST_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setUp();
} else {
Toast.makeText(this, R.string.permissions_required, Toast.LENGTH_LONG).show();
finish();
}
}
}
Even though it might be better if the rest of the app could be used without location, but sometimes there is no other way and if you try to ask for the same permission once and again the dialog will not show up at some point.

FileNotFoundException: open failed: EACCES (Permission denied)

In emulator (i use genymotion) it works fine, but when I run it on a real device (my phone is ASUS ZenFone Laser 5.0) throws a filenotfoundexception
java.io.FileNotFoundException: /storage/emulated/0/cam20160926_075819.jpg: open failed: EACCES (Permission denied)
imgBitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage);
here's the method onActivityResult()
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case CAMERA_REQUEST:
if (resultCode == Activity.RESULT_OK){
Uri selectedImage = imageUri;
getActivity().getContentResolver().notifyChange(selectedImage, null);
ContentResolver cr = getActivity().getContentResolver();
Bitmap imgBitmap;
try {
imgBitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage);
accountPhoto.setImageBitmap(imgBitmap);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Something went wrong while taking a photo", Toast.LENGTH_LONG).show();
Log.e("Camera", e.toString());
}
}
}
}
i read some related questions and solutions about this EACCES, and it seems the problem is on my permission:
<uses-feature android:name="android.hardware.camera2" android:required="true"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
am I missing something? thanks for responding
you have to request permission before you start your instructions because this permission is considered dangerous in Marshmallow:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RESULT);
}
else
{
//your code
}
I suspect WRITE_EXTERNAL_STORAGE overrides the READ_EXTERNAL_STORAGE read permission. If you look into the documentation you'll see that the former also permits reading from storage.
Try and remove the android:maxSdkVersion attribute and see if that works. I suspect that your device runs an SDK version > 18.
Check out this answer for more info: https://stackoverflow.com/a/15270626/425238

Categories

Resources