I am trying to access mp3 files in externalStorage and this is my code:
public class MainActivity extends AppCompatActivity {
private LinearLayout viewL;
private String[] STAR = { "*" };
String fullpath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewL = (LinearLayout) findViewById(R.id.linear);
try{
String provider = "com.android.providers.media.MediaProvider";
Uri uri = Uri.parse("content://media/external/audio/media");
grantUriPermission(provider, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
grantUriPermission(provider, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
grantUriPermission(provider, uri, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
Cursor cursor;
Uri allsongsuri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = android.provider.MediaStore.Audio.Media.IS_MUSIC + " != 0";
cursor = getContentResolver().query(allsongsuri, STAR, selection, null, null);
for(int i =0;i<1;i++){
cursor.moveToFirst();
fullpath = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA));
}
MediaPlayer mp = new MediaPlayer();
Uri myUri = Uri.parse(fullpath);
mp.setDataSource(this,myUri);
mp.prepare();
mp.start();
}
catch (Exception e){
Snackbar.make(viewL,e.toString(),Snackbar.LENGTH_LONG).show();
}
}
}
This is my manifestFile:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.grassa"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
This is my logcat:
Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=20241, uid=10113 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:453)
As you can see i have added all the permissions required but still I am getting permission Denied error Can someone help me out with this?? ThankYou
If you are running it on marshmallow, you need to request the permission at the runtime.
Here's the official doc : http://developer.android.com/training/permissions/requesting.html
You have to check the permission using ContextCompat.checkSelfPermission function. Then, if you don't have the permission,
request it via ActivityCompat.requestPermissions method and implement
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) method to receive the user results.
If the device is running Android 5.1 or lower, or your app's target SDK is 22 or lower: If you list a dangerous permission in your manifest, the user has to grant the permission when they install the app; if they do not grant the permission, the system does not install the app at all.
If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.
use below code,
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// 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(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.
}
}
and handle you permission status by,
#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
}
}
Source : http://developer.android.com/training/permissions/requesting.html
Related
I know there are a lot of questions like this already floating around, and I've tried all that I could come across, but I still can't get it to work.
My problem is the BroadcastReceiver onReceive never seem to be called.
My code is as follows:
class SMSReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("BroadcastReceiver", "onReceive")
if (intent.action == Telephony.Sms.Intents.SMS_RECEIVED_ACTION) {
Log.d("BroadcastReceiver", "SMS received")
// Will do stuff with message here
}
}
The log messages never show up.
AndroidManifest.xml
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".main.MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<activity android:name=".setup.SetupActivity"
android:screenOrientation="portrait">
</activity>
<receiver
android:name=".SMSReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action
android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
In my mainActivity I've tried multiple ways of achieving this, but currently there's only:
var smsReceiver = SMSReceiver()
I appreciate any tips I can get, and it would also be great if any code samples was written in Kotlin. :)
I got into the same issue actually it was only permissions issue even if I was requesting all permissions and allowing all at once still some permissions were not grated, make sure by applying debugging tags that you have all permissions allowed.
I used the following
private val appPermission = arrayOf(Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_MMS)
in onCreate
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.RECEIVE_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.RECEIVE_SMS)) {
// 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, we can request the permission.
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.RECEIVE_SMS),
PERMISSIONS_RECEIVE_SMS)
// 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
}
here is onRequestPermission
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
PERMISSIONS_RECEIVE_SMS -> {
// If request is cancelled, the result arrays are empty.
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
Log.d(TAG, "PERMISSIONS_RECEIVE_SMS permission granted")
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_SMS)) {
// 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, we can request the permission.
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.READ_SMS),
PERMISSIONS_REQUEST_READ_SMS)
// 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
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Log.d(TAG, "PERMISSIONS_RECEIVE_SMS permission denied")
}
return
}
PERMISSIONS_REQUEST_READ_SMS -> {
// If request is cancelled, the result arrays are empty.
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
Log.d(TAG, "PERMISSIONS_REQUEST_READ_SMS permission granted")
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Log.d(TAG, "PERMISSIONS_REQUEST_READ_SMS permission denied")
}
return
}
// Add other 'when' lines to check for other
// permissions this app might request.
else -> {
// Ignore all other requests.
}
}
}
Do not use if check inside the onReceive()
class SMSReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("BroadcastReceiver", "onReceive")
Log.d("BroadcastReceiver", "SMS received")
// Will do stuff with message here
}
I need to open a pdf using a uri.
I have the code in place to open the pdf.
My code works fine on Api greater than 23.
I get the following SecurityException when I try to download the file on a Samsung Galaxy device with Api 23 and version 6.
Here is the exception:
01-25 19:28:38.723 6655-6667/android.process.media E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: No permission to write to /storage/emulated/0/Download/Canto Quick Start Guide.pdf: Neither user 10022 nor current process has android.permission.WRITE_EXTERNAL_STORAGE.
at android.app.ContextImpl.enforce(ContextImpl.java:1438)
at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:1470)
at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:675)
at com.android.providers.downloads.DownloadProvider.checkFileUriDestination(DownloadProvider.java:724)
at com.android.providers.downloads.DownloadProvider.insert(DownloadProvider.java:558)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:263)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:163)
at android.os.Binder.execTransact(Binder.java:507)
I have setup the required permission in manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I have the following check in place to test if the user does not have WRITE_EXTERNAL_STORAGE permission then ask the user for granting access.
int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 2;
// Check whether this app has write external storage permission or not.
int writeExternalStoragePermission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
// If do not grant write external storage permission.
if (writeExternalStoragePermission != PackageManager.PERMISSION_GRANTED) {
// Request user to grant write external storage permission.
((MainActivity)activity).getSharedPreferenceManager().add(PreferenceConstants.SHAREPOINT_FILE_URI, getUrl((SharepointFile) object, activity));
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PermissionConstants.PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getUrl((SharepointFile) object, activity)));
intent.setDataAndType(Uri.parse(getUrl((SharepointFile) object, activity)), "application/pdf");
activity.startActivity(intent);
}
I override the onRequestPermissionResult in MainActivity.java so that as soon as the user grants permission then the download can be initiated.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PermissionConstants.PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
String fileUri = getSharedPreferenceManager().get(PreferenceConstants.SHAREPOINT_FILE_URI);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(fileUri));
startActivity(intent);
} else {
getSharedPreferenceManager().remove(PreferenceConstants.SHAREPOINT_FILE_URI);
}
break;
}
}
I have the code to ask the user for permission. I do get the dialog/alert to allow access. Once the user clicks allow, I see that it still gives the above exception. I went in settings to check my app's permission and see that it is turned "on" for storage. Why would I still get permission issue? Any pointers on what I could be missing here? Appreciate your help!
It is just an assumption but i see you have declared both
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
But docs says:
Any app that declares the WRITE_EXTERNAL_STORAGE permission is implicitly granted this (READ_EXTERNAL_STORAGE) permission.
Try to remove
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
My Android app needs to request permission for location services. I do this with:
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_CODE_ACCESS_COARSE_LOCATION);
But immediately after this is called, onRequestPermissionsResult returns immediately with permission denied:
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ACCESS_COARSE_LOCATION: {
}
}
}
The permission is listed in the manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION"/>
I also cleared the cache to prevent any previous denial the user gave from affecting this.
I am expecting a dialog to pop up requesting the user to grant or deny permission to the location services but it isn't showing.
Change:
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION"/>
to:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
The permission is for "coarse" location data (i.e., not fine-grained), not "course" location data (e.g., where some university class is being held).
private int PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 100;
private void checkPermission() {
if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(newString[{Manfest.permission.ACCESS_COARSE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
} else {
doShowLocation();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showContacts();
}
}
One more scenario that onRequestPermissionsResult can return denied permission even before permission dialog appears is when you declared some other permission in android manifest and asking some other permission in run time. Example:
You have declared
<uses-permission android:name="android.permission.READ_SMS" />
in android manifest file. However you are trying to get
Manifest.permission.SEND_SMS
in runtime permission. So making the runtime permission to READ_SMS will work without any issues.
I'm having a rather strange problem with an Android app I'm writing.
In my app, I use an intent to tell the phone's camera app to take a picture for me. After I take this picture, I want to register the newly taken photo with the device's MediaStore content provider in order to make it show up in the regular "gallery" app.
To do this, I know I need the WRITE_EXTERNAL_STORAGE permission, but even when it's in my manifest I get a permission denied exception. What do I have to do to get this permission? I'm running Android 6.0.1.
Here's my permissions XML in the manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Here's the code that causes the exception:
// insert photo into phone's main photo content provider
ContentResolver cr = getActivity().getContentResolver();
try {
MediaStore.Images.Media.insertImage(cr, photoFile.getPath(),
"Image Capture", "Custom Image capture");
} catch (FileNotFoundException foe) {
Log.e(DEBUG, foe.getMessage());
}
And here's the exception I get:
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=2436, uid=10041 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
EDIT: I should probably mention:
Right now my app uses getExternalFilesDir(Environment.DIRECTORY_PICTURES), which returns the path /sdcard/Android/data/<package>/files/Pictures to save it's photos. I want them to go where the camera app normally puts them, in /sdcard/DCIM/Camera.
You should add the android:maxSdkVersion="18" to the WRITE_EXTERNAL_STORAGE as well. Your code should look like this:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
This may be a problem with respect to you requesting the permission but not being granted the permission by the user. Have a look at my answer # https://stackoverflow.com/a/35574084/529691
And see if that helps.
You should promt the user to provide you permission:
int externalPermissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (externalPermissionCheck==-1){
askPermissionStorage();
}
private void askPermissionStorage() {
//for media
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.
WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//insert explanation
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//if you want to explaian to the user
} else {//if no explanation needed
ActivityCompat.requestPermissions(this, new
String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}
}
The above is for save the picture\video
and this is for the camera permission:
int cameraPermissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA);
if (cameraPermissionCheck == -1) {
askPermissionCamera();
}
private void askPermissionCamera() {
//for camera
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.
CAMERA) != PackageManager.PERMISSION_GRANTED) {
//insert explanation
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
//if you want to explaian to the user
} else {//if no explanation needed
ActivityCompat.requestPermissions(this, new
String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
}
}
I am trying to call getCallCapablePhoneAccounts() method of android.telecom.TelecomManager class. Though i have added required user-permission, i am getting Security exception.
Here is the line of code where i am getting exception
List<PhoneAccountHandle> list = getTelecomManager().getCallCapablePhoneAccounts();
user permission added in manifest
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Exception stacktrace
Caused by: java.lang.SecurityException: getDefaultOutgoingPhoneAccount: Neither user 10102 nor current process
has android.permission.READ_PHONE_STATE.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telecom.ITelecomService$Stub$Proxy.getDefaultOutgoingPhoneAccount(ITelecomService.java:615)
at android.telecom.TelecomManager.getDefaultOutgoingPhoneAccount(TelecomManager.java:439)
On Android >=6.0, We have to request permission runtime.
Step1: add in AndroidManifest.xml file
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Step2: Request permission.
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
} else {
//TODO
}
Step3: Handle callback when you request permission.
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_READ_PHONE_STATE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
//TODO
}
break;
default:
break;
}
}
Edit:
Read official guide here Requesting Permissions at Run Time
Are you running Android M? If so, this is because it's not enough to declare permissions in the manifest. For some permissions, you have to explicitly ask user in the runtime: http://developer.android.com/training/permissions/requesting.html
I was experiencing this problem on Samsung devices (fine on others). like zyamys suggested in his/her comment, I added the manifest.permission line but in addition to rather than instead of the original line, so:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.Manifest.permission.READ_PHONE_STATE" />
I'm targeting API 22, so don't need to explicitly ask for permissions.