可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm updating our app to use the new M Permissions system. It is all working besides the onRequestPermissionsResult(). I need to check a permission on a button press, and if it is successful, send a text message. When I grant permission to do it, the dialog closes, but it doesn't trigger the Send Text until I press the button again.
I've debugged and set breakpoints in the onRequestPermissionsResult() method but it never goes into it.
This method gets called first:
private void askForPermission() { String[] permissions = new String[]{Manifest.permission.SEND_SMS}; ActivityCompat.requestPermissions(getActivity(), permissions, PERMISSIONS_CODE); }
And then my callback looks like this:
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSIONS_CODE) { for (int i = 0; i
Has anybody ran into a similar issue? Appreciate any help with this. Thanks
回答1:
I ran into the same issue and I just found the solution. When using the Support library, you have to use the correct method calls. For example:
- When in AppCompatActivity, you should use ActivityCompat.requestPermissions;
- When in android.support.v4.app.Fragment, you should use simply requestPermissions (this is an instance method of android.support.v4.app.Fragment)
If you call ActivityCompat.requestPermissions in a fragment, the onRequestPermissionsResult callback is called on the activity and not the fragment.
Hope this helps!
回答2:
You can try this:
requestPermissions(permissions, PERMISSIONS_CODE);
If you are calling this code from a fragment it has it's own requestPermissions method. I believe the problem is that you are calling static method.
Pro Tip if you want the onRequestPermissionsResult()
in a fragment: FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)
回答3:
I encountered this problem too. If you want the activity that handles permissions not in the history/recents, then you will be tempted to change your AndroidManifest.xml
entry.
If you set the activity that you call requestPermissions
or AppCompatActivity.requestPermissions
with
android:noHistory="true" android:excludeFromRecents="true"
in your AndroidManifest.xml
then onRequestPermissionsResult()
will not be called. This is true if your Activity is derived from Activity
or AppCompatActivity
.
This can be fixed by removing both flags from 'AndroidManifest.xml' and finishing your activity with finishAndRemoveTask()
instead.
回答4:
I hope it works fine
For Activity :
ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE);
For Fragment :
requestPermissions(permissionsList,REQUEST_CODE);
回答5:
If you have onRequestPermissionsResult
in both activity and fragment, make sure to call super.onRequestPermissionsResult
in activity. It is not required in fragment, but it is in activity.
回答6:
Inside fragment, you need to call:
FragmentCompat.requestPermissions(permissionsList, RequestCode)
Not:
ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode);
回答7:
If you are using requestPermissions in fragment, it accepts 2 parameters instead of 3.
You should use requestPermissions(permissions, PERMISSIONS_CODE);
回答8:
If for some reason you have extended a custom Activity located in some external library that do not call the super you will need to manually call the Fragment super.onRequestPermissionsResult yourself in your Activity 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); } ...
回答9:
You have the checkPermissions function for pre Marshmallow devices in FragmentCompat. I use like this:
FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
回答10:
I have found out that is important where you call android.support.v4.app.Fragment.requestPermissions
.
If you do it in onCreate()
, onRequestPermissionsResult()
is never called.
Solution: Call it in 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); }
回答11:
/* 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);
回答12:
This issue was actually being caused by NestedFragments. Basically most fragments we have extend a HostedFragment which in turn extends a CompatFragment. Having these nested fragments caused issues which eventually were solved by another developer on the project.
He was doing some low level stuff like bit switching to get this working so I'm not too sure of the actual final solution
回答13:
This will work..
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); }
回答14:
If you are calling this code from a fragment it has it’s own requestPermissions method.
So basic concept is, If you are in an Activity, then call
ActivityCompat.requestPermissions(this, permissionsList, permissionscode);
and if in a Fragment, just call
requestPermissions(permissionsList, permissionscode);
回答15:
Before you check everything according to above answers, make sure your request code is not 0!!!
check the code of onRequestPermissionsResult() in FragmentActivity.java:
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); } } }
回答16:
Based on goodgamerguy's answer the solution is:
myFragment.this.requestPermissions(....)
回答17:
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(); } }
回答18:
You can use requestPermissions(PERMISSIONS, MULTIPLE_PERMISSIONS_CODE);
. Do not use FragmentCompat if you are using v4.
回答19:
UPDATE: saw someone else's answer about calling super.onRequestPermissionResult() in Activity and that fixes the request code issue I mentioned and calls the fragment's onRequestPermissionResult.
ignore this stuff:
For me it was calling the onRequestPermissionResult of the Activity despite me calling fragment.requestPermission(...), BUT it returned the result with an incorrect requestCode (111 turned into 65647 why ??? I'll never know).
Luckily this is the only permission we request on that screen so I just ignore the request code (don't have time to figure out why it's not correct right now)
回答20:
I have an amazing solution to achieve this make a BaseActivity like this.
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(); } } } }
}
Now yo can call the code to ask for permission like this
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
Now every time this happens anywhere whether in your fragment or in any activity the base activity would be called.
Thanks