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 를 사용해야합니다 .
- 에 때 android.support.v4.app.Fragment , 당신은 단순히 사용해야 requestPermissions을 (이 android.support.v4.app.Fragment의 인스턴스 방법입니다)
프래그먼트에서 ActivityCompat.requestPermissions를 호출하면 프래그먼트가 아닌 활동에서 onRequestPermissionsResult 콜백이 호출됩니다.
도움이 되었기를 바랍니다!
당신은 이것을 시도 할 수 있습니다 :
requestPermissions(permissions, PERMISSIONS_CODE);
프래그먼트에서이 코드를 호출하는 경우 고유 한 requestPermissions 메소드가 있습니다. 문제는 정적 메소드를 호출하는 것입니다.
onRequestPermissionsResult()
조각에 원하는 경우 프로 팁 :FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)
나는 그것이 잘 작동하기를 바랍니다
활동 :
ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE);
조각의 경우 :
requestPermissions(permissionsList,REQUEST_CODE);
이 문제도 발생했습니다. 기록 / 최근에없는 권한을 처리하는 활동을 원하는 경우 AndroidManifest.xml
항목 을 변경하려는 유혹을 받습니다.
당신이 활동을 설정하면 호출하는 것이 requestPermissions
나 AppCompatActivity.requestPermissions
에
android:noHistory="true"
android:excludeFromRecents="true"
당신의 AndroidManifest.xml
그때에 onRequestPermissionsResult()
호출되지 않습니다. 활동이 Activity
또는 에서 파생 된 경우에 해당됩니다 AppCompatActivity
.
'AndroidManifest.xml'에서 두 플래그를 모두 제거하고 finishAndRemoveTask()
대신 활동을 완료하면이 문제를 해결할 수 있습니다 .
당신이있는 경우 onRequestPermissionsResult
활동과 조각 모두에서 전화로 확인 super.onRequestPermissionsResult
활동한다. 프래그먼트에는 필요하지 않지만 활동 중입니다.
조각 안에서는 다음을 호출해야합니다.
FragmentCompat.requestPermissions(permissionsList, RequestCode)
아니:
ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode);
조각으로 requestPermissions를 사용하는 경우 3 대신 2 개의 매개 변수를 사용합니다.
사용해야합니다 requestPermissions(permissions, PERMISSIONS_CODE);
어떤 이유로 수퍼를 호출하지 않는 외부 라이브러리에있는 사용자 정의 활동을 확장 한 경우 활동 onRequestPermissionsResult에서 조각 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);
}
...
당신은이 checkPermissions가 에서 사전 산들 장치에 대한 기능 FragmentCompat . 나는 이렇게 사용한다 :
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);
}
이 문제는 실제로 NestedFragments로 인해 발생했습니다. 기본적으로 대부분의 프래그먼트는 HostedFragment를 확장하여 CompatFragment를 확장합니다. 이러한 중첩 된 조각으로 인해 프로젝트의 다른 개발자가 문제를 해결했습니다.
그는 비트 스위칭과 같은 저수준 작업을 수행 하여이 작업을 수행 했으므로 실제 최종 솔루션을 너무 확신하지 못합니다.
/* 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);
}
프래그먼트에서이 코드를 호출하는 경우 고유 한 requestPermissions 메소드가 있습니다.
기본 개념은, 당신이 활동에 있다면, 전화
ActivityCompat.requestPermissions(this,
permissionsList,
permissionscode);
조각에 있다면 전화하십시오.
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();
}
}
}
위의 답변에 따라 모든 것을 확인하기 전에 요청 코드가 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();
}
}
goodgamerguy의 답변을 바탕으로 해결책은 다음과 같습니다.
myFragment.this.requestPermissions(....)
이것을 달성하기위한 놀라운 해결책이 있습니다.
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);
이제 이것은 조각 또는 활동에서 기본 활동이 호출 될 때마다 발생합니다.
감사
사용할 수 있습니다 requestPermissions(PERMISSIONS, MULTIPLE_PERMISSIONS_CODE);
. v4를 사용중인 경우 FragmentCompat를 사용하지 마십시오.
세부
- 코 틀린 1.2.70
- minSdkVersion 19에서 체크인 됨
- 안드로이드 스튜디오 3.1.4
연산
모듈 -카메라, 위치, ....
- hasSystemFeature가 있는지 확인하십시오 ( 전화에 모듈 이있는 경우 ).
- 사용자가 모듈에 액세스 할 수 있는지 확인
- 권한 요청 보내기 ( 모듈 사용 을 허용하도록 사용자에게 요청 )
풍모
- 활동 및 조각으로 작업
- 결과 응답이 하나만 있습니다
- 한 번의 요청으로 여러 모듈 을 확인할 수 있습니다
해결책
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 -> {
// }
// }
}
}
}
업데이트 :super.onRequestPermissionResult()
Activity 호출 에 대한 다른 사람의 대답을 보았고 내가 언급 한 요청 코드 문제를 해결하고 조각의 onRequestPermissionResult를 호출합니다 .
이 물건을 무시하십시오 :
나를 위해 onRequestPermissionResult
전화 fragment.requestPermission(...)
를 걸었 음에도 불구하고 Activity of the call을 호출했지만 잘못된 requestCode (111은 65647로 바뀌어 왜 ????를 알 수 없음)로 결과를 반환했습니다.
운 좋게 이것은 우리가 그 화면에서 요청하는 유일한 권한이므로 요청 코드를 무시합니다 (지금 왜 이것이 올바르지 않은지 알아낼 시간이 없습니다)
여기에 내가 어떻게 관리했는지 내 코드를 보여주고 싶습니다.
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 () 함수를 호출해야합니다.
한 번에 여러 권한을 요청할 수도 있습니다.
'Programing' 카테고리의 다른 글
이전 bash 명령의 인수를 어떻게 기억합니까? (0) | 2020.03.24 |
---|---|
Javascript에서 조건부로 객체를 멤버에 추가하는 방법은 무엇입니까? (0) | 2020.03.24 |
Maven 부모 pom 대 모듈 pom (0) | 2020.03.24 |
PHP에서 사용자의 올바른 IP 주소를 검색하는 가장 정확한 방법은 무엇입니까? (0) | 2020.03.24 |
기다리지 않고 C #에서 비동기 메서드를 안전하게 호출하는 방법 (0) | 2020.03.24 |