I am newbie to native android development. I am working on android studio. I have a tabbed activity in which i am using 2 tabs. In one tab there is a map with marker on gps location of the user. The second tab is to take picture and then to save it in the storage provided by the OS. For this i followed this tutorial, run the app on my device but it's crashes. I am running it on Marshmallow. Below is the error i get
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=android/com.android.internal.app.ResolverActivity } from ProcessRecord{e8f9820 15070:com.example.accurat.faisal/u0a228} (pid=15070, uid=10228) with revoked permission android.permission.CAMERA
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3181)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1541)
at android.app.Activity.startActivityForResult(Activity.java:4298)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.support.v4.app.ActivityCompatJB.startActivityForResult(ActivityCompatJB.java:30)
at android.support.v4.app.ActivityCompat.startActivityForResult(ActivityCompat.java:146)
at android.support.v4.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:937)
at android.support.v4.app.FragmentActivity$HostCallbacks.onStartActivityFromFragment(FragmentActivity.java:1047)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:954)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:943)
at com.example.accurat.faisal.Camera$1.onClick(Camera.java:51)
at android.view.View.performClick(View.java:5716)
at android.widget.TextView.performClick(TextView.java:10926)
at android.view.View$PerformClick.run(View.java:22596)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
I searched it and found that i should ask permission for it so i followed this link and tried to add permission check like as bellow
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Check permission for CAMERA
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
// Callback onRequestPermissionsResult interceptado na Activity MainActivity
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.CAMERA},
MainActivity.REQUEST_CAMERA);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE );
}
});
But i am getting red text of CAMERA and REQUEST_CAMERA. Though i have imported them as well but still the red text is showing
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Below is my manifest file
<uses-permission android:name="com.example.accurat.faisal.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.hardware.camera"/>
I don't know what is the problem and don't know the solution and i am stuck to it.
Any help would be highly appreciated
You need to add permission check in your code and based on user action of accecpt or denial should show the camera preview Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running. Also, you need to ask user permission for android.Manifest.permission.WRITE_EXTERNAL_STORAGE if you are creating a file which will be used as an input for image(captured via camera).
Related
Hello Android developers, I am trying to make my app the default sms app on my phone with the following code but its not working as it is not displaying the dialog for a user to choose which app to use as the default sms app. I am aware that as of Android 10 then we need to use the RoleManager class to check if the app is the default sms app and additionally check if the app holds the role and then start an activity for the user to set the current app to have that role. I have followed every required step from the documentation and some previously posted questions on this site but there seems to be an error that is silent because no exception is thrown. Help me make this code display the dialog to the user for changing the app for the sms roles.
//register a delegate for reading the phone number
button.Click += (o, p) =>
{
Toast.MakeText(this,Telephony.Sms.GetDefaultSmsPackage(ApplicationContext),ToastLength.Long).Show();
//check first if the app is the default sms privilege holder
if (Telephony.Sms.GetDefaultSmsPackage(ApplicationContext) != PackageName)
{
//use the role manager api to change the default sms app
//check the api level
if (Build.VERSION.SdkInt > BuildVersionCodes.P)
{
Log.Debug("API", "api greater than 28");
//api level is greater than 28 then use RoleManager class
RoleManager roleManager = (RoleManager)GetSystemService(Context.RoleService);
//check if the role is available first
if (roleManager.IsRoleAvailable(RoleManager.RoleSms))
{
//log the role manager availability
Log.Debug("Sms role available", roleManager.IsRoleAvailable(RoleManager.RoleSms).ToString());
//chek if the role is held
if (roleManager.IsRoleHeld(RoleManager.RoleSms))
{
//means the app has the sms role and we do not need to change
}
else
{
Log.Debug("Info", "Sms Role is not held");
//means the app does not have the sms role and we need to request the user to change
Intent changeIntent = roleManager.CreateRequestRoleIntent(RoleManager.RoleSms);
StartActivityForResult(changeIntent,909);
}
}
else
{
//the role is not avaialble and cannot be changed
Log.Debug("Sms role available",
roleManager.IsRoleAvailable(RoleManager.RoleSms).ToString());
}
}
else
{
//api level is less than or equal to 28 use the deprecated way
Intent changeIntent = new Intent(Telephony.Sms.Intents.ActionChangeDefault);
changeIntent.PutExtra(Telephony.Sms.Intents.ExtraPackageName, PackageName);
StartActivity(changeIntent);
}
}
and here is my manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="SimCardManager.SimCardManager">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE"/>
<uses-permission android:name="android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER"/>
<application android:allowBackup="true" android:label="#string/app_name" android:supportsRtl="true" android:theme="#style/AppTheme">
</application>
</manifest>
An answer in Android Java is also accepted as that is what I use to convert Java code to C#, the code is still Android Java working as a Xamarin Android C# binding, Thank You for your time and effort helping me.
When attempting to create a temp file on Android 10 I am getting a permission denied error. Could someone please write a tutorial on how to create one in the external storage? Most are outdated and not for current versions of Android
Here is the logcat
2020-02-22 13:46:43.766 9544-9544/com.myapp.test E/MainActivity: Image file creation failed
java.io.IOException: Permission denied
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
at java.io.File.createTempFile(File.java:2018)
at com.myapp.test.MainActivity.create_image(MainActivity.java:915)
at com.myapp.test.MainActivity.access$200(MainActivity.java:85)
at com.myapp.test.MainActivity$6.onShowFileChooser(MainActivity.java:513)
at vo.runFileChooser(PG:10)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:336)
at android.os.Looper.loop(Looper.java:197)
at android.app.ActivityThread.main(ActivityThread.java:7762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)
My AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:remove="android:maxSdkVersion" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
And code in the MainActivity.Java
private File create_image() throws IOException {
#SuppressLint("SimpleDateFormat")
String file_name = new SimpleDateFormat("yyyy_mm_ss").format(new Date());
String new_name = "file_"+file_name+"_";
File sd_directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return File.createTempFile(new_name, ".jpg", sd_directory); // fails due to permission denied
}
I was using official documentation to implement taking a photo from camera:
https://developer.android.com/training/camera/photobasics
yet it doesn't work and throws an exception on createTempFile method. Strangely google hasn't updated the code.
Here's a solution I've found:
Add:
android:requestLegacyExternalStorage="true"
to AndroidManifest.xml. No need to change anything in code. Works for now, but may not in upcoming Android versions.
You need to change
File sd_directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
to
File sd_directory = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
You need to add a file provider
https://developer.android.com/reference/android/support/v4/content/FileProvider
And request the read/write storage permissions at runtime.
https://developer.android.com/training/permissions/requesting
In android 10 permission isn't directly accepted. So, you have ask from user to accept permission. There's a library which you can use for asking permission. Let me add that link
It is known as Dexter Library
You have to add a line to gradle.build
implementation 'com.karumi:dexter:6.2.2'
Following source code used for single permission at a time.
Dexter.withContext(this)
.withPermission(Manifest.permission.CAMERA)
.withListener(new PermissionListener() {
#Override public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}
#Override public void onPermissionDenied(PermissionDeniedResponse response) {/* ... */}
#Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {/* ... */}
}).check();
There's way to asking for multiple permission in Dexter library. You can get that on that link
As you are using getExternalStoragePublicDirectory In android 10+, you can't write on public folder directly. One way is to use getExternalFilesDir to capture image and then use MediaStore APIs to copy file into public directory.
I'm trying to write code to send an SMS from an Android app, but when I try to send the SMS it sends me back the error:
09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
java.lang.SecurityException: Sending SMS message: uid 10092 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
at **.**.****.MainActivity$3.onClick(MainActivity.java:70)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I checked but I have the permissions in the manifest, as follows:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-feature android:name="android.hardware.telephony"
android:required="true"/>
<application
android:exported="true"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I searched the internet but all the errors were about the <uses-permission/> syntax, could you help me please?
(the following is extracted from a blog post of mine about this)
The big reason for not getting your permission nowadays is because
your project has a targetSdkVersion of 23 or higher, and the permission
that you are requesting is "dangerous". In Android 6.0, this includes:
ACCEPT_HANDOVER
ACCESS_BACKGROUND_LOCATION
ACCESS_MEDIA_LOCATION
ACTIVITY_RECOGNITION
ANSWER_PHONE_CALLS
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
For these permissions, not only does your targetSdkVersion 23+ app
need to have the <uses-permission> element(s), but you also have
to ask for those permissions at runtime from the user on Android 6.0+
devices, using methods like checkSelfPermission() and
requestPermissions().
As a temporary workaround, drop your targetSdkVersion below 23.
However, eventually, you will have some reason to want your
targetSdkVersion to be 23 or higher. At that time, you will need
to adjust your app to use the new runtime permission system.
The Android documentation has
a page dedicated to this topic.
Above API level 23 you will be given programmatically pragmatically like:
private static final int PERMISSION_REQUEST_CODE = 1;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.SEND_SMS)
== PackageManager.PERMISSION_DENIED) {
Log.d("permission", "permission denied to SEND_SMS - requesting it");
String[] permissions = {Manifest.permission.SEND_SMS};
requestPermissions(permissions, PERMISSION_REQUEST_CODE);
}
}
Please go through the link below,
https://developer.android.com/guide/topics/permissions/overview.html
Some samples are also available there to get start with the permissions.
To make android more secure now developers has to mention permission in manifest as well as they should have to ask user as well in run time to get the work done. They are permission categorized in dangerous permission section which are mention below
CALENDAR
READ_CALENDAR
WRITE_CALENDAR
CAMERA
CAMERA
CONTACTS
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
RECORD_AUDIO
PHONE
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS
SENSORS
BODY_SENSORS
SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
request permission pragmatically (after API 23)
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Ask for permision
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
}
else {
// Permission has already been granted
}
"If the app has the permission, the method checkSelfPermission() returns PERMISSION_GRANTED, and the app can proceed with the operation.
If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission. You need to prompt the user for that permission, as shown in the above code. Calling requestPermissions() brings up a standard Android dialog, which you cannot customize."
If you are using sdk 23 or higher then you must check run time permissions.
when you declare permisson in Manifest and it's not work means you are performing Task in MarshMallow and for MarshMallow you have set Permisson at RunTime.
like this way
ActivityCompat.requestPermissions();
If you are using Android version "23" or "23+", then app will show you errors when you are trying to access anything which requires user's permission. You have to ask for permissions at run-time even if you have declared those permissions in Android manifest.
Check this: https://developer.android.com/training/permissions/requesting.html
But if you have created your whole application and don't want to change at every place then a little cheat will be sufficient.
Go to "Build.gradle" file and change the target Sdk version to less than 23, like 22, 21.
Along with CommonsWare's answer,
There is a Security Setting (I checked on CM13) to set SMS Message Limit. If you set this to "None", OS will popup a Dialog for every SMS, even after obtaining SMS_SEND permission in the runtime. Best thing is to set this to maximum.
If the maximum is not enough, there are ways to increases the maximum rate on a rooted device.
I added this to my MainActivity, that resolve my problem
int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_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(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
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.
}
}
I hope the solution to write to external storage will be useful too
public boolean checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Timber.tag(LOG_TAG).e("Permission error. You have permission");
return true;
} else {
Timber.tag(LOG_TAG).e("Permission error. You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
// for a stuff below api level 23
Timber.tag(LOG_TAG).e("Permission error. You already have the permission");
return true;
}
}
So i had to create an app to send and receive messages but the send action crashed whenever i clicked on send even though the permission was granted . I had requested runtime permissions and allowed them, still i faced a crash that the process doesnt have the requested permission to send SMS .
I had checked the granted permissions from :
adb shell dumpsys package <package-name>
The order of my request for permissions was
RECEIVE_SMS
SEND_SMS
I reverted the order of request and it works fine . This was tested with a complete new app(uninstall-> install -> test). The answer may seem weird but just give it a shot .
(If it works in the shown way in a certain order, then Android might have a bug!!)
I'm extracting a bitmap in my app right now. It requires a READ_EXTERNAL_STORAGE permission. Since I'm working with Android 6 (API23), I have
1. declared such permission in Android.manifest as
<uses-permission tools:node="replace" android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission tools:node="replace" android:name="android.permission.READ_EXTERNAL_STORAGE" />
checked permissions during runtime( using
ActivityCompat.requestPermissions(...)
in MainActivity and then another
onRequestPermissionsResult(..)
callback to handle the stuff after I get such permission).
However I still fail to fetch the bitmap I want, with an error indicating that I have insufficient permissions.
I also checked the phone's app settings regarding my app's permission and switched on and off the "storage" option, a dialog did popped up requesting permission, but still, after allowing access for the app I get the same error:
07-12 14:54:59.255 31895 31911 E DatabaseUtils: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uricontent://media/external/images/media from pid=18177, uid=10077 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
In MainActivity
String[] perms = {"android.permission.READ_EXTERNAL_STORAGE"};
int permsRequestCode = 200;
In OnCreate
ActivityCompat.requestPermissions(this, perms, permsRequestCode);
The callback in MainActivity:
#Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
super.onRequestPermissionsResult(permsRequestCode, permissions, grantResults);
switch(permsRequestCode){
case 200:
Log.e(TAG, "checking permissions");
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED&&isPreview){
bitmap.getPixels(left, 0,0,0,0,w/2,h);
bitmap.getPixels(right, 0,0,w/2,0,w/2,h);
Log.e(TAG, "left and right stored");
};
//writeAccepted = grantResults[1]==PackageManager.PERMISSION_GRANTED;
break;
}
}
Am I still missing anything here?
I'm trying to write code to send an SMS from an Android app, but when I try to send the SMS it sends me back the error:
09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
java.lang.SecurityException: Sending SMS message: uid 10092 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
at **.**.****.MainActivity$3.onClick(MainActivity.java:70)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I checked but I have the permissions in the manifest, as follows:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-feature android:name="android.hardware.telephony"
android:required="true"/>
<application
android:exported="true"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I searched the internet but all the errors were about the <uses-permission/> syntax, could you help me please?
(the following is extracted from a blog post of mine about this)
The big reason for not getting your permission nowadays is because
your project has a targetSdkVersion of 23 or higher, and the permission
that you are requesting is "dangerous". In Android 6.0, this includes:
ACCEPT_HANDOVER
ACCESS_BACKGROUND_LOCATION
ACCESS_MEDIA_LOCATION
ACTIVITY_RECOGNITION
ANSWER_PHONE_CALLS
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
For these permissions, not only does your targetSdkVersion 23+ app
need to have the <uses-permission> element(s), but you also have
to ask for those permissions at runtime from the user on Android 6.0+
devices, using methods like checkSelfPermission() and
requestPermissions().
As a temporary workaround, drop your targetSdkVersion below 23.
However, eventually, you will have some reason to want your
targetSdkVersion to be 23 or higher. At that time, you will need
to adjust your app to use the new runtime permission system.
The Android documentation has
a page dedicated to this topic.
Above API level 23 you will be given programmatically pragmatically like:
private static final int PERMISSION_REQUEST_CODE = 1;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.SEND_SMS)
== PackageManager.PERMISSION_DENIED) {
Log.d("permission", "permission denied to SEND_SMS - requesting it");
String[] permissions = {Manifest.permission.SEND_SMS};
requestPermissions(permissions, PERMISSION_REQUEST_CODE);
}
}
Please go through the link below,
https://developer.android.com/guide/topics/permissions/overview.html
Some samples are also available there to get start with the permissions.
To make android more secure now developers has to mention permission in manifest as well as they should have to ask user as well in run time to get the work done. They are permission categorized in dangerous permission section which are mention below
CALENDAR
READ_CALENDAR
WRITE_CALENDAR
CAMERA
CAMERA
CONTACTS
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
RECORD_AUDIO
PHONE
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS
SENSORS
BODY_SENSORS
SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
request permission pragmatically (after API 23)
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Ask for permision
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
}
else {
// Permission has already been granted
}
"If the app has the permission, the method checkSelfPermission() returns PERMISSION_GRANTED, and the app can proceed with the operation.
If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission. You need to prompt the user for that permission, as shown in the above code. Calling requestPermissions() brings up a standard Android dialog, which you cannot customize."
If you are using sdk 23 or higher then you must check run time permissions.
when you declare permisson in Manifest and it's not work means you are performing Task in MarshMallow and for MarshMallow you have set Permisson at RunTime.
like this way
ActivityCompat.requestPermissions();
If you are using Android version "23" or "23+", then app will show you errors when you are trying to access anything which requires user's permission. You have to ask for permissions at run-time even if you have declared those permissions in Android manifest.
Check this: https://developer.android.com/training/permissions/requesting.html
But if you have created your whole application and don't want to change at every place then a little cheat will be sufficient.
Go to "Build.gradle" file and change the target Sdk version to less than 23, like 22, 21.
Along with CommonsWare's answer,
There is a Security Setting (I checked on CM13) to set SMS Message Limit. If you set this to "None", OS will popup a Dialog for every SMS, even after obtaining SMS_SEND permission in the runtime. Best thing is to set this to maximum.
If the maximum is not enough, there are ways to increases the maximum rate on a rooted device.
I added this to my MainActivity, that resolve my problem
int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_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(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
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.
}
}
I hope the solution to write to external storage will be useful too
public boolean checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Timber.tag(LOG_TAG).e("Permission error. You have permission");
return true;
} else {
Timber.tag(LOG_TAG).e("Permission error. You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
// for a stuff below api level 23
Timber.tag(LOG_TAG).e("Permission error. You already have the permission");
return true;
}
}
So i had to create an app to send and receive messages but the send action crashed whenever i clicked on send even though the permission was granted . I had requested runtime permissions and allowed them, still i faced a crash that the process doesnt have the requested permission to send SMS .
I had checked the granted permissions from :
adb shell dumpsys package <package-name>
The order of my request for permissions was
RECEIVE_SMS
SEND_SMS
I reverted the order of request and it works fine . This was tested with a complete new app(uninstall-> install -> test). The answer may seem weird but just give it a shot .
(If it works in the shown way in a certain order, then Android might have a bug!!)