android - Fragment not shown after permission request -
on first app start app requesting permissions when user wants start action hitting button. after user has granted permissions fragment in mainactivity should replaced.
everything called (oncreate(), onstart(), onresume(),...) on secondfragment not show up.
on second app start, when there no need ask permissions again, works fine , secondfragment displayed.
the same code used in both ways:
/** * method starts 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(); } my fragments placed in framelayout.
update tried build dummy app reproduce error. not same behavior dummy app crashes when replacing fragment after requesting permission. on second app start everthing works fine.
here code.
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"> <!-- 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> <!-- 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 match // 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 , change types of parameters private string mparam1; private string mparam2; public firstfragment() { // required empty public constructor } /** * use factory method create new instance of * fragment using provided parameters. * * @param param1 parameter 1. * @param param2 parameter 2. * @return new instance of fragment firstfragment. */ // todo: rename , change types , 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 layout 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 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) { (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 match // fragment initialization parameters, e.g. arg_item_number private static final string arg_param1 = "param1"; private static final string arg_param2 = "param2"; // todo: rename , change types of parameters private string mparam1; private string mparam2; public secondfragment() { // required empty public constructor } /** * use factory method create new instance of * fragment using provided parameters. * * @param param1 parameter 1. * @param param2 parameter 2. * @return new instance of fragment secondfragment. */ // todo: rename , change types , 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 layout 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(); } } update
error of dummy app:
fatal exception: main process: com.example.permissiontest, pid: 15228 java.lang.runtimeexception: failure delivering result resultinfo{who=@android:requestpermissions:, request=12, result=-1, data=intent { act=android.content.pm.action.request_permissions (has extras) }} activity {com.example.permissiontest/com.example.permissiontest.mainactivity}: java.lang.illegalstateexception: can not perform action after 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) @ 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) caused by: java.lang.illegalstateexception: can not perform action after 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) @ 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)
Comments
Post a Comment