1

How can I set the local variable publicIpAddress inside the onResponse() callback below? The line "publicIpAddress = response" has the error "final local variable publicIpAddress cannot be assigned, since it is defined in an enclosing type"

public static String getPublicIpAddress(Context context)
    {
        String publicIpAddress = "";

        StringRequest jsonObjectRequest = new StringRequest(Request.Method.GET, 
                                                                    "http://icanhazip.com/", 
                                                                    new Response.Listener<String>() 
        {
            @Override
            public void onResponse(String response) {
                publicIpAddress = response;
            }                       
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Error in getPublicIpAddress()");
            }
        });

        VolleySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);

        return publicIpAddress;
    }
code
  • 5,294
  • 16
  • 62
  • 113

3 Answers3

1

A final variable can only be initialized once. See How final keyword works

In your case, you are initializing it 2 times, in the declaration (final String publicIpAddress = ""; and in OnResponse).

Try to: 1) Remove the keyword final 2) Remove the initialization in the declaration of the publicIpAddress

Community
  • 1
  • 1
JFPicard
  • 5,029
  • 3
  • 19
  • 43
  • Hi JFPicard. Thanks for your feedback. I removed final but I'm still getting the same error. The IDE is recommending to add "final" to the publicIpAddress local variable now. – code Mar 27 '15 at 18:47
  • I think I am lacking an understanding in the scope here – code Mar 27 '15 at 18:47
  • It says "cannot access a non-final variable inside an inner class defined in a different method. Am I required to move this variable in the global scope of my class? – code Mar 27 '15 at 18:48
  • Try declaring it as a member of your class. In other words, move String publicIpAddress = ""; out of the function. – Eric S. Mar 27 '15 at 18:52
  • My bad, I didn't saw it was in a inner method. Try using Static String publicIpAddress – JFPicard Mar 27 '15 at 18:53
  • Thank you, I figured moving it as a global member of the class would work, but is this the recommended way in terms of Design? – code Mar 27 '15 at 18:56
1

Ok Do like this

public class xxxx  extends Activity {

  static String publicIpAddress;
................................

public static String getPublicIpAddress(Context context)
    {

        StringRequest jsonObjectRequest = new StringRequest(Request.Method.GET, 
                                                                    "http://icanhazip.com/", 
                                                                    new Response.Listener<String>() 
        {
            @Override
            public void onResponse(String response) {
                publicIpAddress = response;
            }                       
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Error in getPublicIpAddress()");
            }
        });

        VolleySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);

        return publicIpAddress;
    }
Soham
  • 4,397
  • 11
  • 43
  • 71
  • 1
    Thank you, I figured moving it as a global member of the class would work, but is this the recommended way in terms of Design? – code Mar 27 '15 at 18:56
  • I wouldn't recommend you to use static method or static variable.If you need the function in everywhere why don't you just make it public.And it will be better if you can use private keyword in function or in variable.Otherwise I don't think there are any other issues.If this answer helps you then please accept it. – Soham Mar 27 '15 at 19:02
1

This is definitely not recommended. The request you are making is asynchronous and will always return null or "" - whatever value you initialized publicIpAddress with. Your method is returning immediately after placing StringRequest in the queue before it has a chance to execute the onResponse method. The return happens before this code is ever called: publicIpAddress = response;

Read this: Asynchronous HTTP Requests in Android Using Volley

m1k3t
  • 93
  • 1
  • 2
  • 7
  • So how do you access the returned JSON outside of the callback? The post you linked to doesn't say how. – Matt Jul 09 '17 at 19:18