许可请求

时间:2017-07-26 09:19:36

标签: android android-fragments fragmenttransaction

在第一个应用启动时,当用户想通过点击按钮开始操作时,我的应用会请求一些权限。在用户授予权限后,应该替换我的MainActivity中的Fragment。

我的SecondFragment上的所有内容都被调用(onCreate(), onStart(), onResume(),...),但它不会显示出来。

在第二个应用程序启动时,当不需要再次请求权限时,一切正常并显示SecondFragment。

两种方式都使用相同的代码:

/**
 * This method starts the second fragment.
 */
private void startSecondView(){

    final SecondFragment frag = new SecondFragment();
    final FragmentTransaction ft =  getFragmentManager().beginTransaction();
    ft.replace(R.id.container, frag);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    ft.addToBackStack(null);
    ft.commit();
}

我的片段放在FrameLayout中。

更新 我很快尝试构建一个虚拟应用程序来重现此错误。 不完全相同的行为,但在请求权限后替换Fragment时虚拟应用程序崩溃。在第二个应用程序开始everthing工作正常。

这是一些代码。

activity_main.xml中

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

<RelativeLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent">

    <!-- The main content view -->
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@+id/container"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 tools:ignore="MergeRootFrame"/>
</RelativeLayout>

<!-- The navigation drawer -->
<android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_header"
        app:menu="@menu/navigation_menu">

    <android.support.design.widget.NavigationView
            android:id="@+id/navigation_drawer_bottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            app:elevation="0dp"
            app:menu="@menu/menu_navigation_dawer_bottom"/>

</android.support.design.widget.NavigationView>

MainActivity

   public class MainActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }

        @Override
        protected void onResume(){
            super.onResume();

            final FirstFragment frag = new FirstFragment();
            frag.setRetainInstance(true);
            getSupportFragmentManager().beginTransaction()
                        .add(R.id.container, frag)
                        .commit();

        }
    }

FirstFragment

public class FirstFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private static final int PERMISSIONS_REQUEST = 12;

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public FirstFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment FirstFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static FirstFragment newInstance(String param1, String param2) {
        FirstFragment fragment = new FirstFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_first, container, false);

        Button button = (Button) rootView.findViewById(R.id.btnStartTour);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checkRequirementsAndStart();
            }
        });

        // Inflate the layout for this fragment
        return rootView;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    private void checkRequirementsAndStart(){
        final String[] checkPermissions = new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.SEND_SMS,
                Manifest.permission.CALL_PHONE
        };


        if(hasPermissions(getActivity(), checkPermissions)) {
            startSecondView();
        } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
            requestPermissions(checkPermissions, PERMISSIONS_REQUEST);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == PERMISSIONS_REQUEST) {
            for(int x = 0; x < permissions.length; x++){
                if(grantResults[x] != PackageManager.PERMISSION_GRANTED){
                    return; //Abort if permission is missing
                }
            }
            startSecondView();
        }
    }

    private void startSecondView(){
        final SecondFragment frag = new SecondFragment();
        final FragmentTransaction ft =  getFragmentManager().beginTransaction();
        ft.replace(R.id.container, frag);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.addToBackStack(null);
        ft.commit();
    }

    public boolean hasPermissions(Context context, String... permissions) {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
            for (String permission : permissions) {
                if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
        }
        return true;
    }
}

SecondFragment

public class SecondFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public SecondFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment SecondFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static SecondFragment newInstance(String param1, String param2) {
        SecondFragment fragment = new SecondFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }
}

更新

虚拟应用程序错误:

  

致命的例外:主要                     处理:com.example.permissiontest,PID:15228                     java.lang.RuntimeException:传递结果失败ResultInfo {who = @ android:requestPermissions:,request = 12,   result = -1,data = Intent {   act = android.content.pm.action.REQUEST_PERMISSIONS(有额外的)}}到   活动   {com.example.permissiontest / com.example.permissiontest.MainActivity}:   java.lang.IllegalStateException:之后无法执行此操作   的onSaveInstanceState                         在android.app.ActivityThread.deliverResults(ActivityThread.java:3699)                         在android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)                         在android.app.ActivityThread.-wrap16(ActivityThread.java)                         在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1393)                         在android.os.Handler.dispatchMessage(Handler.java:102)                         在android.os.Looper.loop(Looper.java:148)                         在android.app.ActivityThread.main(ActivityThread.java:5417)                         at java.lang.reflect.Method.invoke(Native Method)                         在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)                         在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)                      引起:java.lang.IllegalStateException:在onSaveInstanceState之后无法执行此操作                         在android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1842)                         在android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1860)                         在android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:650)                         在android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:609)                         在com.example.permissiontest.MainActivity.startSecondView(MainActivity.java:75)                         在com.example.permissiontest.MainActivity.onRequestPermissionsResult(MainActivity.java:40)                         在android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6582)                         在android.app.Activity.dispatchActivityResult(Activity.java:6460)                         在android.app.ActivityThread.deliverResults(ActivityThread.java:3695)                         在android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)                         在android.app.ActivityThread.-wrap16(ActivityThread.java)                         在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1393)                         在android.os.Handler.dispatchMessage(Handler.java:102)                         在android.os.Looper.loop(Looper.java:148)                         在android.app.ActivityThread.main(ActivityThread.java:5417)                         at java.lang.reflect.Method.invoke(Native Method)                         在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)                         在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

0 个答案:

没有答案