Android M 권한: onRequestPermissionsResult()가 호출되지 않음
새로운 M 런타임 권한 시스템을 사용하기 위해 앱을 업데이트하고 있습니다.onRequestPermissionsResult()를 제외하고 모두 동작하고 있습니다.버튼 누름에 대한 권한을 확인하고 성공하면 문자 메시지를 보내야 합니다.이 작업을 수행할 권한을 부여하면 대화 상자가 닫히지만 버튼을 다시 누를 때까지 텍스트 보내기가 트리거되지 않습니다.
onRequestPermissionsResult() 메서드로 디버깅하여 브레이크 포인트를 설정했지만 이 메서드에 들어가지 않습니다.
이 메서드가 먼저 호출됩니다.
private void askForPermission() {
String[] permissions = new String[]{Manifest.permission.SEND_SMS};
ActivityCompat.requestPermissions(getActivity(), permissions, PERMISSIONS_CODE);
}
그리고 콜백은 다음과 같습니다.
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_CODE) {
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int grantResult = grantResults[i];
if (permission.equals(Manifest.permission.SEND_SMS)) {
if (grantResult == PackageManager.PERMISSION_GRANTED) {
onPPSButtonPress();
} else {
requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSIONS_CODE);
}
}
}
}
}
비슷한 문제에 부딪힌 사람이 있나요?도움에 감사드립니다.고마워요.
저도 같은 문제에 부딪혀서 해결책을 찾았어요.지원 라이브러리를 사용할 때는 올바른 메서드 호출을 사용해야 합니다.예를 들어 다음과 같습니다.
- AppCompatActivity에서 ActivityCompat.requestPermissions를 사용해야 합니다.
- 안드로이드일 때.support.v4.app을 참조해 주세요.fragment는 단순히 request Permissions를 사용해야 합니다(이것은 안드로이드의 인스턴스 방식입니다).support.v4.app을 참조해 주세요.단편화)
프래그먼트 내에서 ActivityCompat.requestPermissions를 호출하면 onRequestPermissionsResult 콜백이 fragment가 아닌 액티비티로 호출됩니다.
다음과 같이 시험해 보십시오.
requestPermissions(permissions, PERMISSIONS_CODE);
fragment에서 이 코드를 호출하는 경우 자체 requestPermissions 메서드가 있습니다.스태틱 메서드를 호출하고 있는 것이 문제라고 생각합니다.
(프로팁) (한 )onRequestPermissionsResult() fragment화:FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)
잘 됐으면 좋겠다
액티비티의 경우:
ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE);
fragment의 경우:
requestPermissions(permissionsList,REQUEST_CODE);
저도 이 문제를 겪었습니다.를 원하는 , "/"를 할 수 .AndroidManifest.xml작성하다
requestPermissions ★★★★★★★★★★★★★★★★★」AppCompatActivity.requestPermissions
android:noHistory="true"
android:excludeFromRecents="true"
안에서AndroidManifest.xmlonRequestPermissionsResult()호출되지 않습니다.이것은 액티비티가 다음에서 파생된 경우 해당됩니다.Activity ★★★★★★★★★★★★★★★★★」AppCompatActivity
이 는 ' Manifest하고 'Android Manifest.xml'로 할 수 .finishAndRemoveTask()★★★★★★ 。
「 」가 onRequestPermissionsResult프래그먼트 을 발신해 .super.onRequestPermissionsResult동동중중중중다다단편적으로 필수는 아니지만, 액티브하게 되어 있습니다.
권장되지 않는 답변은http://https://developer.android.com/training/permissions/requesting 를 참조해 주세요.
fragment 내에서는, 다음의 콜을 실시할 필요가 있습니다.
FragmentCompat.requestPermissions(permissionsList, RequestCode)
없음:
ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode);
fragment에서 request Permissions를 사용하는 경우 3개의 파라미터가 아닌 2개의 파라미터를 받아들입니다.
하면 됩니다.requestPermissions(permissions, PERMISSIONS_CODE);
어떤 이유로 Super를 호출하지 않는 외부 라이브러리에 있는 커스텀 액티비티를 확장한 경우 수동으로 Fragment super.onRequestPermissionsResult를 호출해야 합니다.
YourActivity extends SomeActivityNotCallingSuperOnRequestPermissionsResult{
Fragment requestingFragment;//the fragment requesting the permission
...
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestingFragment!=null)
requestingFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
...
Fragment Compat에는 프리 마시멜로 디바이스의 checkPermissions 기능이 있습니다.사용법은 다음과 같습니다.
FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
서 부르느냐가 하다는 것을 .android.support.v4.app.Fragment.requestPermissions.
onCreate(),onRequestPermissionsResult()을 사용하다
콜:콜:콜:콜:콜:콜:콜:콜:콜:콜:콜:onActivityCreated();
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED)
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 0);
}
이 문제는 실제로 Nested Fragments에 의해 발생하였습니다.기본적으로 대부분의 fragment는 Hosted Fragment를 확장하여 Compative Fragment를 확장합니다.이러한 네스트된 단편으로 인해 문제가 발생하였고, 결국 프로젝트의 다른 개발자에 의해 해결되었습니다.
그는 이 작업을 수행하기 위해 비트 전환과 같은 낮은 수준의 작업을 하고 있었기 때문에 실제 최종 해결책이 무엇인지 잘 모르겠습니다.
/* use the object of your fragment to call the
* onRequestPermissionsResult in fragment after
* in activity and use different request Code for
* both Activity and Fragment */
if (isFragment)
mFragment.requestPermissions(permissions.toArray(new
String[permissions.size()]),requestPermission);
else
ActivityCompat.requestPermissions(mActivity,permissions.toArray(new
String[permissions.size()]),requestPermission);
이거면 될 거야..
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
fragment에서 이 코드를 호출하는 경우 자체 requestPermissions 메서드가 있습니다.
기본적인 컨셉은 액티비티에 참가하고 있는 경우,
ActivityCompat.requestPermissions(this,
permissionsList,
permissionscode);
fragment에 있는 경우,
requestPermissions(permissionsList,
permissionscode);
비슷한 문제가 있었습니다만, 버튼을 눌러 콜을 발신하면, 그것이 CallIntent가 트리거 됩니다.먼저 권한을 확인했습니다.허가가 나지 않으면 권한을 요청하고 onRequestPermissionResult는 체크 권한을 호출하여 다시 호출합니다.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case Constants.PERMISSIONS_REQUEST_CALL_PHONE: {
if ( grantResults[0] == PackageManager.PERMISSION_GRANTED) {
checkPermissionsAndCall();
}
}
}
}
public void checkPermissionsAndCall(){
if (Build.VERSION.SDK_INT > 22) {
if(ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED){
requestPermissions( new String[]{Manifest.permission.CALL_PHONE}, Constants.PERMISSIONS_REQUEST_CALL_PHONE);
}
else{
callIntent();
}
}
}
goodgamerguy의 답변에 따르면 솔루션은 다음과 같습니다.
myFragment.this.requestPermissions(....)
위의 답변에 따라 모든 것을 체크하기 전에 요청 코드가 0이 아닌지 확인하십시오.
fragmentActivity.java의 onRequestPermissionsResult() 코드를 확인합니다.
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
int index = (requestCode>>16)&0xffff;
if (index != 0) {
index--;
String who = mPendingFragmentActivityResults.get(index);
mPendingFragmentActivityResults.remove(index);
if (who == null) {
Log.w(TAG, "Activity result delivered for unknown Fragment.");
return;
}
Fragment frag = mFragments.findFragmentByWho(who);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for who: " + who);
} else {
frag.onRequestPermissionsResult(requestCode&0xffff, permissions, grantResults);
}
}
}
private void showContacts() {
if (getActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
} else {
doShowContacts();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
doShowContacts();
}
}
BaseActivity를 이렇게 만들기 위한 훌륭한 솔루션이 있습니다.
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
CustomToast.getInstance().setCustomToast("Now you can share the Hack.");
} else {
Toast.makeText(this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
}
}
}
}
이제 이렇게 코드를 호출하여 허가를 요청할 수 있습니다.
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
fragment 내든 액티비티 내든 어디서든 이러한 현상이 발생할 때마다 기본 액티비티가 호출됩니다.
고마워요.
하시면 됩니다.requestPermissions(PERMISSIONS, MULTIPLE_PERMISSIONS_CODE); 를 사용하는 을 사용하지 v4 、 Fragment Compat 、 Fragment Compat 、 Fragment Compat 、 Fragment Compat 、 Fragment Compat 。
세부 사항
- 코틀린 1.2.70
- minSdkVersion 19 체크인
- Android studio 3.1.4
알고리즘.
모듈 - 카메라, 위치...
- has System Feature(전화기에 모듈이 있는 경우)가 있는지 확인합니다.
- 사용자가 모듈에 액세스할 수 있는지 확인하십시오.
- 권한 요청 전송(사용자에게 모듈 사용을 허용하도록 요청)
특징들
- 액티비티 및 단편 작업
- 결과 응답이 1개뿐입니다.
- 한 번의 요청으로 여러 모듈을 체크할 수 있습니다.
솔루션
class PermissionType(val manifest_permission: String, val packageManager: String) {
object Defined {
val camera = PermissionType(Manifest.permission.CAMERA, PackageManager.FEATURE_CAMERA)
val currentLocation = PermissionType(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.FEATURE_LOCATION_GPS)
}
}
class Permission {
enum class PermissionResult {
ACCESS_ALLOWED, ACCESS_DENIED, NO_SYSTEM_FEATURE;
}
interface ManagerDelegate {
fun permissionManagerDelegate(result: Array<Pair<String, PermissionResult>>)
}
class Manager internal constructor(private val delegate: ManagerDelegate?) {
private var context: Context? = null
private var fragment: Fragment? = null
private var activity: AppCompatActivity? = null
private var permissionTypes: Array<PermissionType> = arrayOf()
private val REQUEST_CODE = 999
private val semaphore = Semaphore(1, true)
private var result: Array<Pair<String, PermissionResult>> = arrayOf()
constructor(permissionType: PermissionType, delegate: ManagerDelegate?): this(delegate) {
permissionTypes = arrayOf(permissionType)
}
constructor(permissionTypes: Array<PermissionType>, delegate: ManagerDelegate?): this(delegate) {
this.permissionTypes = permissionTypes
}
init {
when (delegate) {
is Fragment -> {
this.fragment = delegate
this.context = delegate.context
}
is AppCompatActivity -> {
this.activity = delegate
this.context = delegate
}
}
}
private fun hasSystemFeature(permissionType: PermissionType) : Boolean {
return context?.packageManager?.hasSystemFeature(permissionType.packageManager) ?: false
}
private fun hasAccess(permissionType: PermissionType) : Boolean {
return if (Build.VERSION.SDK_INT < 23) true else {
context?.checkSelfPermission(permissionType.manifest_permission) == PackageManager.PERMISSION_GRANTED
}
}
private fun sendRequest(permissionTypes: Array<String>) {
if (fragment != null) {
fragment?.requestPermissions(permissionTypes, REQUEST_CODE)
return
}
if (activity != null){
ActivityCompat.requestPermissions(activity!!, permissionTypes, REQUEST_CODE)
}
}
fun check() {
semaphore.acquire()
AsyncTask.execute {
var permissionsForSendingRequest: Array<String> = arrayOf()
this.result = arrayOf()
for (it in permissionTypes) {
if (!hasSystemFeature(it)) {
result += Pair(it.manifest_permission, PermissionResult.NO_SYSTEM_FEATURE)
continue
}
if (hasAccess(it)) {
result += Pair(it.manifest_permission, PermissionResult.ACCESS_ALLOWED)
} else {
permissionsForSendingRequest += it.manifest_permission
}
}
if (permissionsForSendingRequest.isNotEmpty()) {
sendRequest(permissionsForSendingRequest)
} else {
delegate?.permissionManagerDelegate(result)
}
}
}
fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
REQUEST_CODE -> {
if (grantResults.isEmpty()) {
return
}
for ((i,permission) in permissions.withIndex()) {
for (item in this.permissionTypes) {
if (permission == item.manifest_permission && i < grantResults.size) {
result += if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Pair(item.manifest_permission, PermissionResult.ACCESS_ALLOWED)
} else {
Pair(item.manifest_permission, PermissionResult.ACCESS_DENIED)
}
break
}
}
}
delegate?.permissionManagerDelegate(result)
}
}
semaphore.release()
}
}
}
액티비티에서의 사용(동일 단편화)
class BaseActivity : AppCompatActivity(), Permission.ManagerDelegate {
private lateinit var permissionManager: Permission.Manager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.base_activity)
permissionManager = Permission.Manager(arrayOf(PermissionType.Defined.camera, PermissionType.Defined.currentLocation), this)
permissionManager.check()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
permissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun permissionManagerDelegate(result: Array<Pair<String, Permission.PermissionResult>>) {
result.forEach {
println("!!! ${it.first} ${it.second}")
// when (it.second) {
// Permission.PermissionResult.NO_SYSTEM_FEATURE -> {
// }
//
// Permission.PermissionResult.ACCESS_DENIED -> {
// }
//
// Permission.PermissionResult.ACCESS_ALLOWED -> {
// }
// }
}
}
}
여기에서는 어떻게 이 일을 처리했는지 코드를 보여드리고 싶습니다.
public class CheckPermission {
public Context context;
public static final int PERMISSION_REQUEST_CODE = 200;
public CheckPermission(Context context){
this.context = context;
}
public boolean isPermissionGranted(){
int read_contact = ContextCompat.checkSelfPermission(context.getApplicationContext() , READ_CONTACTS);
int phone = ContextCompat.checkSelfPermission(context.getApplicationContext() , CALL_PHONE);
return read_contact == PackageManager.PERMISSION_GRANTED && phone == PackageManager.PERMISSION_GRANTED;
}
}
이 수업에서는 허가 여부를 확인하고 싶습니다.그렇지 않으면 다음과 같이 MainActivity의 허가를 호출합니다.
public void requestForPermission() {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {READ_CONTACTS, CALL_PHONE}, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
showMessageOKCancel("You need to allow access to both the permissions",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE},
PERMISSION_REQUEST_CODE);
}
}
});
return;
}
}
}
}
여기서 onCreate 메서드에서는 requestForPermission() 함수를 호출해야 합니다.
바로 그겁니다.또한 한 번에 여러 권한을 요청할 수도 있습니다.
업데이트: 전화에 대한 다른 사용자의 응답을 확인했습니다.super.onRequestPermissionResult()액티비티에서, 그리고 이것은 내가 언급한 요청 코드 문제를 수정하고 fragment의 onRequestPermissionResult를 호출합니다.
다음 내용을 무시합니다.
내게는 그것이 그 이름을 불렀어'onRequestPermissionResult액티비티 중 가장 중요한 것은fragment.requestPermission(...)그러나 잘못된 requestCode(111이 65647로 바뀐 이유는 무엇입니까?)와 함께 결과를 반환했습니다.난 절대 몰라.)
다행히 이 화면에서는 이것이 유일한 권한이기 때문에 저는 요청 코드를 무시합니다(왜 지금 이것이 올바르지 않은지 알 시간이 없습니다).
올바른 request Permissions를 호출해도 이 문제가 발생할 수 있다는 문제도 있습니다.문제는 부모 액티비티가 슈퍼를 호출하지 않고 이 메서드를 덮어쓸 수 있다는 것입니다.슈퍼를 추가하면 고정됩니다.
kotlin 사용자의 경우 onRequestPermissionResult를 덮어쓰지 않고 권한을 확인하고 검증하기 위한 내선번호입니다.
* @param permissionToValidate (request and check currently permission)
*
* @return recursive boolean validation callback (no need OnRequestPermissionResult)
*
* */
internal fun Activity.validatePermission(
permissionToValidate: String,
recursiveCall: (() -> Boolean) = { false }
): Boolean {
val permission = ContextCompat.checkSelfPermission(
this,
permissionToValidate
)
if (permission != PackageManager.PERMISSION_GRANTED) {
if (recursiveCall()) {
return false
}
ActivityCompat.requestPermissions(
this,
arrayOf(permissionToValidate),
110
)
return this.validatePermission(permissionToValidate) { true }
}
return true
}
언급URL : https://stackoverflow.com/questions/32714787/android-m-permissions-onrequestpermissionsresult-not-being-called
'programing' 카테고리의 다른 글
| 계산된 속성 및 VueX를 사용한 스타일 바인딩 (0) | 2022.07.04 |
|---|---|
| 렌더링 후 Vue 구성 요소 이벤트 (0) | 2022.07.04 |
| C 프리프로세서는 코멘트를 삭제합니까, 아니면 매크로를 먼저 전개합니까? (0) | 2022.07.04 |
| String에 있는 Java의 hashCode()는 왜 31을 승수로 사용합니까? (0) | 2022.07.04 |
| Http Servlet Request - 참조 URL을 얻는 방법 (0) | 2022.07.04 |