I have these two activities in my Android application in which the first one is where the user will enter the asked information (to a edittext) and the other one is where it will send the data (I used putExtra to transfer the data from the 1st activity to the 2nd) to the MySQL database and will later on display results in ListView. The problem is, when the 2nd activity starts (considering that I have already entered something on the first activity) and after the progress dialog shows, there is nothing being displayed, or the results don't appear. But when I tried just starting the second activity (the edittext in the 1st activity is null) it shows the results. I'm not sure if what causes the problem, is on the application or in the PHP file I used in fetching the data?
Here are the codes:
MainActivity.java
//first activity
public class SearchFragment extends Fragment implements View.OnClickListener {
Button butt;
EditText destination;
String d;
public SearchFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_search, container, false);
butt = (Button) view.findViewById(R.id.searchBUTTon);
butt.setOnClickListener(this);
destination = (EditText) view.findViewById(R.id.destinationTO);
return view;
}
#Override
public void onClick(View v) {
d = destination.getText().toString();
Intent a = new Intent(getActivity(), SearchResultsActivity.class);
a.putExtra("to", d);
startActivity(a);
}
}
SearchResultsAcivity.java
//second activity
public class SearchResultsActivity extends AppCompatActivity implements ListView.OnItemClickListener {
private ListView listView;
private String JSON_STRING;
String destination;
TextView d;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_results);
Intent a = getIntent();
destination = a.getStringExtra("to");
d = (TextView) findViewById(R.id.textView3);
d.setText(destination);
listView = (ListView) findViewById(R.id.listView);
listView.setOnItemClickListener(this);
getJSON();
}
private void showBusList() {
JSONObject jsonObject = null;
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(config.TAG_JSON_ARRAY);
for (int i = 0; i < result.length(); i++) {
JSONObject jo = result.getJSONObject(i);
//get strings
String id = jo.getString(config.TAG_ID);
String busName = jo.getString(config.TAG_BUSNAME);
String terminal = jo.getString(config.TAG_TERMINAL);
HashMap<String, String> busDetails = new HashMap<>();
busDetails.put(config.TAG_ID, id);
busDetails.put(config.TAG_BUSNAME, busName);
busDetails.put(config.TAG_TERMINAL, terminal);
list.add(busDetails);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new SimpleAdapter(
SearchResultsActivity.this, list, R.layout.result_list_item, new String[] {
config.TAG_ID, config.TAG_BUSNAME, config.TAG_TERMINAL}, new int[] {R.id.id, R.id.busName,
R.id.terminal});
listView.setAdapter(adapter);
}
private void getJSON() {
class GetJSON extends AsyncTask<Void, Void, String> {
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(SearchResultsActivity.this, "Message", "Fetching data... Please wait.", false, false);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
JSON_STRING = s;
showBusList();
}
#Override
protected String doInBackground(Void... params) {
RequestHandler rh = new RequestHandler();
String s = rh.sendGetRequestParam(config.URL_SEARCH, destination);
return s;
}
}
GetJSON gj = new GetJSON();
gj.execute();
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
RequestHandler.java
//handles requests
public String sendGetRequestParam(String requestURL, String id){
StringBuilder sb =new StringBuilder();
try {
URL url = new URL(requestURL+id);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String s;
while((s=bufferedReader.readLine())!=null){
sb.append(s+"\n");
}
}catch(Exception e){
}
return sb.toString();
}
PHP file
<?php
$connection = mysqli_connect("mysql.hostinger.ph", "u679871488_bus", "Damnyoufudge20", "u679871488_bus") or die("Error " . mysqli_error($connection));
$des = $_GET['destination'];
$sql = "SELECT * from appDB WHERE route LIKE '%".$des."%'";
$result = mysqli_query($connection, $sql) or die ("Error in Selecting " . mysqli_error($connection));
$thisArray = array();
while($row = mysqli_fetch_assoc($result)) {
$thisArray[] = $row;
}
echo json_encode(array('busDetails' => $thisArray));
Error from logcat
03-06 16:10:25.525 31710-31710/com.thesis.iwander W/System.err: org.json.JSONException: Value <html> of type java.lang.String cannot be converted to JSONObject
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONObject.<init>(JSONObject.java:159)
at org.json.JSONObject.<init>(JSONObject.java:172)
at com.thesis.iwander.SearchResultsActivity.showBusList(SearchResultsActivity.java:62)
at com.thesis.iwander.SearchResultsActivity.access$100(SearchResultsActivity.java:29)
at com.thesis.iwander.SearchResultsActivity$1GetJSON.onPostExecute(SearchResultsActivity.java:109)
at com.thesis.iwander.SearchResultsActivity$1GetJSON.onPostExecute(SearchResultsActivity.java:93)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5333)
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:829)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
at dalvik.system.NativeStart.main(Native Method)
try array_push method in php in your php code
while($row = mysqli_fetch_assoc($result)) {
//$thisArray[] = $row;
array_push($thisArray, $row);
}
i think it'll work.
Try it once and check if get this data in android.
It is bad practice to append user input directly to sql query in php like you used '%".$des."%'. It causes SQL Injection Attacks.
Always prefer mysqli_prepare($sql) to avoid SQL Injection Attacks.
UPDATE 1
In SearchResultsActivity.java, try to replace
destination = a.getStringExtra("to");
this line with
destination = a.getExtras().getString("to");
Log.e("tag", " DESTINATION :: " + destination);
And check if you're getting the text from first activity.
UPDATE 2
Never ever forget to catch exceptions you're throwing.
You forgot to catch exception in sendGetRequestParam method. Catch it and print it. So you'll know if there is any error connecting to server.
Related
I am New to the android studio and want to something more. Actually, I am trying to pass the string that I got from the spinner in onCreateMethod and pass to the onPostExecute function. I will be grateful for the help. Bellow is my code.
I tried making a global variable called First and store the string from spinner and pass it on the onPostExecute function.
public class Convert extends AppCompatActivity implements LocationListener
{
Spinner dropdown;
Button btn;
String text;
String first;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_convert);
dropdown = (Spinner) findViewById(R.id.spinner1);
btn = (Button)findViewById(R.id.btn);
String[] items = new String[]{"United States,USD", "Nepal,NPR", "Bangladesh,BDT","Brazil,BRL"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, items);
dropdown.setAdapter(adapter);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
text = dropdown.getSelectedItem().toString();
first = text.substring(text.length()-3);
Log.i("her", first);
}
});
new DownloadTask().execute("http://openexchangerates.org/api/latest.json?
app_id=XXXXXXXXXX");
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urls[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char counter = (char) data;
result += counter;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try{
JSONObject jsonObject = new JSONObject(result);
JSONObject curr = jsonObject.getJSONObject("rates");
String npr = curr.getString(first);
Log.i("money", npr );
} catch (JSONException e) {
e.printStackTrace();
}
}
}
What I want is to pass the string first on the onPostExecute function.
When you will call your DownloadTask, asyncTask fires with method execute, just pass param though him. Example:
How to pass url
new DownloadTask().execute("url for download");
How to receive url
protected String doInBackground(String... urls) {
String url = urls[0]; // url for download
}
Also you could send and array of params. Also be careful with AsyncTask, do not pass your context/view variable, it could arise memory leaks, read docs.
So I have been trying to make a feature in my app where I can login and then fetch data from my database through the Django REST Framework. My logging in works as it only uses POST, but retrieving items does not work.
For some reason my AsyncTask does not get called for retrieving posts.
I have placed my AsyncTask for both activities, which are login and posts, on a separate java file only for handling Web Server stuff.
I am wondering if this is because I should put AsyncTask on each activities.
login.java
public class Login extends AppCompatActivity {
Button LoginButton;
EditText uUserName, uPassWord;
WSAdapter.SendAPIRequests AuthHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//SetupHomeBtn = (ImageButton) findViewById(R.id.SetupHomeBtn);
LoginButton = (Button) findViewById(R.id.LoginButton);
uUserName = (EditText) findViewById(R.id.LoginUserBox);
uPassWord = (EditText) findViewById(R.id.LoginPassBox);
//AuthHelper = new WSAdapter().new SendDeviceDetails();
// Moves user to the main page after validation
LoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// gets the username and password from the EditText
String strUserName = uUserName.getText().toString();
String strPassWord = uPassWord.getText().toString();
// API url duh
String APIUrl = "http://192.168.0.18:8000/token-auth/";
// If the user is authenticated, then transfer to the MainActivity page
if (APIAuthentication(strUserName, strPassWord, APIUrl)){
startActivity(new Intent(Login.this, Posts.class));
}
}
});
}
private boolean APIAuthentication(String un, String pw, String url){
// when it wasn't static -> AuthHelper = new WSAdapter().new SendAPIRequests();
AuthHelper = new WSAdapter.SendAPIRequests();
JSONObject postData = new JSONObject();
try {
// Attempt to input info to the Django API
postData.put("username", un);
postData.put("password", pw);
// Putting the data to be posted in the Django API
AuthHelper.execute(url, postData.toString());
return true;
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
}
posts.java
public class Posts extends AppCompatActivity {
TextView postsSect;
Button postsDoneBtn;
WSAdapter.SendAPIRequests PostsHelper;
StringBuilder postsBuffer = new StringBuilder();
#Override
protected void onResume(){
super.onResume();
PostsDetails postDetailsHelper = new PostsDetails();
postDetailsHelper.ListPosts();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_posts);
PostsDetails postDetailsHelper = new PostsDetails();
postsDoneBtn = (Button) findViewById(R.id.PostsDoneButton);
postDetailsHelper.callPostDetails("192.168.0.18:8000/api");
postDetailsHelper.ListPosts();
postDetailsHelper.postDetailsCalled('n');
postsDoneBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Posts.this, MainActivity.class));
}
});
}
public class PostsDetails {
//String post_title, post_content;
ArrayList<Integer> post_id = new ArrayList<Integer>();
ArrayList<String> post_title = new ArrayList<String>();
ArrayList<String> post_content = new ArrayList<String>();
boolean isPDCalled;
// sets if Post details are called
boolean postDetailsCalled(char called) {
if (called == 'y'){
return true;
}
return false;
}
// checks if postsDetails functions are called for AsyncTask
boolean getIsPDCalled(){
return isPDCalled;
}
// calls the execute for AsyncTask
private void callPostDetails(String theurl){
PostsHelper = new WSAdapter.SendAPIRequests();
// sets if post details are called
postDetailsCalled('y');
// executes AsyncTask
PostsHelper.execute(theurl);
}
// sets values for the posts arrays
public void setPost(int p_id, String p_title, String p_content) {
post_id.add(p_id);
post_title.add(p_title);
post_content.add(p_content);
}
// Lists the posts from the database
public void ListPosts() {
/////////// add functionality if a post was deleted and was clicked
postsSect = (TextView) findViewById(R.id.PostsSection);
postsSect.setText(post_title.get(post_title.size()) + "\n");
for (int i = post_id.size() - 1; i > 0; i--)
{
postsSect.append(post_title.get(i));
}
}
}
}
WSAdapter.java
// I forgot what WS stands for, but this class serves as an adapter for JSON and Online stuff
// I think it stands for With-Server Adapter
public class WSAdapter extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
static public class SendAPIRequests extends AsyncTask<String, String, String> {
// Add a pre-execute thing
#Override
protected String doInBackground(String... params) {
Log.e("TAG", params[0]);
Log.e("TAG", params[1]);
String data = "";
HttpURLConnection httpURLConnection = null;
try {
// Sets up connection to the URL (params[0] from .execute in "login")
httpURLConnection = (HttpURLConnection) new URL(params[0]).openConnection();
// Sets the request method for the URL
httpURLConnection.setRequestMethod("POST");
// Tells the URL that I am sending a POST request body
httpURLConnection.setDoOutput(true);
// To write primitive Java data types to an output stream in a portable way
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
// Writes out a byte to the underlying output stream of the data posted from .execute function
wr.writeBytes("postData=" + params[1]);
// Flushes the postData to the output stream
wr.flush();
wr.close();
// Representing the input stream
InputStream in = httpURLConnection.getInputStream();
// Preparing input stream bytes to be decoded to charset
InputStreamReader inputStreamReader = new InputStreamReader(in);
StringBuilder dataBuffer = new StringBuilder();
// Translates input stream bytes to charset
int inputStreamData = inputStreamReader.read();
while (inputStreamData != -1) {
char current = (char) inputStreamData;
inputStreamData = inputStreamReader.read();
// concatenates data characters from input stream
dataBuffer.append(current);
}
data = dataBuffer.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
// Disconnects socket after using
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
Log.e("TAG", data);
return data;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// expecting a response code fro my server upon receiving the POST data
Log.e("TAG", result);
Posts.PostsDetails postsHelper = new Posts().new PostsDetails();
// For posts
try {
if (postsHelper.getIsPDCalled()){
JSONObject pJObj = new JSONObject(result);
JSONArray pJObjArray = pJObj.getJSONArray("posts");
for (int i = 0; i < pJObjArray.length(); i++) {
JSONObject pJObj_data = pJObjArray.getJSONObject(i);
postsHelper.setPost(pJObj_data.getInt("id"), "post_title", "post_content");
}
}
} catch (JSONException e) {
//Toast.makeText(JSonActivity.this, e.toString(), Toast.LENGTH_LONG).show();
Log.d("Json","Exception = "+e.toString());
}
}
}
}
Yes, you can and should put the network calls functions in a separate java file for better readability and test-coverage.
Apart from that, i would suggest to use Retrofit as your HTTP client. It helps you to manage all the dirty things like headers and converters etc, so you can put all your effort on your logic and implementing your callback actions.
In my activity I am adding a header button to save the values of a listview, with an EditText and post them to a php/mysql web app.
I am able to get the values of the listview if I use setOnItemClickListener but when I use setOnClickListener on the header save button, I am not able to iterate through the listview.
I am using a custom array adaptor :-
public class CustomOrderAdaptor extends ArrayAdapter{
int groupid;
ArrayList<OneOrder> records;
Context context;
public CustomOrderAdaptor(Context context, int vg, int id, ArrayList<OneOrder>records) {
super(context, vg, id, records);
this.context = context;
groupid = vg;
this.records = records;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(groupid, parent, false);
TextView textName = (TextView) itemView.findViewById(R.id.product_name);
textName.setText(records.get(position).getproduct_name());
EditText new_quantity = (EditText) itemView.findViewById(R.id.new_quantity);
new_quantity.setText(records.get(position).getnew_quantity());
TextView textOrderitemid = (TextView) itemView.findViewById(R.id.order_item_id);
textOrderitemid.setText(records.get(position).getorder_item_id());
TextView textQuantity = (TextView) itemView.findViewById(R.id.quantity);
textQuantity.setText(records.get(position).getquantity());
return itemView;
}
}
data model :-
public class OneOrder {
private String quantity;
private String new_quantity;
private String product_name;
private String order_item_id;
public void setquantity(String quantity){this.quantity=quantity;}
public void setnew_quantity(String new_quantity){this.new_quantity=new_quantity;}
public void setproduct_name(String product_name){this.product_name=product_name;}
public void setorder_item_id(String order_item_id){this.order_item_id=order_item_id;}
public String getquantity(){return quantity;}
public String getnew_quantity(){return new_quantity;}
public String getproduct_name(){return product_name;}
public String getorder_item_id(){return order_item_id;}
}
My activity is :-
protected void onCreate(Bundle savedInstanceState) {
//TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_order);
context = this;
records = new ArrayList<OneOrder>();
listOrder = (ListView) findViewById(R.id.order_item_list);
LayoutInflater inflater = LayoutInflater.from(this);
View nTop = inflater.inflate(R.layout.activity_get_order_footer, null);
listOrder.addHeaderView(nTop);
adapter = new CustomOrderAdaptor(context, R.layout.list_order, R.id.product_name,
records);
listOrder.setAdapter(adapter);
Button mButton = (Button) nTop.findViewById(R.id.button_save);
mButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
JSONObject order_items = new JSONObject();
JSONObject sendObject = new JSONObject();
for (int i=0;i<adapter.getCount();i++){
JSONObject order_item = new JSONObject();
OneOrder current_order = (OneOrder) listOrder.getAdapter().getItem(i);
//OneOrder current_order = (OneOrder) getListView().getItemAtPosition(i);
try {
order_item.put("quantity", current_order.getquantity().toString());
order_item.put("new_quantity", current_order.getnew_quantity().toString());
order_item.put("order_item_id", current_order.getorder_item_id().toString());
order_items.put(String.valueOf(i),order_item);
} catch (JSONException e) {
e.printStackTrace();
}
}
HttpURLConnection conn = null;
try {
Intent i = getIntent(); // gets the previously created intent
String order_id = i.getStringExtra("order_id");
sendObject.put("items", order_items.toString());
sendObject.put("order_id", order_id);
try {
URL url = new URL("http://192.168.0.70/steam_dos/index.php?option=com_steam§ion=linen&task=save_order_out");
String message = sendObject.toString();
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout( 10000 /*milliseconds*/ );
conn.setConnectTimeout( 15000 /* milliseconds */ );
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setFixedLengthStreamingMode(message.getBytes().length);
//make some HTTP header nicety
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
//open
conn.connect();
//setup send
BufferedOutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(message.getBytes());
//clean up
os.flush();
//do something with response
InputStream is = conn.getInputStream();
}catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
the error is here :-
order_item.put("quantity", current_order.getquantity().toString());
the error is simple :-
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String au.com.southportsteamlaundry.rfid.steamscanadditions.OneOrder.getquantity()' on a null object reference
The view looks like this :-
Layout view
I am trying to save all of the values of the listview after the save button is clicked but I am not getting the listview items with that code, could you please explain the best way to achieve that ? Thanks.
Normally it's not recommended to use Edit text with adapter, the reason is edit text saving cannot be handled when it scroll out.
There are two kinds solution.
Replace the listview with scrollview
2 create a variable and add a TextWatcher on the edittext. Whenever the edittext get modified, the text watcher detect the change and override the variable whener you done something on it.
code would be like
Implementing Text Watcher for EditText
my answer may not be the best one, but this is what I implemented to get the EditText values of the list view :
mButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
JSONObject order_item = new JSONObject();
order_items_edited = new JSONObject();
for (int i = 0; i < listOrder.getCount(); i++) {
EditText et = (EditText) listOrder.getChildAt(i).findViewById(R.id.new_quantity);
if (et!=null) {
TextView oi = (TextView) listOrder.getChildAt(i).findViewById(R.id.order_item_id);
Log.i("dtag", "et is " + String.valueOf(et.getText()));
Log.i("dtag", "oi is " + String.valueOf(oi.getText()));
try {
order_item.put("new_quantity", String.valueOf(et.getText()));
order_item.put("order_item_id", String.valueOf(oi.getText()));
order_items_edited.put(String.valueOf(i),order_item);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
the main issue I was having was a null object for et, which is valid, but I wasn't testing for it.
Now its working, I will look at implementing a cleaner solution.
I am making a app which fetches json from my websites and parses that json to listview on android.
I get the json using http request then make 2 arrays websites t hold all websites names and links to hold links.I want the listview to show websites names and on clicking then open the website in the browser.
Can anyone please help me.Tried everything I could. Help me figure out the problem or tell me another way to do this thanks.
Trying To get the json and parse it into a listView Below is my code:
public class GetWebsiteList extends AsyncTask<String, String, String> {
// Creating JSON Parser object
ArrayList<HashMap<String, String>> productsList;
String websites[]=new String[10];
String links[]=new String[10];
// url to get all products list
private String url_all_products = "http://androidtest.cu.cc/getwebsites.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_WEBSITES = "websites";
private static final String TAG_SNO = "sno";
private static final String TAG_NAME = "name";
private static final String TAG_LINK = "link";
// products JSONArray
JSONArray products = null;
// Progress Dialog
private ProgressDialog pDialog;
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(mainpage.this);
pDialog.setMessage("Loading Website List.Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... arg0) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);
//ArrayAdapter adapter = ArrayAdapter.
// Check your log cat for JSON reponse
Log.d("nitrek All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
String suc;
switch(success)
{
case 1:
suc="True";
break;
case 0:
suc="False";
break;
default:
suc="unkonwn";
break;
}
if (success == 1) {
// products found
// Getting Array of Products
Log.d(" nitrek success",suc);
products = json.getJSONArray(TAG_WEBSITES);
// looping through All Products
Log.d(" nitrek websites", products.toString());
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_SNO);
String name = c.getString(TAG_NAME);
String link= c.getString(TAG_LINK);
Log.d("nitrek website",id+name+link);
// websites[i]=new String();
websites[i]=name;
links[i]=link;
Log.d("nitrek web",websites[i]+links[i]);
/* creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
try {
map.put(TAG_SNO, id);
map.put(TAG_NAME, name);
productsList.add(map);
}
catch (Exception e)
{
e.printStackTrace();
}
// adding HashList to ArrayList
*/
}
} else {
// no products found
// Launch Add New product Activity
Toast.makeText(mainpage.this,"no website found", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(final String result) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
*/
//ListAdapter adapter = new SimpleAdapter(mainpage.this, productsList, R.layout.listitem, new String[]{TAG_SNO, TAG_NAME},new int[]{R.id.sno, R.id.name});
// updating listview
try {
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(mainpage.this, R.layout.listitem, R.id.name, websites);
final ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < websites.length; ++i) {
list.add(websites[i]);
}
final StableArrayAdapter adapter = new StableArrayAdapter(mainpage.this, R.layout.listitem, list);
//ArrayAdapter<String> ad = new ArrayAdapter<String>(mainpage.this, R.layout.listitem, websites);
ListView lv = (ListView) findViewById(R.id.list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Intent intent = new Intent(this, homepage.class);
count = 0;
String url = links[position];
Toast.makeText(mainpage.this, "Opening: " + url, Toast.LENGTH_SHORT).show();
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
//notify_test(url);
startActivity(i);
}
});
} catch (Exception e) {
Log.d("error list nitrekerror", "below");
e.printStackTrace();
}
Toast.makeText(mainpage.this, result, Toast.LENGTH_LONG).show();
int i = 0;
while (i < websites.length && i < 3) {
Toast.makeText(mainpage.this, websites[i] + " " + links[i], Toast.LENGTH_LONG).show();
i++;
}
}
});
}
}
private class StableArrayAdapter extends ArrayAdapter<String> {
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
public StableArrayAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
#Override
public long getItemId(int position) {
String item = getItem(position);
return mIdMap.get(item);
}
#Override
public boolean hasStableIds() {
return true;
}
}
but I am getting this error and not able to figure out why?
Below is the logcat:
07-08 00:58:34.245 27826-27826/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: nitz.nitrek.myrtoguide, PID: 27826
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java)
at android.widget.AbsListView.obtainView(AbsListView.java)
at android.widget.ListView.measureHeightOfChildren(ListView.java)
at android.widget.ListView.onMeasure(ListView.java)
at android.view.View.measure(View.java)
at android.widget.RelativeLayout.measureChild(RelativeLayout.java)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.FrameLayout.onMeasure(FrameLayout.java)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java)
at android.widget.LinearLayout.measureVertical(LinearLayout.java)
at android.widget.LinearLayout.onMeasure(LinearLayout.java)
at android.view.View.measure(View.java)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:868)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.FrameLayout.onMeasure(FrameLayout.java)
at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java)
at android.widget.LinearLayout.measureVertical(LinearLayout.java)
at android.widget.LinearLayout.onMeasure(LinearLayout.java)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.FrameLayout.onMeasure(FrameLayout.java)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java)
at android.widget.LinearLayout.measureVertical(LinearLayout.java)
at android.widget.LinearLayout.onMeasure(LinearLayout.java)
at android.view.View.measure(View.java)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java)
at android.widget.FrameLayout.onMeasure(FrameLayout.java)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java)
at android.view.View.measure(View.java)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java)
at android.view.Choreographer.doCallbacks(Choreographer.java)
at android.view.Choreographer.doFrame(Choreographer.java)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java)
at android.os.Handler.handleCallback(Handler.java)
at android.os.Handler.dispatchMessage(Handler.java)
at android.os.Looper.loop(Looper.java)
at android.app.ActivityThread.main(ActivityThread.java)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
07-08 00:58:34.245 780-3917/? E/ActivityManager﹕ App crashed! Process: nitz.nitrek.myrtoguide
You had declared the websites array of size 10 but you were filling it with only 2-3 entries depending of number of websites you got as response so on passing the whole array to arrayadapter you were getting a null pointer exception.So you got the number of websites received in response and dynamically declared the array of that size only.
You have forgot to override getView off ArrayAdapter. And sync about viewHolder for more performance. You can read this https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView
You need to override this method to inflate your view else any view is create by your adapter and throw null Exception.
Example of override :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Object data = yourTabObj[position]
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_listView, parent, false);
}
// Lookup view for data population
TextView title = (TextView) convertView.findViewById(R.id.title);
title.setText(data.name);
// Return the completed view to render on screen
return convertView;
}
After you understand that think about viewHolder to increase performance.
I have an HTTP GET that is receiving information from a URI. The URI is for Google Shopping.
https://www.googleapis.com/shopping/search/v1/public/products?key=key&country=US&q=digital+camera&alt=atom
(Left my key out).
Is there a way that I can change it from
q=digital+camera
to anything a user puts in an EditText?
So basically, I want the EditText to change what is searched on Google Shopping.
First screen, ProductSearchEntry with EditText for search query:
Code for ProductSearchEntry
public class ProductSearchEntry extends Activity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.productsearchentry);
Button search = (Button) findViewById(R.id.searchButton);
search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent searchIntent = new Intent(getApplicationContext(), ProductSearch.class);
startActivity(searchIntent);
}
});
}
}
Then, I have a second class, ProductSearch, with no picture, but just this code:
public class ProductSearch extends Activity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.productsearchresults);
EditText searchQuery = (EditText) findViewById(R.id.searchQuery);
ProductSearchMethod test = new ProductSearchMethod();
String entry;
TextView httpStuff = (TextView) findViewById(R.id.httpTextView);
try {
entry = test.getSearchData(searchQuery.getText().toString());
httpStuff.setText(entry);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Which references the ProductSearchMethod class which consists of a TextView that is changed to the code recieved in the HTTP GET:
Code:
public class ProductSearchMethod {
public String getSearchData(String query) throws Exception{
BufferedReader in = null;
String data = null;
try{
HttpClient client = new DefaultHttpClient();
URI site = new URI("https://www.googleapis.com/shopping/search/v1/public/products?key=key&country=US&q="+query.replace(" ","+")+"&alt=atom");
HttpGet request = new HttpGet();
request.setURI(site);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.seperator");
while((l = in.readLine()) !=null){
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
}finally{
if (in != null){
try{
in.close();
return data;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
ProductSearchMethod comes up great, but it doesn't change the text from "Loading Items" to the website code. I had it working before but then I tried to edit what it searched (all this ^) and now it doesn't change.
Make changes in your code like
public class ProductSearchEntry extends Activity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.productsearchentry);
EditText etSearch = (EditText) findViewById(id of your edittext);
Button search = (Button) findViewById(R.id.searchButton);
search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//while calling intent
Intent searchIntent = new Intent(getApplicationContext(), ProductSearch.class);
searchIntent.putExtra("searchText",etSearch.getText().toString());
startActivity(searchIntent);
}
});
}
}
and another activity like this,
public class ProductSearch extends Activity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.productsearchresults);
String searchQuery = getIntent().getStringExtra("searchText");
ProductSearchMethod test = new ProductSearchMethod();
String entry;
TextView httpStuff = (TextView) findViewById(R.id.httpTextView);
try {
entry = test.getSearchData(searchQuery);
httpStuff.setText(entry);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Yeah... Change your getSearchData() method to include a string as a parameter
public String getSearchData(String query) throws Exception{
Then, insert that string into the query URL, replacing spaces with "+". You may want to do further conditioning to the string, for instance URL encoding it.
URI site = new URI("https://www.googleapis.com/shopping/search/v1/public/products?key=key&country=US&q="+query.replace(" ","+")+"&alt=atom");
In your XML, create a button that contains the following line:
android:onClick="search"
In your ProductSearch activity, add the following method, and move the code in onCreate into it. You will also need to create an EditText in your XML for input.
public void search(View v)
{
EditText searchQuery = (EditText) findViewById(R.id.searchQuery);
ProductSearchMethod test = new ProductSearchMethod();
String returned;
try {
returned = test.getSearchData(searchQuery.getText().toString());
httpStuff.setText(returned);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Finally, you will probably want to read up on running asynchronous tasks so that the query won't freeze your app while performing.
May be I got you wrong, but why don't you just pass it as a parameter in
getSearchData() => getSearchData(string query)
Then you can change the line
URI site = new URI("https://www.googleapis.com/shopping/search/v1/public/products?key=key&country=US&q=digital+camera&alt=atom");
to
URI site = new URI("https://www.googleapis.com/shopping/search/v1/public/products?key=key&country=US&q=+ URLEncoder.encode(query, "UTF-8")+&alt=atom");
Check out http://androidforums.com/developer-101/528924-arduino-android-internet-garage-door-works-but-could-use-input.html I use Asynctask to trigger a get command on a local Arduino server. It appends the Arduino's pin number and, depending on if it's needed, a port number to the end of the URL. I'm sure you could use it to help you out.