1

I have created an app that is connected to a remote database. The items in the database are displayed through a spinner in my MainActivity class. I want to display the selected item in a separate class(Map.java) and XML page(map.xml), So I used this code in Map.java to try get the selected item and display it:

    Spinner mySpinner = (Spinner)findViewById(R.id.spinFood);
    String text = mySpinner.getSelectedItem().toString();
    EditText e = (EditText) findViewById (R.id.editText1);
    e.setText(text);

To display this value I created an EditText in my map.xml file:

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:text="@string/text"
    android:id="@+id/editText1"
    android:layout_alignBottom="@+id/textView"
    android:layout_toRightOf="@+id/textView"
    android:layout_alignRight="@+id/imageView"
    android:layout_alignEnd="@+id/imageView" />

The android:input_type="text" is a string value I created:

<string name="text"> %s </string>

But whenever I open the map page my app crashes. Could someone please tell me where I am going wrong? Here all of my code for MainActivity and Map.java

MainActivity

package com.example.cillin.infoandroidhivespinnermysql;

import java.util.ArrayList;
..

public class MainActivity extends Activity implements OnItemSelectedListener        {

private Button btnAddNewCategory;
private TextView txtCategory;
public Spinner spinnerFood;

// array list for spinner adapter
private ArrayList<Category> categoriesList;
ProgressDialog pDialog;

// API urls
// Url to create new category
private String URL_NEW_CATEGORY = "http://192.168.1.4/food_api/new_category.php";
// Url to get all categories
private String URL_CATEGORIES = "http://192.168.1.4/food_api/get_categories.php";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnAddNewCategory = (Button) findViewById(R.id.btnAddNewCategory);
    spinnerFood = (Spinner) findViewById(R.id.spinFood);
    txtCategory = (TextView) findViewById(R.id.txtCategory);

    categoriesList = new ArrayList<Category>();

    // spinner item select listener
    spinnerFood.setOnItemSelectedListener(this);

    // Add new category click event
    btnAddNewCategory.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (txtCategory.getText().toString().trim().length() > 0) {

                // new category name
                String newCategory = txtCategory.getText().toString();

                // Call Async task to create new category
                new AddNewCategory().execute(newCategory);
            } else {
                Toast.makeText(getApplicationContext(),
                        "Please enter category name", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    });

    new GetCategories().execute();

}

/**
 * Adding spinner data
 * */
private void populateSpinner() {
    List<String> lables = new ArrayList<String>();

    txtCategory.setText("");

    for (int i = 0; i < categoriesList.size(); i++) {
        lables.add(categoriesList.get(i).getName());
    }

    // Creating adapter for spinner
    ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_spinner_item, lables);

    // Drop down layout style - list view with radio button
    spinnerAdapter
            .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    // attaching data adapter to spinner
    spinnerFood.setAdapter(spinnerAdapter);

    //spinnerValue = spinnerFood.getSelectedItem().toString();
}

/**
 * Async task to get all food categories
 * */
private class GetCategories extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Fetching food categories..");
        pDialog.setCancelable(false);
        pDialog.show();

    }

    @Override
    protected Void doInBackground(Void... arg0) {
        ServiceHandler jsonParser = new ServiceHandler();
        String json = jsonParser.makeServiceCall(URL_CATEGORIES, ServiceHandler.GET);

        Log.e("Response: ", "> " + json);

        if (json != null) {
            try {
                JSONObject jsonObj = new JSONObject(json);
                if (jsonObj != null) {
                    JSONArray categories = jsonObj
                            .getJSONArray("categories");

                    for (int i = 0; i < categories.length(); i++) {
                        JSONObject catObj = (JSONObject) categories.get(i);
                        Category cat = new Category(catObj.getInt("id"),
                                catObj.getString("name"));
                        categoriesList.add(cat);
                    }
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }

        } else {
            Log.e("JSON Data", "Didn't receive any data from server!");
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        if (pDialog.isShowing())
            pDialog.dismiss();
        populateSpinner();
    }

}

/**
 * Async task to create a new food category
 * */
private class AddNewCategory extends AsyncTask<String, Void, Void> {

    boolean isNewCategoryCreated = false;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Creating new category..");
        pDialog.setCancelable(false);
        pDialog.show();

    }

    @Override
    protected Void doInBackground(String... arg) {

        String newCategory = arg[0];

        // Preparing post params
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("name", newCategory));

        ServiceHandler serviceClient = new ServiceHandler();

        String json = serviceClient.makeServiceCall(URL_NEW_CATEGORY,
                ServiceHandler.POST, params);

        Log.d("Create Response: ", "> " + json);

        if (json != null) {
            try {
                JSONObject jsonObj = new JSONObject(json);
                boolean error = jsonObj.getBoolean("error");
                // checking for error node in json
                if (!error) {
                    // new category created successfully
                    isNewCategoryCreated = true;
                } else {
                    Log.e("Create Category Error: ", "> " + jsonObj.getString("message"));
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }

        } else {
            Log.e("JSON Data", "Didn't receive any data from server!");
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        if (pDialog.isShowing())
            pDialog.dismiss();
        if (isNewCategoryCreated) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // fetching all categories
                    new GetCategories().execute();
                }
            });
        }
    }

}

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
                           long id) {
    Toast.makeText(
            getApplicationContext(),
            parent.getItemAtPosition(position).toString() + " Selected" ,
            Toast.LENGTH_LONG).show();

}

@Override
public void onNothingSelected(AdapterView<?> arg0) {
}

}

Map.java

package com.example.cillin.infoandroidhivespinnermysql;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

public class Map extends Activity {

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);


    //This page layout is located in the menu XML file
    //SetContentView links a Java file, to its XML file for the layout
    setContentView(R.layout.map);

    /*TextView.setText(spinnerValue);
    TextView spinv = (TextView)findViewById(R.id.textView2);
    spinv.setText(getspin());
    spinv = getspin();*/

    Spinner mySpinner = (Spinner)findViewById(R.id.spinFood);
    String text = mySpinner.getSelectedItem().toString();
    EditText e = (EditText) findViewById (R.id.editText1);
    e.setText(text);


    Button mainm = (Button)findViewById(R.id.mainmenu);
    mainm.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //This button is linked to the map page
            Intent i = new Intent(Map.this, MainMenu.class);

            //Activating the intent
            startActivity(i);
        }
    });
}

}

Any help would be much appreciated!!

Here are the errors in my logcat when is crashes:

  E/DatabaseUtils﹕ Writing exception to parcel
    java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
            at com.android.server.am.ActivityManagerService.handleIncomingUser(ActivityManagerService.java:14643)
            at android.app.ActivityManager.handleIncomingUser(ActivityManager.java:2469)
            at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:688)
            at android.content.ContentProvider$Transport.call(ContentProvider.java:325)
            at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:275)
            at android.os.Binder.execTransact(Binder.java:404)


    E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.cillin.infoandroidhivespinnermysql, PID: 14691
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.cillin.infoandroidhivespinnermysql/com.example.cillin.infoandroidhivespinnermysql.Map}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
            at      

android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
            at android.app.ActivityThread.access$900(ActivityThread.java:161)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5356)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
        at com.example.cillin.infoandroidhivespinnermysql.Map.onCreate(Map.java:34)
        at android.app.Activity.performCreate(Activity.java:5426)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
            at android.app.ActivityThread.access$900(ActivityThread.java:161)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:157)
            at android.app.ActivityThread.main(ActivityThread.java:5356)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
            at dalvik.system.NativeStart.main(Native Method)
Cillín
  • 187
  • 1
  • 13
  • It would be very difficult to find the error without stacktrace. Please provide logcat output containing Exception that led to app crash. – Aniket Thakur Jul 07 '15 at 14:35
  • possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – njzk2 Jul 07 '15 at 15:03

1 Answers1

0

I'm guessing that you're getting a NullPointerException in your Map.class

Spinner mySpinner = (Spinner)findViewById(R.id.spinFood);
String text = mySpinner.getSelectedItem().toString();
EditText e = (EditText) findViewById (R.id.editText1);
e.setText(text);

You get a reference to Spinner, then you try to get the selected item and then convert that item to a string. As far as I can tell you haven't actually added any items to the spinner. My guess is that you are trying to access an object in the spinner and since it doesn't exist it returns null. Then you try to call a method on the null object and get an NPE.

This is just a guess. A stacktrace is very helpful in trying to diagnose this.

Where I think you're going wrong is that you populate the spinner in MainActivity and then expect to be able to select an item from that spinner from a different activity. This isn't how it works. Map.class won't be able to reference anything in MainActivity.class. You could try passing the object from MainActivity.class to Map.class or use a different method of passing data, but trying to reference data in MainAcitivity.class from Map.class won't work.

Edit: If you just want to pass a String from MainActivity.class to Map.class you can add the string as an 'extra' to the intent that you use to start Map.class.

In your MainActivity.class code. When the item from the spinner is selected, create an intent and set the string as an extra using the putExtra() method. You will need to supply a key that basically tags the extra so you can identify it in the receiving activity and the string you want to send.

Intent intent = new Intent(this, Map.class);
intent.putExtra("KEY_SPINNER_STRING", variableRepresentingString);
startActivity(intent);

In the Map.class activity, in the onCreate() method you will need to receive the intent, check for the extra, then unpack the extra. Then you will have the String.

onCreate(Bundle savedInstanceState) {
    String spinnerString;
    if (getIntent() != null && getIntent().getExtras() != null) {
        Bundle bundle = getIntent().getExtras();
        if (bundle.getString("KEY_SPINNER_STRING") != null) {
            spinnerString = bundle.getString("KEY_SPINNER_STRING");
        }
    }
}

If everything is done correctly the String will be passed from MainActivity.class and received by Map.class

neonDion
  • 2,278
  • 2
  • 20
  • 39
  • So I should store the selected spinner item into a string that is located in the MainActivity. Then make a method in the MainActivity that prints this string. Then call this method in the Map.java? – Cillín Jul 07 '15 at 15:42
  • I'm not exactly sure how your app is supposed to work so it's hard to answer. Are you trying to select something from the spinner in MainActivity.class and then launch Map.class and show the item that was selected in MainActivity.class? – neonDion Jul 07 '15 at 15:44
  • Yes that's exactly what i'm trying to do – Cillín Jul 07 '15 at 15:49
  • I understand this theory. But what should I have instead of "KEY_SPINNER_STRING"?? – Cillín Jul 07 '15 at 18:09
  • KEY_SPINNER_STRING is simply a placeholder for a unique key. In practice you'd usually do something like this in MainActivity.class: public static final String KEY_SPINNER_STRING = "com.package.name.KEY_SPINNER_STRING". Then use the constant KEY_SPINNER_STRING as the key when setting the extra in MainActivity and for getting the extra in Map. – neonDion Jul 07 '15 at 18:10
  • Ok I understand. I am now trying to display this string in Map.java. So I wrote the code: EditText e = (EditText) findViewById (R.id.editText1); e.setText(spinnerString); – Cillín Jul 07 '15 at 18:33
  • In MainActivity there is a callback called onItemSelected(). This is the method that is called when you select an item from your spinner. When this message is called you'll need to get the String that was selected. It looks like you're already doing that and showing the String in a Toast. This is where I was thinking you would want to launch Map.class. If that's the case, then follow the instructions above to launch your Map activity. Map activity should then receive the intent and pull the extra out of it and then you'll have the String ready to use in Map.class. – neonDion Jul 07 '15 at 18:42
  • Yes I tried out what you suggested. What that does is when I select an item on the spinner it goes straight to the Map.java page. But I also want to display on Map.java page what I have selected.. – Cillín Jul 07 '15 at 18:55