简体   繁体   中英

App crashing when TextView is changed inside onLocationChanged inside a fragment

I am a beginner at developing for Android. I in my app I got GPS and a navigation drawer working. My goal is to display coordinates in a fragment. I got the app to feed the GPS data into logcat and now I'm trying to change the text on TextvView from the onLocationChanged method. Changing text inside onCreateView works flawlessly.

It works like this:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    myView = inflater.inflate(R.layout.fragment_gps, container, false);

    gpsLongitude = (TextView) myView.findViewById(R.id.gps_longitude);
    gpsLongitude.setText("something");

    return myView;
}

But not when I do this:

private double longitude;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    myView = inflater.inflate(R.layout.fragment_gps, container, false);

    gpsLongitude = (TextView) myView.findViewById(R.id.gps_longitude);

    return myView;
}

...

public void onLocationChanged(Location location) {

    Log.e("GPS", "found signal");
    longitude = location.getLongitude();
    gpsLongitude.setText("Longitude: " + Double.toString(longitude));

}

I get :

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference

(this happens right after i get : E/GPS: found signal in the logcat)

If I do this:

public void onLocationChanged(Location location) {

    gpsLongitude = (TextView) getView().findViewById(R.id.gps_longitude);
    gpsLongitude.setText("Longitude: " + Double.toString(longitude));
}

The same thing happens:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference

Doing this:

public void onLocationChanged(Location location) {

    gpsLongitude = (TextView) getView().findViewById(R.id.gps_longitude);
    gpsLongitude.setText("something");

}

Results in :

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference

XML:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/gps_longitude"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Longitude"
        android:textSize="40dp"
        android:textAlignment="center"
        android:layout_margin="10dp"/>
    <TextView
        android:id="@+id/gps_latitude"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Latitude"
        android:textSize="40dp"
        android:textAlignment="center"
        android:layout_margin="10dp"/>
    <TextView
        android:id="@+id/gps_altitude"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Altitude"
        android:textSize="40dp"
        android:textAlignment="center"
        android:layout_margin="10dp"/>
    <TextView
        android:id="@+id/gps_speed"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Speed"
        android:textSize="40dp"
        android:textAlignment="center"
        android:layout_margin="10dp"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="75dp"
        android:gravity="center">
        <Button
            android:onClick="onStartButtonClick"
            android:id="@+id/gps_start"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:text="Start"
            android:textSize="20dp"/>
        <Button
            android:onClick="onStopButtonClick"
            android:id="@+id/gps_stop"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:text="Stop"
            android:textSize="20dp"/>

    </LinearLayout>

</LinearLayout>
</ScrollView>

Have been seeking for an answer for a few hours.

EDIT:

MainActivity.java :

    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    GPSFragment locationListener = new GPSFragment();
    if (android.os.Build.VERSION.SDK_INT > 23) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{
                    Manifest.permission.ACCESS_FINE_LOCATION
            }, 10);
            return;
        }
    }
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,locationListener);
private double longitude;
private ViewGroup myView = null;


@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    myView = inflater.inflate(R.layout.fragment_gps, container, false);
    return myView;
}

public void onLocationChanged(Location location) {

    Log.e("GPS", "found signal");
    if (null != myView) {
        TextView gpsLongitude = (TextView) myView.findViewById(R.id.gps_longitude);
        longitude = location.getLongitude();
        gpsLongitude.setText("Longitude: " + Double.toString(longitude));
    }


}

Pass your view to the method like this

    public void onLocationChanged(Location location, View view) {

    gpsLongitude = (TextView) view.findViewById(R.id.gps_longitude);
    gpsLongitude.setText("something");

}

when you call your method pass the view

onLocationChanged(location,myView);

First, make sure you implement the right interface of android.location.LocationListener in your Fragment

public class GPSFragment extends Fragment implements LocationListener {
...
}

You should request the requestLocationUpdates in onCreateView()

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    myView = inflater.inflate(R.layout.fragment_gps, container, false);
    gpsLongitude = (TextView) myView.findViewById(R.id.gps_longitude);

    LocationManager lm= (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, (android.location.LocationListener) this);

    return myView;
}


@Override
public void onLocationChanged(Location location) {
    if(location==null){
        gpsLongitude.setText("Unknown location");
    }else {
        Log.e("GPS", "found signal");
        double longitude = location.getLongitude();
        gpsLongitude.setText("Longitude: " + Double.toString(longitude));
    }
}

Ok so I found a solution:

private double longitude;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    myView = inflater.inflate(R.layout.fragment_gps, container, false);

    gpsLongitude = (TextView) myView.findViewById(R.id.gps_longitude);

    return myView;
}


public void showGPSData (View view) {
    gpsLongitude.setText("Longitude: " + Double.toString(longitude));
}


public void onLocationChanged(Location location) {
    longitude = location.getLongitude();
    showGPSData(myView);
}

So essentially I just created a method intended for changing text (showGPSData) in Text view, moved the Text view to onCreate and made so that the method (showGPSData) is called on location change.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM