-1

I am new to java and I could use some help. In the following program, when I rotate the screen the ListView disappears. When I click back, then pull the app back up both of my TextViews and my ListView are cleared. I read up on this some and from what I gather it's because the activity basically restarts upon these actions. I looked for a good way to save the information in these cases, but nothing I tried is working. Any help would be greatly appreciated. If my code is a mess, I apologize, like I said I'm a beginner. I tried to use the onSavedInstanceState() method, but I can't get it to work. I realize it's probably some stupid mistake that I am making, but I have been at it for hours and I can't figure out what I'm doing wrong. Thanks in advance.

package dev.rogueinteractive.barcodescannershoppingcartii;

import android.app.Activity;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements OnClickListener {

public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putStringArrayList("myKey", (ArrayList<String>) productReport);
}


    private static final String USER_AGENT = "Mozilla/5.0";
    private static  String GET_URL ;
    private ArrayAdapter<String> listAdapter ;
    List<String> productReport = new ArrayList<String>();

public void sendGET() throws IOException  {
        URL obj = new URL(GET_URL);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", USER_AGENT);
        int responseCode = con.getResponseCode();
        System.out.println("GET Response Code :: " + responseCode);
        if (responseCode == HttpURLConnection.HTTP_OK) { // success
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // print result
            fullResponse = response.toString();
            String[]responseArray = fullResponse.split("\"");
            String price = new String(responseArray[30]);
            price = new StringBuffer(price).insert(1, " ").toString();
            price = new StringBuffer(price).insert(2, "$").toString();
            responseArray[30] = price;
            List<String> modifiedArray = new ArrayList<String>();
            modifiedArray.add(responseArray[27]);
            modifiedArray.add("\n");
            modifiedArray.add("\n");
            modifiedArray.add(responseArray[28]);
            modifiedArray.add(responseArray[29]);
            modifiedArray.add(responseArray[30]);

            modifiedResponse = modifiedArray.toString();
            modifiedResponse= modifiedResponse.replaceAll(",", "");
            modifiedResponse = modifiedResponse.replaceAll("[\\[\\]]", "");
            productReport.add(modifiedResponse);
        } else {
            responseTXT.setText("GET request not worked");
        }
    }
    public String modifiedResponse;
    public String fullResponse;
    public String scanContent;
    private Button scanBtn;
    private TextView formatTxt, contentTxt, responseTXT;
    public ListView mainListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {
            List<String> productReport = savedInstanceState.getStringArrayList("myKey");
            if (productReport != null) {
                listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow, productReport);
            }
        }
        setContentView(R.layout.activity_main);
        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        mainListView = (ListView) findViewById( R.id.mainListView );
        scanBtn = (Button) findViewById(R.id.scan_button);
        formatTxt = (TextView) findViewById(R.id.scan_format);
        contentTxt = (TextView) findViewById(R.id.scan_content);
        responseTXT = (TextView) findViewById(R.id.response);
        scanBtn.setOnClickListener(this);
    }

    public void onClick(View v) {
        if (v.getId() == R.id.scan_button) {
            IntentIntegrator scanIntegrator = new IntentIntegrator(this);
            scanIntegrator.initiateScan();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
        if (scanningResult.getFormatName() != null) {
            this.scanContent = scanningResult.getContents();
            String scanFormat = scanningResult.getFormatName();
            formatTxt.setText("FORMAT: " + scanFormat);
            contentTxt.setText("CONTENT: " + scanContent);
            GET_URL="http://api.walmartlabs.com/v1/search?query="+scanContent+"&format=json&apiKey=5sk5b7u25b4qawku5zsm289z";
            try {
                sendGET();
            } catch (IOException e) {
                e.printStackTrace();
            }
            listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow, productReport);
            mainListView.setAdapter( listAdapter );
        } else if (scanningResult==null){
            Toast toast = Toast.makeText(getApplicationContext(),
                    "No scan data received!", Toast.LENGTH_SHORT);
            toast.show();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Main Activity

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button android:id="@+id/scan_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:text="@string/scan" />
<TextView
    android:id="@+id/scan_format"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textIsSelectable="true"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/scan_button" />
<TextView
    android:id="@+id/scan_content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textIsSelectable="true"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/scan_format" />

<ListView android:id="@+id/mainListView"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:layout_below="@id/scan_content"/>

<TextView
    android:id="@+id/response"
    android:maxLines = "10000"
    android:scrollbars = "vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textIsSelectable="true"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/scan_content" />
</RelativeLayout>

Row Layout

<?xml version="1.0" encoding="utf-8"?>


<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rowTextView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:textSize="16sp" >
</TextView>
user3221816
  • 135
  • 2
  • 2
  • 10

1 Answers1

1

I think you've missed two things.

First, you're not setting back your mainListView adapter to receive the list you've saved on onSaveInstanceState. Note that you're getting the myList on onCreate method, if savedInstanceState is not null, but the listView is not receiving the new adapter you're creating. I'd suggest add this on onCreate method:

...
//current code
scanBtn.setOnClickListener(this);
//New Code to be added
mainListView.setAdapter( listAdapter );

Second, if savedInstanceState is not null, you're creating a new list of productReport to receive the list you've saved before rotation, but you're using the list productReport elsewhere. You should add all items received from the bundle you've saved on this list or even recreate the list of products.

//Current code    
if (savedInstanceState != null) {
            List<String> productReport = savedInstanceState.getStringArrayList("myKey");
            if (productReport != null) {
                listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow, productReport);
            }
        }
//Replaced code
if (savedInstanceState != null) {
        productReport = savedInstanceState.getStringArrayList("myKey");
        if (productReport != null) {
            listAdapter = new ArrayAdapter<String>(this, R.layout.simplerow, productReport);
        }
    }

Another thing: I don't think you're 100% sure about the json returned by the site you've been getting data. It's not AT ALL a good idea to retrieve data and try to get things like

String price = response[30];

because you can get easily an array out of bounds exception. Check the GSON library, maybe you can create a model class to hold the results using something like

new Gson().fromJson(//your response string goes here, //your model class goes here)

Finally, you cannot hold the state when back button is pressed, unless you make it static or retrieve data again.

filipe.costa01
  • 238
  • 1
  • 10
  • Oh awesome. Thanks a ton. That totally worked to save ListView on screen rotation. However, when I press the back button and go to the home screen then return to my app, the ListView is cleared again. Is there a way to restore it to its previous state? Thanks for the suggeson for GSON library too. That was the next thing I was going to look for. – user3221816 Sep 21 '15 at 18:35
  • Maybe you could use SharedPreferences to save the data you want. I would suggest you save on SharedPreferences the query you've made, then when you call onCreate, if savedInstance is null, you could check if the SharedPreferences contains the query you've saved there, and reload the data again. – filipe.costa01 Sep 21 '15 at 18:58