矛盾を引き起こす奇妙な問題があります。ネイティブFragments
に切り替えて修正する必要がありましたが、バグがあります。
私の元の問題:v4 Fragments.
を使用してナビゲーションドロワーをセットアップしました。フラグメントの1つで許可を求めるためにActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1);
を呼び出しますが、許可を許可または拒否しても何も起こりません。コールバックonRequestPermissionsResult()
は呼び出されません。代わりに、フラグメントが添付されているアクティビティで呼び出されます。役に立たないが、フラグメントで動作するためにコールバックが必要です。
これを念頭に置いて、FragmentCompat
を使用する必要があると言われましたが、それはnative Fragments (v13+)
でのみ動作するため、ナビゲーションドロワーをv4サポートライブラリフラグメントではなくネイティブフラグメントから動作するように変更しました。 ただし、AppCompatActivityを使用しているため、addToBackStack()
や前のフラグメントに戻るなど、特定の機能が動作しません。
簡単に言えば、誰もがv4.Fragment
を使用し、Fragment
で許可を求め、Fragment
にコールバックを取得する方法を知っていますか?これはAndroidのバグであり、まだ対処されていないように感じますが、100%ではありません。
私のコードを見る必要があるかどうかを教えてください、それは実行時のアクセス許可に必要な標準的なメソッドです。私の理解からはうまくいきませんが、v4 Fragmentsで作業したいと思います。
この動作は、v4 Fragmentサポートクラス FragmentのrequestPermissions に存在するようです。 Activity/FragmentCompatの実装は、11〜23のAPIレベルで拡張機能を備えたネイティブクラスを使用したい人のために存在します。
これを親アクティビティに追加するとうまくいきます:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
ソース: https://code.google.com/p/Android/issues/detail?id=189121#c5
fragment v4
でpermissionResultを取得する必要がある場合は、必ず使用してください
Fragment.requestPermission(String[], int);
の代わりに
AppCompat.requestPermission(Activity, String[], int)
this answer!
コードのこの部分を使用できます
requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS}, PERMISSION_REQUEST_CODE);
サポートフラグメント内のアクセス許可を確認し、コールバックを取得する必要があるときに、最近同じ状況に直面しました。
ContextCompat
をcheckSelfPermission
に使用してから、@ NasaGeekがAndroid.support.v4.app.Fragment
のrequestPermissions
を呼び出して許可を要求し、onRequestPermissionsResult
にコールバックすることができたv4フラグメント。
お役に立てれば。
ありがとう。
現時点では、最も安定したソリューションは手作業で行っています。私自身は、親フラグメントから子フラグメントに通知するだけで解決しました。
if (fragment.getParentFragment() != null) {
Fragment parentFragment = fragment.getParentFragment();
try {
ChildFragmentPermissionRegistry registry = (ChildFragmentPermissionRegistry) parentFragment;
registry.registerPermissionListener((ChildFragmentPermissionCallback) fragment);
parentFragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
} catch (ClassCastException e) {
Log.e(PermissionVerifier.class.getSimpleName(), e.getMessage());
}
} else {
fragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
}
親フラグメントがChildFragmentPermissionRegistryインターフェースを実装し、子フラグメントを登録する場合、
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (callback != null) {
callback.onRequestPermissionsResult(requestCode, permissions, grantResults);
callback = null;
}
}
および子フラグメントはChildFragmentPermissionCallbackを実装します
インターフェイスは次のようなものです。
public interface ChildFragmentPermissionCallback {
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
}
public interface ChildFragmentPermissionRegistry {
void registerPermissionListener(ChildFragmentPermissionCallback callback);
}
v4.Fragmentはうまく機能します。 v4.Fragmentのネストされたフラグメントに問題があります。許可が求められますが、ネストされたフラグメントでonRequestPermissionsResult()コールバックが呼び出されることはありません!
Googleで最近修正されたかどうかはわかりませんが、何のトリックもせずに期待どおりの結果を得ることができます。
最も重要なことは、アクティビティでsuper.onRequestPermissionsResult(requestCode, permissions, grantResults);
を呼び出すことです。そのため、フラグメントから要求された場合、結果をフラグメントに渡します。
だから、私がやっていることは:
1)フラグメントで、v4 fragment.requestPermissions(permissions, requestCode)
を使用して許可を求めます
2)アクティビティのonRequestPermissionsResultで、super.onRequestPermissionsResult(requestCode, permissions, grantResults);
を呼び出す必要があります
3)フラグメントのonRequestPermissionsResultに、結果を処理するコードを記述します。
私の場合、フラグメントに許可を要求し、フラグメントで応答を取得する必要もあります。
しかし、Android 8.1で実行されている私の電話
これを確認するためにもう1つの条件を追加する必要がありました
だから最終的には私の解決策があります
private void doOnWazeButtonClick()
{
int permissionStatus = PackageManager.PERMISSION_DENIED;
if (getContext() != null)
{
permissionStatus = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionStatus == PackageManager.PERMISSION_GRANTED)
{
showContentWaze();
}
else
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
Objects.requireNonNull(getActivity()).requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
}
else
{
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
}
}
}