При первом запуске приложения мое приложение запрашивает некоторые разрешения, когда пользователь хочет начать действие, нажав кнопку. После того, как пользователь предоставил разрешения, фрагмент в моей MainActivity должен быть заменен.
Все называется (onCreate(), onStart(), onResume(),...
) в моем SecondFragment, но не отображается.
При втором запуске приложения, когда нет необходимости снова запрашивать разрешения, все работает нормально, и отображается 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.
Обновить Я быстро попытался создать фиктивное приложение для воспроизведения этой ошибки. Не совсем то же самое поведение, но фиктивное приложение вылетает при замене фрагмента после запроса разрешения. При втором запуске приложения все работает нормально.
Вот некоторый код.
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();
}
}
Первый фрагмент
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;
}
}
Второй фрагмент
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();
}
}
Обновить
Ошибка фиктивного приложения:
Пожалуйста, поделитесь всем классом фрагментов.