Preference fragment returns null on transaction - java

I'm trying to implement a preference fragment in my app, so I set preferences.xml file, fragment that is supposed to show preferences, and fragment transaction. When I try to show SettingsFragment, the app crashes with this error log:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:431)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:481)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:472)
at com.ikurek.pwr.MainActivity.onNavigationItemSelected(MainActivity.java:145)
at android.support.design.widget.NavigationView$1.onMenuItemSelected(NavigationView.java:153)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:810)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:957)
at android.support.design.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:328)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Why is this object null? How else am I supposed to set up a setting fragment? I know that solution for this is proably very simple, but somehow I cannot figure this out by myself. Here's my code:
Part that calls fragment transaction from MainActivity:
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment = null;
Class fragmentClass = null;
int id = item.getItemId();
if (id == R.id.nav_news) {
fragmentClass = NewsFragment.class;
} else if (id == R.id.nav_map) {
fragmentClass = CatFragment.class;
} else if (id == R.id.nav_buildings) {
fragmentClass = BuildingsFragment.class;
} else if (id == R.id.nav_settings) {
fragmentClass = SettingsFragment.class;
} else if (id == R.id.nav_info) {
fragmentClass = AppInfoFragment.class;
} else if (id == R.id.nav_bugreport) {
fragmentClass = ContactFragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frameLayoutForFragments, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
My preferences.xml:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="false"
android:key="saveLastPosition"
android:summary="1st check box"
android:title="Check"/>
<CheckBoxPreference
android:defaultValue="true"
android:key="keepScreenOn"
android:summary="2nd check box"
android:title="Box"/>
</PreferenceScreen>
And my SettingsFragment:
public class SettingsFragment extends PreferenceFragment {
public SettingsFragment() {
// Required empty public constructor
}
public static SettingsFragment newInstance() {
SettingsFragment fragment = new SettingsFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}

Well from what I can tell you are passing a null fragment to your fragment manager. As you will notice:
Fragment fragment = null;
Class fragmentClass = SettingsFragment.class;
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frameLayoutForFragments, fragment).commit();
You have:
Fragment fragment = null;
You never actually declare this as a SettingsFragment. You should either have:
Fragment fragment = new SettingsFragment();
Or declare it in your replace statement.
Class fragmentClass = SettingsFragment.class;
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frameLayoutForFragments, new SettingsFragment()).commit();

Related

How can I pass values from 1 fragment to another with Bundle()?

I found this code to pass the data from a fragment to another:
Fragment 1:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment2 fragment2 = new Fragment2();
Bundle bundle = new Bundle();
bundle.putString("data", data);
fragmentTransaction.replace(R.id.fragment_container, fragment2);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Fragment 2:
Bundle bundle = getArguments();
assert bundle != null;
String data = bundle.getString("data");
But I dont want to change the fragment. So I removed parts of it. But it doesnt work. Here my code:
Fragment 1:
public void openActifity2(){
Fragment_score fragment_score = new Fragment_score();
Bundle bundle = new Bundle();
bundle.putInt("FINISHED_LEVELS", finishedLevels);
bundle.putInt("FAILED_LEVELS", failedLevels);
bundle.putInt("SKIPPED_LEVELS", skippedLevels);
bundle.putInt("USED_HINTS", usedHints);
fragment_score.setArguments(bundle);
}
Fragment 2:
Bundle bundle = getArguments();
int finishedLevels = bundle.getInt("FINISHED_LEVELS");
int failedLevels = bundle.getInt("FINISHED_LEVELS");
int skippedLevels = bundle.getInt("FINISHED_LEVELS");
int usedHints = bundle.getInt("FINISHED_LEVELS");
Do I have to use the code I found on the internet or does my version work too?
I get this error when I open the second fragment:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.rexan_snerficonquiz, PID: 20931
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.Bundle.getInt(java.lang.String)' on a null object reference
at com.example.rexan_snerficonquiz.Fragment_score.onCreateView(Fragment_score.java:26)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
in order to avoid getting the error, try this
Bundle bundle = getArguments();
if(bundle != null){
int finishedLevels = bundle.getInt("FINISHED_LEVELS", "DEFAULT_VALUE");
int failedLevels = bundle.getInt("FINISHED_LEVELS", "DEFAULT_VALUE");
int skippedLevels = bundle.getInt("FINISHED_LEVELS", "DEFAULT_VALUE");
int usedHints = bundle.getInt("FINISHED_LEVELS", "DEFAULT_VALUE");
}
Based on your comments, you can change fragment in onOptionsItemSelected method
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_1) {
// add your action here that you want
return true;
}else if (id==R.id.action_2) {
// add your action here that you want
return true;
}
return super.onOptionsItemSelected(item);
}
If you change the fragments than your code will be working fine. But if you don't want to change fragments than 1) int finishedLevels = bundle.getInt("FINISHED_LEVELS", 0); OR 2) Instead of bundle use static global variables public static int finishedLevels = 0; in Fragment 1 and then simply get their value in Fragment 2 using class name reference.
Note: If you don't want to change the fragment and want values in Fragment 2 then i would recommend the static variables

java.lang.IllegalArgumentException: No view found for id 0x7f0700ca

I have a login fragment and want to replace the fragment after successful login.
I tried to replace the fragment inside the login fragment.
First I tried to call the following code inside the fragment (onActivityCreated,onCreateView,onStart)
getSupportFragmentManager().beginTransaction()
.replace(R.id.mainframelayout, ReservationFragment.newInstance())
.commitNow();
My second way was to try to call a activity method:
public void replaceFragments(Class fragmentClass) {
Fragment fragment = null;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.mainframelayout, fragment)
.commitNow();
}
Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.mainframelayout, LoginFragment.newInstance())
.commitNow();
}
}
public void replaceFragments(Class fragmentClass) {
Fragment fragment = null;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.mainframelayout, fragment)
.commitNow();
}
}
Activity xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mainframelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</FrameLayout>
The following error always came up:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.retrofit, PID: 15872
java.lang.IllegalArgumentException: No view found for id 0x7f07007c (com.example.retrofit:id/mainframelayout) for fragment
ReservationFragment{6e639e1} (59264633-2704-48d9-872d-551ef1142b68)
id=0x7f07007c}
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:305)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1185)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1816)
at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297)
at com.example.retrofit.MainActivity.replaceFragments(MainActivity.java:33)
at com.example.retrofit.ui.login.LoginFragment$1.onClick(LoginFragment.java:54)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 15872 SIG: 9
I've tried many things, but I haven't found a solution.
I understand that the fragment may not have access to the activity xml, but why the second way not work I dont understand.

Fragments gets null after orientation change

I am having troubles with my Fragments. I have four fragments which were in portrait mode.
Setting the fragments
public void setCorrectNavigationItem(int id) {
if (id == R.id.nav_auftragsbilder) {
fragment = new AuftragsbilderFragment();
id = R.id.nav_auftragsbilder;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else if (id == R.id.nav_auftragskorrektur) {
fragment = new AuftragskorrekturFragment();
id = R.id.nav_auftragskorrektur;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else if (id == R.id.nav_lagerplatz) {
fragment = new LagerplatzFragment();
id = R.id.nav_lagerplatz;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else if (id == R.id.nav_biegenstatus) {
fragment = new BiegestatusFragment();
id = R.id.nav_biegenstatus;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
_navigationView.setCheckedItem(id);
_selectedMenuItem = id;
SharedPreferences.Editor editor = menuCheck.edit();
editor.putInt("id", id);
editor.commit();
//Fragment öffnen
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.fragment_container, fragment);
ft.commit();
}
}
So in my fragment setting method I now have to set the orientation for each different fragment. I had to change my 'BiegestatusFragment' to landscape, there I am calling a method which is scanning barcodes, on intent result I set parameters in my Fragment.
Here is my Barcode-Scanning Activity
//Biegestatus Begleitschein-Barcodes
public void makeBiegestatusBegleitscheinBarcode() {
_lastAction = ACTION_BIEGESTATUS_BEGLEITSCHEIN_BARCODE;
if (!checkCameraPermission(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
} else {
Intent intent = new Intent(this, ContinuousCaptureActivity.class);
startActivityForResult(intent, 1);
}
}
Intent Result
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
ArrayList<String> begleitscheine = data.getStringArrayListExtra("begleitscheine");
if (resultCode == 1 && begleitscheine != null) {
//HERE IT IS NULL
((BiegestatusFragment) fragment).setBegleitscheine(begleitscheine);
} else {
Toast.makeText(this, "Scannen abgebrochen", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "Unbekannter Fehler aufgetreten, Entwickler kontaktieren.", Toast.LENGTH_LONG).show();
}
}
Fragments onCreateView
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_biegestatus, container, false);
_cardEdit = (EditText) v.findViewById(R.id.workerEdit);
_scrollViewArticles = (ScrollView) v.findViewById(R.id.scrollViewArticles);
_searchImageLayout = (LinearLayout) v.findViewById(R.id.searchImageLayout);
_personalNummer = (EditText) v.findViewById(R.id.workerEdit);
_progressBar = (LinearLayout) v.findViewById(R.id.progressBar);
_maschinenPicker = (NumberPicker) v.findViewById(R.id.maschinenPicker);
_pickerHolder = (LinearLayout) v.findViewById(R.id.pickerHolder);
_scanBegleitscheinBtn = (Button) v.findViewById(R.id.scanBegleitscheinBtn);
return v;
}
Method should be called
public void setBegleitscheine(ArrayList<String> begleitscheine) {
_begleitscheine = begleitscheine;
}
Now my Fragment is null because of the orientation change.
Removing the orientation setting methods solves my problem. But I need to have this fragment in landscape.
Error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: at.co.era.bilder.erabilderapp, PID: 21835
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=1, data=Intent { launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 }(has extras) }} to activity {at.co.era.bilder.erabilderapp/at.co.era.bilder.erabilderapp.HomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void at.co.era.bilder.erabilderapp.BiegestatusFragment.setBegleitscheine(java.util.ArrayList)' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:4520)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563)
at android.app.ActivityThread.-wrap22(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void at.co.era.bilder.erabilderapp.BiegestatusFragment.setBegleitscheine(java.util.ArrayList)' on a null object reference
at at.co.era.bilder.erabilderapp.HomeActivity.onActivityResult(HomeActivity.java:1130)
at android.app.Activity.dispatchActivityResult(Activity.java:7280)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4516)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563) 
at android.app.ActivityThread.-wrap22(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6776) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 
//Fragment öffnen
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.fragment_container, fragment);
ft.addToBackStack(null); // or you can give it any name instead of null to get the frament when poping the fragment from backstack
ft.commit();
}
You can force your activity not to reload after orientation changed by adding the following line in manifest to your activity tag
android:configChanges="orientation"
Inside fragment ,in onCreateView() try using :
setRetainInstance(true);
Check the doc here :
https://developer.android.com/reference/android/app/Fragment#setRetainInstance(boolean)

Android: Fragment is not attached to Activity error

So I'm working on an app and I had this part working for days, and out of no where it just stopped working for no reason...
I also had the same error when I was trying to use another headless fragment in my MainActivity, but ended up replacing the fragment with inner methods inside of the MainActivity and everything went back to working properly.
However, I can't rewrite every bit of code I have just to avoid using fragments. The fragment code is below.
public class IMEIFragment extends Fragment implements ActivityCompat.OnRequestPermissionsResultCallback{
public static final String TAG_IMEI = "IMEILoader";
protected Activity mActivity;
private String RecordedIMEI;
//public static final String CHECK_INTERNET = "network_connection";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return null; //Do we need this at all?
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = context instanceof Activity ? (Activity) context : null;
mActivity = activity;
}
//Is this needed?
#SuppressWarnings("deprecation")
#Override
public void onAttach(Activity activity) {
activity = getActivity();
if (isAdded() && activity != null) {
super.onAttach(activity);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
mActivity = activity;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onDetach() {
super.onDetach();
mActivity = null;
}
public String loadIMEI(Context context) {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has not been granted.
requestPermissions(context);
} else {
// READ_PHONE_STATE permission is already been granted.
RecordedIMEI = permissionGrantedActions(context);
}
if (RecordedIMEI != null) {
Log.i("loadIMEIService", "IMEI number returned!");
}
} else {
// READ_PHONE_STATE permission is already been granted.
RecordedIMEI = permissionGrantedActions(context);
}
if (RecordedIMEI != null) {
Log.i("loadIMEIService", "IMEI number returned!");
}
return RecordedIMEI;
}
private void requestPermissions(Context context) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
Log.i("loadIMEIService", "READ_PHONE_STATE permission not granted, asking for it...");
// TODO create proper notification content
PermissionHelper.requestPermissions(((PriceActivity) getActivity()),
new String[]{Manifest.permission.READ_PHONE_STATE},
Constants.PERM_REQUEST_PHONE_STATE,
getString(R.string.notify_perm_title),
getString(R.string.notify_perm_body),
R.drawable.ic_security);
}
}
// Callback received when a permissions request has been completed.
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
boolean isGranted = false;
for (int i = 0; i < grantResults.length; i++)
if (permissions[i].equals(Manifest.permission.READ_PHONE_STATE) && (grantResults[i] == PackageManager.PERMISSION_GRANTED))
isGranted = true;
if (isGranted) {
Context context = getActivity().getApplicationContext();
permissionGrantedActions(context);
}
else
Log.w("loadIMEIService", "READ_PHONE_STATE permission not granted. loadIMEI will not be available.");
}
public String permissionGrantedActions(Context context) {
//Have an object of TelephonyManager
TelephonyManager tm =(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
//Get IMEI Number of Phone
String IMEINumber = tm.getDeviceId();
if(IMEINumber != null) {
Log.i("loadIMEIService", "IMEI number recorded!");
}
return IMEINumber;
}
}
Error is below:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.project1, PID: 5498
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.project1/com.android.project1.main.MainActivity}: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity
at android.app.Fragment.getResources(Fragment.java:805)
at android.app.Fragment.getString(Fragment.java:827)
at com.android.project1.fragments.IMEIFragment.requestPermissions(IMEIFragment.java:107)
at com.android.project1.fragments.IMEIFragment.loadIMEI(IMEIFragment.java:80)
at com.android.project1.main.MainActivity.onCreate(MainActivity.java:108)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
And here's the relevant part of my MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDeviceCode = (TextView) findViewById(R.id.device_code);
// Initializing headless fragment
mFragment =
(IMEIFragment) getFragmentManager()
.findFragmentByTag("IMEILoader");
if (mFragment == null) {
mFragment = new IMEIFragment();
getFragmentManager().beginTransaction()
.add(mFragment, "IMEILoader").commit();
}
if (mFragment != null) {
mNumber = mFragment.loadIMEI(MainActivity.this);
mDeviceCode.setText(Html.fromHtml("<b>IMEI</b>: " + mNumber));
}
I literally had the exact same code working for over a week. Anyone knows what could be the problem?
Edit 1: The error is pointing to requestPermissions inside my fragment
Fragments should be self contained as much as possible. You are calling directly into your IMEIFragment from the activity,
Caused by: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity
at android.app.Fragment.getResources(Fragment.java:805)
at android.app.Fragment.getString(Fragment.java:827)
at com.android.project1.fragments.IMEIFragment.requestPermissions(IMEIFragment.java:107)
at com.android.project1.fragments.IMEIFragment.loadIMEI(IMEIFragment.java:80)
at com.android.project1.main.MainActivity.onCreate(MainActivity.java:108)
You can't do that. Adding the fragment via a transaction from the activity is an asynchronous operation. E.g., when the commit() method completes, the fragment is not initialized. Moreover, you have no way of knowing when it's initialized. That's why it should be self contained. The fragment decides when to call loadIMEI(), not the activity.
If you really need it to be initiated by the activity, you can add a callback from the fragment to the activity like,
void onFragmentReady(Fragment f);
Or something.
And yes, onCreateView() should return something. If your fragment really doesn't have any UI at all, you don't need it to be a fragment.

java.lang.NullPointerException - error when logout Android

I followed this tutorial (http://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/) for creating member system with login and logout feature. The problem is when logout it doesn't work. I'm creating logout in Fragment Navigation Drawer Menu.
This My Activity.
public class HomeActivity extends AppCompatActivity implements FragmentDrawer.FragmentDrawerListener {
private static String TAG = HomeActivity.class.getSimpleName();
private Toolbar mToolbar;
private FragmentDrawer drawerFragment;
private SQLiteHandler db;
private SessionManager session;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
drawerFragment = (FragmentDrawer)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
drawerFragment.setDrawerListener(this);
// display the first navigation drawer view on app launch
displayView(0);
}
private void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new HomeFragment();
title = getString(R.string.title_home);
break;
case 1:
captureImage();
break;
case 2:
fragment = new ReportsFragment();
title = getString(R.string.title_reports);
break;
case 3:
title = getString(R.string.title_settings);
break;
case 4:
logoutUser();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle(title);
}
}
private void logoutUser() {
session.setLogin(false);
db.deleteUsers();
// Launching the login activity
Intent intent = new Intent(HomeActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}
And this is error log.
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.company.report.activity.HomeActivity.logoutUser(HomeActivity.java:251)
at com.company.report.activity.HomeActivity.displayView(HomeActivity.java:124)
at com.company.report.activity.HomeActivity.onDrawerItemSelected(HomeActivity.java:99)
at com.company.report.activity.FragmentDrawer$1.onClick(FragmentDrawer.java:79)
at com.company.report.activity.FragmentDrawer$RecyclerTouchListener.onInterceptTouchEvent(FragmentDrawer.java:160)
at android.support.v7.widget.RecyclerView.dispatchOnItemTouchIntercept(RecyclerView.java:1986)
at android.support.v7.widget.RecyclerView.onInterceptTouchEvent(RecyclerView.java:2027)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1629)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1912)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371)
at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1860)
at android.view.View.dispatchPointerEvent(View.java:5721)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2890)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2466)
at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2475)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Looks like sessionand db are never initialized. Initialize it and the error will be gone.

Categories