I'm new to Android, this is my first project, I've spent a while trying to solve this now and have hit a bit of a dead end. I'm wanting to open a fragment using ViewPager, and then access the fragment from the Activity it was opened from. I have tried creating the fragment in the Activity rather than the ViewPager but that throws up a different error.
public class TorchActivity extends SherlockFragmentActivity {
private static TorchFragment torchFrag;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
}
public static class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager mgr) {
super(mgr);
}
@Override
public int getCount() {
return (2);
}
@Override
public Fragment getItem(int position) {
if(position == 0){
torchFrag = new TorchFragment();
return torchFrag;
}else{
ColourPickerFragment colourPickerFrag = new ColourPickerFragment();
return colourPickerFrag;
}
}
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
When I come to access the fragment later on in the same Activity I get a NullPointerException.
@Override
public void lightSensorCheck(boolean isThereALightSensor) {
torchFrag.setIsThereALightSensor(isThereALightSensor);
}
In the fragment:
public void setIsThereALightSensor(boolean isThereALightSensor) {
this.isThereALightSensor = isThereALightSensor;
}
It works fine if I take the ViewPager code out and run it, any help is appreciated.
02-17 16:01:30.132: E/AndroidRuntime(32006): FATAL EXCEPTION: main
02-17 16:01:30.132: E/AndroidRuntime(32006): java.lang.RuntimeException: Unable to start activity ComponentInfo{uk.co.bimrose.android.survivaltorch/uk.co.bimrose.android.survivaltorch.TorchActivity}: java.lang.NullPointerException
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2517)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2574)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.ActivityThread.access$600(ActivityThread.java:162)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1413)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.os.Handler.dispatchMessage(Handler.java:99)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.os.Looper.loop(Looper.java:158)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.ActivityThread.main(ActivityThread.java:5789)
02-17 16:01:30.132: E/AndroidRuntime(32006): at java.lang.reflect.Method.invokeNative(Native Method)
02-17 16:01:30.132: E/AndroidRuntime(32006): at java.lang.reflect.Method.invoke(Method.java:525)
02-17 16:01:30.132: E/AndroidRuntime(32006): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
02-17 16:01:30.132: E/AndroidRuntime(32006): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:843)
02-17 16:01:30.132: E/AndroidRuntime(32006): at dalvik.system.NativeStart.main(Native Method)
02-17 16:01:30.132: E/AndroidRuntime(32006): Caused by: java.lang.NullPointerException
02-17 16:01:30.132: E/AndroidRuntime(32006): at uk.co.bimrose.android.survivaltorch.TorchActivity.lightSensorCheck(TorchActivity.java:199)
02-17 16:01:30.132: E/AndroidRuntime(32006): at uk.co.bimrose.android.survivaltorch.LightFragment.updateLightSensorStatus(LightFragment.java:180)
02-17 16:01:30.132: E/AndroidRuntime(32006): at uk.co.bimrose.android.survivaltorch.LightFragment.sensorCheck(LightFragment.java:134)
02-17 16:01:30.132: E/AndroidRuntime(32006): at uk.co.bimrose.android.survivaltorch.LightFragment.onAttach(LightFragment.java:65)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:883)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:556)
02-17 16:01:30.132: E/AndroidRuntime(32006): at uk.co.bimrose.android.survivaltorch.TorchActivity.onStart(TorchActivity.java:109)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1239)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.Activity.performStart(Activity.java:5205)
02-17 16:01:30.132: E/AndroidRuntime(32006): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2490)
02-17 16:01:30.132: E/AndroidRuntime(32006): ... 11 more
Here is the code for the fragment:
public class TorchFragment extends SherlockFragment implements OnClickListener {
private Button buttonOn;
private Button buttonSos;
private Button buttonOff;
private TextView luxStatic;
private TextView luxMessage;
private TextView timerStatic;
private TextView timerMessage;
private TextView batteryStatic;
private TextView batteryMessage;
private TextView shutdownMessage;
private TextView shutdownMessageStatic;
private TextView timesUsed;
private ImageView img;
private TextView heading;
private SharedPreferences prefs;
private int lightSensitivity;
private boolean timerOn;
private int batteryPct;
private boolean isThereALightSensor;
public static int serviceCount;
private AlertResetListener alertResetListener;
private ServiceListener sListener;
private SetDataListener sDListener;
private ClearShutdownMessageListener cSMListener;
private ColourSchemeListener cSListener;
private int[] colourScheme = new int[4];
private LinearLayout dataCompassLayout;
int x = 0;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Makes sure that the container activity has implemented the callback interface
try {
alertResetListener = (AlertResetListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement AlertReset");
}
// start / stop service
try {
sListener = (ServiceListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement ServiceListener");
}
// Clear the dataFragment
try {
sDListener = (SetDataListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement SetDataListener");
}
// Clear the dataFragment shutdown message
try {
cSMListener = (ClearShutdownMessageListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement ClearShutdownMessageListener");
}
// Get the colourscheme
try {
cSListener = (ColourSchemeListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement ColourSchemeListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.torchfrag, parent, false);
buttonOn = (Button) result.findViewById(R.id.button_on);
buttonSos = (Button) result.findViewById(R.id.button_sos);
buttonOff = (Button) result.findViewById(R.id.button_off);
buttonOn.setText("ON");
buttonOff.setText("OFF");
buttonSos.setText("SOS");
luxStatic = (TextView) result.findViewById(R.id.luxstatic);
luxMessage = (TextView) result.findViewById(R.id.luxmessage);
timerStatic = (TextView) result.findViewById(R.id.timerstatic);
timerMessage = (TextView) result.findViewById(R.id.timermessage);
batteryStatic = (TextView) result.findViewById(R.id.batterystatic);
batteryMessage = (TextView) result.findViewById(R.id.batterymessage);
shutdownMessage = (TextView) result.findViewById(R.id.shutdownmessage);
shutdownMessageStatic = (TextView) result.findViewById(R.id.shutdownmessagestatic);
timesUsed = (TextView) result.findViewById(R.id.timesused);
timesUsed.setText(Integer.toString(TorchActivity.timesUsed));
//Compass
img = (ImageView) result.findViewById(R.id.compass);
heading = (TextView) result.findViewById(R.id.heading);
dataCompassLayout = (LinearLayout) result.findViewById(R.id.datacompasslayout);
setColourScheme();
buttonOn.setOnClickListener(this);
buttonSos.setOnClickListener(this);
buttonOff.setOnClickListener(this);
return (result);
}
public void onResume() {
setColourScheme();
clearShutdownMessage();
getPreferences();
clearText();
setStaticMessage();
super.onResume();
}
@Override
public void onClick(View view) {
alertResetListener.alertReset();
TorchActivity.keepRunning = false;
cSMListener.clearShutdownMessage();
switch (view.getId()) {
case R.id.button_on:
serviceCount++;
sListener.startService("on");
break;
case R.id.button_sos:
serviceCount++;
sListener.startService("sosPreset");
break;
case R.id.button_off:
sListener.reset();
sDListener.setData();
break;
default:
throw new RuntimeException("Unknown button ID");
}
}
private void setColourScheme(){
//Calls the method from the activity which gets the colour scheme from the ColourSchemeFragment
colourScheme = cSListener.getColourScheme();
buttonOn.setBackgroundColor(getResources().getColor(colourScheme[0]));
buttonOff.setBackgroundColor(getResources().getColor(colourScheme[1]));
buttonSos.setBackgroundColor(getResources().getColor(colourScheme[2]));
dataCompassLayout.setBackgroundColor(getResources().getColor(colourScheme[3]));
}
public void setSosTextColour(String s){
int sosColour = 0;
if(s.equals("white")){
sosColour = R.color.button_text_sos;
}else{
sosColour = R.color.button_text_onoff;
}
try {
XmlResourceParser parser = getResources().getXml(sosColour);
ColorStateList colors = ColorStateList.createFromXml(getResources(), parser);
buttonSos.setTextColor(colors);
} catch (Exception e) {
// handle exceptions
}
}
// Called from TorchActivity whenever some new data is sent from one of the sensors
public void setMessage(int msg, String from) {
if (from.equals("light")) {
luxMessage.setText("Current LUX: " + Integer.toString(msg) + "\n");
} else if (from.equals("timer")) {
timerMessage.setText("Turns off in " + Integer.toString(msg) + " minutes\n");
} else if (from.equals("battery")) {
// Stops it updating battery % when the torch isn't on
if (TorchActivity.keepRunning) {
batteryMessage.setText("Current battery level: " + Integer.toString(msg) + "\n");
//toast("********");
}
}
}
public void setStaticMessage() {
if (lightSensitivity < 1000) {
luxStatic.setText("Turns off at " + Integer.toString(lightSensitivity) + " LUX");
}
if (timerOn) {
timerStatic.setText("Timer: ON");
} else {
timerStatic.setText("Timer: OFF");
}
if (batteryPct > 0) {
batteryStatic.setText("Turns off at " + Integer.toString(batteryPct) + "% battery");
}
shutdownMessageStatic.setText("Torch stopped by: ");
}
public void clearText() {
luxMessage.setText("\n");
luxStatic.setText("Light Monitor: OFF");
// only lets it clear the timer if the torch is off, && it's not the first time through. On the first time
// through it was getting cleared when it shouldn't have been.
if (!TorchActivity.keepRunning && !TorchActivity.autoOn) {
timerMessage.setText("\n");
}
timerStatic.setText("\nTimer: OFF");
batteryMessage.setText("\n");
batteryStatic.setText("Battery monitor: OFF");
}
public void updateCompass(String s, RotateAnimation rA){
img.startAnimation(rA);
heading.setText(s);
}
public void setImageWhite(){
img.setImageResource(R.drawable.compass_white);
}
public void setImageBlack(){
img.setImageResource(R.drawable.compass);
}
private void getPreferences() {
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
lightSensitivity = Integer.valueOf(prefs.getString("lightsensitivity", "1000000"));
timerOn = prefs.getBoolean("timeron", false);
batteryPct = Integer.valueOf(prefs.getString("batterypct", "50"));
}
// From TorchActivity
public void setShutdownMessage(String s) {
shutdownMessage.setText("The " + s);
}
public void clearShutdownMessage() {
shutdownMessage.setText("");
}
public void setIsThereALightSensor(boolean isThereALightSensor) {
this.isThereALightSensor = isThereALightSensor;
}
public boolean getIsThereALightSensor() {
return isThereALightSensor;
}
// Container Activity must implement this interface
public interface AlertResetListener {
public void alertReset();
}
// Container Activity must implement this interface
public interface ServiceListener {
public void startService(String s);
// Resets the service and the timer
public void reset();
}
// Container Activity must implement this interface
public interface SetDataListener {
public void setData();
}
public interface ClearShutdownMessageListener {
public void clearShutdownMessage();
}
public interface ColourSchemeListener {
public int[] getColourScheme();
}
}
Looks like you are calling setIsThereALightSensor
before the fragment is attached.
This is confirmed from your comment
Quoting
I solved the issue by starting the fragments
in the onAttach
in the TorchFragment
(via the hosting activity) so it was up and running when it's methods were called
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.