선언해도 Android 권한이 작동하지 않습니다
Android 앱에서 SMS를 보내는 코드를 작성하려고하는데 SMS를 보내려고하면 오류가 다시 발생합니다.
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)
확인했지만 다음과 같이 매니페스트에 권한이 있습니다.
<?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>
인터넷을 검색했지만 모든 오류가 <uses-permission/>
구문 에 관한 것이 었습니다. 제발 도와 줄 수 있습니까?
(다음은 내 블로그 게시물 에서 추출되었습니다 )
현재 귀하의 허가를받지 않는 가장 큰 이유는 귀하의 프로젝트가 targetSdkVersion
23 이상이고 귀하가 요청한 허가가 "위험"하기 때문입니다. Android 6.0에서는 다음이 포함됩니다.
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
이러한 권한의 경우 targetSdkVersion
23+ 앱에는 <uses-permission>
요소가 있어야 할뿐만 아니라 런타임과 checkSelfPermission()
and 같은 방법을 사용하여 Android 6.0 이상 기기의 사용자에게 해당 권한을 요청해야합니다 requestPermissions()
.
임시 해결 방법으로 targetSdkVersion
23 이하로 떨어 뜨립니다 .
그러나 결국 targetSdkVersion
23 세 이상이 되기를 원하는 이유 가 있습니다. 이때 새로운 런타임 권한 시스템을 사용하도록 앱을 조정해야합니다. Android 문서에는 이 주제 전용 페이지가 있습니다 .
API 레벨 23 이상에서는 다음과 같이 프로그래밍 방식으로 실용적으로 제공됩니다.
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);
}
}
실용적으로 권한 요청 (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
}
"앱에 권한이있는 경우 checkSelfPermission () 메소드는 PERMISSION_GRANTED를 반환하고 앱은 작업을 진행할 수 있습니다.
앱에 권한이없는 경우이 메서드는 PERMISSION_DENIED를 반환하며 앱은 사용자에게 명시 적으로 권한을 요청해야합니다. 위의 코드와 같이 사용자에게 해당 권한을 묻는 메시지가 표시되어야합니다. requestPermissions ()를 호출하면 사용자 정의 할 수없는 표준 Android 대화 상자가 나타납니다. "
SDK 23 이상을 사용하는 경우 런타임 권한을 확인해야합니다.
당신은 선언 할 때 permisson
에 Manifest
그것은 당신이 작업을 수행하는 수단 작동하지 않을 것 MarshMallow
과에 대한 MarshMallow
당신에 Permisson를 설정을 RunTime
.
이런 식으로
ActivityCompat.requestPermissions();
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
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.
}
}
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.
You can use this code to access your messages
Open a Dialog using the code below:
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
1);
Get the Activity result as below:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 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.
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
or edit file build.gradle
and chanche number targetSdkVersion
less than 23
And no longer need the code above
NOTE
Of course this is not the case, and it's just an educational aspect
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 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;
}
}
'development' 카테고리의 다른 글
WebKit / Blink에서 MacOS 트랙 패드 사용자에게 스크롤 막대가 숨겨지지 않도록 방지 (0) | 2020.06.06 |
---|---|
Promise.all : 해결 된 값의 순서 (0) | 2020.06.06 |
파이썬에서 PDF 파일을 만드는 방법 (0) | 2020.06.06 |
장고 동적 모델 필드 (0) | 2020.06.06 |
준비된 명령문에서 "like"와일드 카드 사용 (0) | 2020.06.06 |