1

i´ve read a lot of post that had almost the same question but it doesn´t help me with my problem, the thing is that I am trying to create an app to constantly update the information in 2 EditTexts for Latitude and Longitude using the GPS of the device. In tutorials I had seen they create the classes inside the MainActivity so I try to do almost the same but creating a new class file. When I send the information to the MainActivity it reach the EditText but it seems that those cannot be filled with the information I don't know why... Thinking that It could be the threads I try to implement a AsynkTask (but my android skills are not to high) and i am having the same error... If some one could help me I whould be really Greatfull! I post the code next...

This is the MainActivity

public class MainActivity extends Activity {

    public EditText edTLatitud;
    public EditText edTLongitud;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edTLatitud = (EditText)this.findViewById(R.id.edTxtLatitud);
        edTLongitud = (EditText)this.findViewById(R.id.edTxtLongitud);
        ConfigGps();
    }

    private void ConfigGps()
    {
        LocationManager mLocationManager;
        LocationListener mLocationListener;

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocationListener = new MyLocationListener();
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000, 1, mLocationListener);
    }

This is the new file class

public class MyLocationListener implements LocationListener{

    private MainActivity mainActivity = new MainActivity();
    private GPSBackground gpsBackground = new GPSBackground();
    private String Latitud,Longitud;

    @Override
    public void onLocationChanged(Location location) {

        gpsBackground.execute(location);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    private class GPSBackground extends AsyncTask<Location, Void,Void>
    {

        @Override
        protected Void doInBackground(Location... params) {
            Location location = params[0];

            try{
                mainActivity.edTLatitud.setText(String.valueOf(location.getLatitude()));
                mainActivity.edTLongitud.setText(String.valueOf(location.getLongitude()));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }

            return null;
        }
    }
}

The error I catch is this one:

563-572/com.apps3d.logixuexapp W/System.err: java.lang.NullPointerException
08-22 18:57:40.745      563-572/com.apps3d.logixuexapp W/System.err: at com.apps3d.logixuexapp.MyLocationListener$GPSBackground.doInBackground(MyLocationListener.java:50)
08-22 18:57:40.745      563-572/com.apps3d.logixuexapp W/System.err: at com.apps3d.logixuexapp.MyLocationListener$GPSBackground.doInBackground(MyLocationListener.java:42)
08-22 18:57:40.755      563-572/com.apps3d.logixuexapp W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:185)
08-22 18:57:40.755      563-572/com.apps3d.logixuexapp W/System.err: at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
08-22 18:57:40.755      563-572/com.apps3d.logixuexapp W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:138)
08-22 18:57:40.755      563-572/com.apps3d.logixuexapp W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
08-22 18:57:40.755      563-572/com.apps3d.logixuexapp W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
08-22 18:57:40.755      563-572/com.apps3d.logixuexapp W/System.err: at java.lang.Thread.run(Thread.java:1019)

Well if i am doing something wrong please give me a hand, I am new on this of android development jejej Thanks !!

Ahmed Ekri
  • 4,601
  • 3
  • 23
  • 42
Elsanty
  • 148
  • 1
  • 9

4 Answers4

3

A couple things here. This isn't the correct way to use a reference of your Activity. Also, you can't update UI elements in doInBackground() as it needs to be done on the UI. You can do this in any other AsyncTask method. Also, if you are able to make it an inner class of your Activity then it will have access to member variables and its functions.

See these answers on passing a reference to your AsyncTask.

And this one on using an interface to get the data when your AsyncTask is done.

Community
  • 1
  • 1
codeMagic
  • 44,549
  • 13
  • 77
  • 93
2

You are doing this

    private MainActivity mainActivity = new MainActivity();
    mainActivity.edTLatitud.setText(String.valueOf(location.getLatitude()));

Which is wrong

You need to pass the values to other activity using intent. Have editText for your second activity. Retrieve the value initialize your edittext and set the value. This is if your second class is a activity class.

Your second class is non activity class

   public class MyLocationListener implements LocationListener{

As suggested by codeMagic using interface would be better

Have a interface in second class

Implement the interface in your activity class and then set the values to editext

Or you could make asynctask an inner class of your activity class and then update editext in onPostExecute.

Edit:

You are also invoking asynctask everytime the location is changed gpsBackground.execute(location).

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • Can you please send me a link or post me an example of using an intent as you mention it please? – Elsanty Aug 22 '13 at 21:11
  • @Elsanty your second class is non activity class so don't bother with intents. Use interface. check the link codeMagic answer the second link – Raghunandan Aug 22 '13 at 21:12
  • @Elsanty you can make your asycntask an inner class of your activity class and update edittext in `onPostExecute`. – Raghunandan Aug 22 '13 at 21:15
  • so I have to move the asynktask class to the MainActivity and then update the edittext in opPostExecute? but how I will call the asynkTask from the class MyLocationListener in method onLocationChange? – Elsanty Aug 22 '13 at 21:24
  • @Elsanty you should rethink your design. – Raghunandan Aug 22 '13 at 21:27
  • well, the thing is that I try it putting all the classes in the MainActivity and it works... but I read that way of programation is not so organiced, thats why I want to create separated classes... – Elsanty Aug 22 '13 at 21:34
  • @Elsanty but you cannot update ui the way you are doing. You can have inner class that's not a problem. – Raghunandan Aug 22 '13 at 21:38
  • @Elsanty you can use interface to keep classes separate did u try it? – Raghunandan Aug 22 '13 at 21:46
  • No @Raghunandan, i am just starting and my english is not that good but I will keep trying, mean while I leave all the code in the MainActivity and create inner classes...thanks! – Elsanty Aug 22 '13 at 21:59
  • @Elsanty it may not be efficient design if you create a bunch of inner classes in different `Activities` that do the same thing. But if this is the only `Activity` using the `AsyncTask` then it is much more efficient and easier to use if you make it an inner class. Also, if this answer was the most helpful then you can click the check mark next to it so others with the same problem can get to it easier ;) – codeMagic Aug 22 '13 at 22:13
1

This doesn't actually answer your question, but the line

private MainActivity mainActivity = new MainActivity();

pops out as me as a serious problem. In Android, we never (AFAIK) create an Activity object in this way. The biggest problem is that this MainActivity is not the same as the one being displayed on your device. You need to use a reference to the existing MainActivity instead.

To do this, you have at least two options:

  1. Declare MyLocationListener as an inner class of MainActivity. Then MyLocationListener can access the fields of MainActivity directly.

  2. Add a constructor to MyLocationListener with a MainActivity parameter. Then when you create a MyLocationListener object, send it a reference to the current MainActivity.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • How can I create that reference? – Elsanty Aug 22 '13 at 21:17
  • I also create the first time the MyLocationListener as an inner class of MainActivity and it works, but reading some information they said that this class pr programation is not organized so creating new classes was better... other thing, how can I create a constructor to reference the MainActivity? – Elsanty Aug 22 '13 at 21:39
  • @Elsanty To start, I suggest you read [the Oracle tutorial about constructors](http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html). – Code-Apprentice Aug 22 '13 at 21:41
  • but what I do is not a constructor?? – Elsanty Aug 22 '13 at 22:06
  • @Elsanty `MyLocationListener` does not currently have an explicit constructor. My second suggestion is to add one. – Code-Apprentice Aug 22 '13 at 22:13
0

you can pass a reference of your activity to the AsynchTask and than you can use the edittext

nonamer92
  • 1,887
  • 1
  • 13
  • 24