I have an Activity that uses a ListView to display an array of data fetched from a JSON response. Clicking on one of the items will present the user with a business card activity, displaying the data associated with the item clicked. When the application first loads, it works fine. I can close the business card and reopen it multiple times. However, if i pause on the ListView activity, the page will no longer load the data. I have placed Log.d commands before and after the connection to try debugging the issue. The activity is receiving the information necessary to perform the connection. However, the closest I have gotten to a solution is knowing that when it doesn't work, I cannot Log.d the response code immediately after opening the connection.
To be clear, I am including the entirety of the code I am using, just in case the issue lies somewhere else. First is the code for the ListView Activity, then is the Business Card Activity code.
This is the Directory Activity.
public class DirectoryActivity extends AppCompatActivity {
ListView lvContacts;
Button goMenu;
Button goFilter;
TextView tempText;
static ArrayList<String> arrlst = new ArrayList<>();
static ArrayAdapter<String> adapter;
private FetchList process;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_directory);
lvContacts = findViewById(R.id.lvContacts);
goMenu = findViewById(R.id.btn_goMenu);
goFilter = findViewById(R.id.btn_goSearch);
tempText = findViewById(R.id.temptext);
// Set adapter for listview: used in FetchList
adapter = new ArrayAdapter<>(this, R.layout.layout_org_list, R.id.listViewItem, arrlst );
lvContacts.setAdapter(adapter);
// Get list from DB
process = new FetchList();
process.setListener(new FetchList.FetchListTaskListener() {
#Override
public void onFetchListTaskFinished(String[] result) {
// update UI in Activity here
arrlst.clear();
for (String OrgName:result) {
addItemsToList(OrgName);
}
adapter.notifyDataSetChanged();
}
});
process.execute();
// Set onclick listener for listview
lvContacts.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
String selectedOrg = lvContacts.getItemAtPosition(position).toString(); // Get org name from list view
goBusinessCard(selectedOrg); // Go to business card
}
});
}
#Override
protected void onDestroy() {
process.setListener(null); // PREVENT LEAK AFTER ACTIVITY DESTROYED
super.onDestroy();
}
public static void addItemsToList(String item) {
arrlst.add(item);
}
// Set Methods for Buttons
public void goMenu(View v) {
startActivity(new Intent(this, HomeActivity.class));
}
public void goFilter(View v) {
startActivity(new Intent(this, FilterActivity.class));
Log.d("FILTER DEBUG", "checking if extras are filled " + this.getIntent().getExtras());
}
// Method for opening BusinessCardActivity and passes orgID
public void goBusinessCard(String selectedOrg) {
Bundle extras = new Bundle();
extras.clear();
extras.putString("selectedOrg", selectedOrg);
Intent BusinessCard = new Intent(this, BusinessCardActivity.class);
BusinessCard.putExtras(extras);
startActivity(BusinessCard);
}
// ASYNC TASK
static class FetchList extends AsyncTask<Void, Void, String[]> {
private FetchListTaskListener listener;
#Override
protected String[] doInBackground(Void... voids) {
try {
URL url = new URL(URL_READ_ORG ); // Set url to API Call location
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); // Open connection to html
InputStream inputStream = httpURLConnection.getInputStream(); // create input stream from html location
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8")); // create reader for inputStream
StringBuilder data = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null ) {
data.append(line); // creates string from all lines in response
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
JSONObject JO = new JSONObject(data.toString()); // creates object from json response in data string
JSONArray JA = JO.getJSONArray("orgs");
// Create array list to store items from json response
List<String> al_orgList = new ArrayList<>();
// Iterate through JSON array to get json object org_name
for (int i = 0; i < JA.length(); i++) {
JSONObject Orgs = JA.getJSONObject(i);
String org_name = Orgs.getString("org_name");
al_orgList.add(org_name);
}
// convert array list to array
return al_orgList.toArray(new String[al_orgList.size()]);
} catch (JSONException | IOException e) {
e.printStackTrace();
}
return null;
}
// UI Process - allows manipulation of UI
#Override
protected void onPostExecute(String[] result) {
super.onPostExecute(result);
if (listener != null) {
listener.onFetchListTaskFinished(result);
}
}
private void setListener(FetchListTaskListener listener) {
this.listener = listener;
}
public interface FetchListTaskListener {
void onFetchListTaskFinished(String[] result);
}
}
This is the Business Card Activity that runs the data fetch for individual items
public class BusinessCardActivity extends AppCompatActivity {
TextView tv_org, tv_name, tv_email, tv_phone, tv_website, tv_servicetype,
tv_servicesprovided, tv_address;
String Favorite, Latitude, Longitude, selectedOrg, FavoriteChanged, dbPhone, phoneNum, dbWeb, orgWeb;
CheckBox cbFavorite;
List<String> arrlstID = new ArrayList<>();
String[] arrID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_business_card);
// Assign fields to variables
tv_org = findViewById(R.id.tv_org);
tv_name = findViewById(R.id.tv_name);
tv_email = findViewById(R.id.tv_email);
tv_phone = findViewById(R.id.tv_phone);
tv_website = findViewById(R.id.tv_website);
tv_servicetype = findViewById(R.id.tv_servicetype);
tv_servicesprovided = findViewById(R.id.tv_servicesprovided);
tv_address = findViewById(R.id.tv_address);
cbFavorite = findViewById(R.id.cbFavorite);
// Set variable for selectedOrg from DirectoryActivity
selectedOrg = Objects.requireNonNull(this.getIntent().getExtras()).getString("selectedOrg");
// Get Org data from DB using async
process = new FetchOrg();
process.setListener(new FetchOrg.FetchOrgTaskListener() {
#Override
public void onFetchOrgTaskFinished(String[] result) {
setTextView(result);
// onClick for Email
tv_email.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
showEmailDialog();
}
});
// onClick for Call
tv_phone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Get phone number from DB
// Replace any non-digit in phone number to make call
phoneNum = dbPhone.replaceAll("\\D", "");
// make call
goCall(phoneNum);
}
});
// onClick for Web
tv_website.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Fix URL logic
orgWeb = "http://" + dbWeb;
goWeb(orgWeb);
}
});
// onClick for Address
tv_address.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
goMap();
}
});
// TODO add favorite functionality
// When checkbox status changes, change value of Favorite
cbFavorite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
});
}
});
process.execute(selectedOrg);
/*
// if favorite = 1 then check box
if (Favorite.equals("1")) {
cbFavorite.setChecked(true);
} else {
cbFavorite.setChecked(false);
}
*/
}
#Override
protected void onDestroy() {
process.setListener(null); // PREVENT LEAK AFTER ACTIVITY DESTROYED
super.onDestroy();
}
// Method to assign text view items from async task
public void setTextView(String[] org_data) {
String name = org_data[1] + " " + org_data[2];
String address = org_data[8] + " " + org_data[9] + " " + org_data[10] + " " + org_data[11];
tv_org.setText(org_data[0]);
tv_name.setText(name);
tv_email.setText(org_data[3]);
tv_phone.setText(org_data[4]);
tv_website.setText(org_data[5]);
tv_servicetype.setText(org_data[6]);
tv_servicesprovided.setText(org_data[7]);
tv_address.setText(address);
}
public void showEmailDialog() {
// Get dialog_box_goals.xml view
LayoutInflater layoutInflater = LayoutInflater.from(BusinessCardActivity.this);
View promptView = layoutInflater.inflate(R.layout.dialog_box_send_email, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(BusinessCardActivity.this);
alertDialogBuilder.setView(promptView);
final EditText etEmailMessage = (EditText) promptView.findViewById(R.id.etMailMessage);
// setup a dialog window
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Submit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// my code
/* WONT USE THIS UNTIL EMAILS ARE FINAL
USING MY EMAIL FOR TESTING PURPOSES
// Get email
niagaraDB.open();
c2 = niagaraDB.getEmailByID(passedID);
if (c2.moveToFirst())
{
public String emailTo = c2.getString(0);
}
niagaraDB.close();
*/
// This is for final code
// String to = "mailto:" + emailTo;
String to = "snownwakendirt#yahoo.com";
String subject = "Mail From Connect & Protect Niagara App";
String message = etEmailMessage.getText().toString();
if (message.isEmpty()) {
Toast.makeText(BusinessCardActivity.this,
"Message must contain something",
Toast.LENGTH_LONG).show();
} else {
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
// email.putExtra(Intent.EXTRA_CC, new String[]{ to});
// email.putExtra(Intent.EXTRA_BCC, new String[]{to});
email.putExtra(Intent.EXTRA_SUBJECT, subject);
email.putExtra(Intent.EXTRA_TEXT, message);
// need this to prompt email client only
email.setType("message/rfc822");
try {
startActivity(Intent.createChooser(email, "Choose an Email client :"));
finish();
Log.i("Email Sent...", "");
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(BusinessCardActivity.this,
"There is no email client installed.",
Toast.LENGTH_SHORT).show();
}
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// create an alert dialog
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
public void goCall(final String phoneNum) {
startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNum, null)));
}
public void goWeb(String orgWeb) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(orgWeb)));
}
public void goCloseBusinessCard(View v) {
finish();
startActivity(new Intent(this, DirectoryActivity.class));
}
public void goMap() {
/*
int locationAddressLatInt = Integer.parseInt(locationAddressLat);
int locationAddressLongInt = Integer.parseInt(locationAddressLong);
*/
// pass id to map view. only one item in array for ease of use in MapActivity
arrlstID.add(selectedOrg);
arrID = new String[arrlstID.size()];
arrlstID.toArray(arrID);
Bundle extras = new Bundle();
extras.putStringArray("arrID", arrID);
Intent Map = new Intent(BusinessCardActivity.this, MapActivity.class);
Map.putExtras(extras);
startActivity(Map);
}
// ASYNC TASK
static class FetchOrg extends AsyncTask<String, Void, String[]> {
private FetchOrgTaskListener listener;
#Override
protected String[] doInBackground(String... params) {
try {
// assign passed string from main thread
String org_name = params[0];
String orgbyname = URL_GET_ORG_BY_NAME + "?org_name=" + org_name;
String line = "";
URL url = new URL(orgbyname);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
line = br.readLine();
br.close();
is.close();
conn.disconnect();
/*
This JSON section contains a JSON Object that holds a JSON Array. The Array is created to
individualize each object within the JSON Array. Then, each JSON object is fetched and
assigned to a string variable.
*/
JSONObject JO = new JSONObject(line); // creates object from json response in data string
JSONObject Orgs = JO.getJSONObject("orgs"); // creates array for parsing of json data
// get items from JSONArray and assign for passing to onProgressUpdate
String Org = Orgs.getString("org_name");
String FirstName = Orgs.getString("contact_first_name");
String LastName = Orgs.getString("contact_last_name");
String Email = Orgs.getString("contact_email");
String Phone = Orgs.getString("contact_phone");
String Website = Orgs.getString("org_website");
String ServiceType = Orgs.getString("org_type");
String ServicesProvided = Orgs.getString("org_services");
String Address = Orgs.getString("org_street_address");
String City = Orgs.getString("org_city");
String State = Orgs.getString("org_state");
String Zip = Orgs.getString("org_zip");
String Lat = Orgs.getString("latitude");
String Long = Orgs.getString("longitude");
// Add items to string array
String[] org_data = new String[14]; // 14 is length of array, not the count
org_data[0] = Org;
org_data[1] = FirstName;
org_data[2] = LastName;
org_data[3] = Email;
org_data[4] = Phone;
org_data[5] = Website;
org_data[6] = ServiceType;
org_data[7] = ServicesProvided;
org_data[8] = Address;
org_data[9] = City;
org_data[10] = State;
org_data[11] = Zip;
org_data[12] = Lat;
org_data[13] = Long;
return org_data;
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
super.onPostExecute(result);
if (listener != null) {
listener.onFetchOrgTaskFinished(result);
}
}
private void setListener(FetchOrgTaskListener listener) {
this.listener = listener;
}
public interface FetchOrgTaskListener {
void onFetchOrgTaskFinished(String[] result);
}
}
Activity lifecycle would go back from paused to resume state.
You need to provide the expected behaviour inside onResume something like below
public void onResume(){
super.onResume();
new XXXAsyncTask( new XXXAsyncListener(){
public void postTaskMethod(){
//do stuff here
}
}).execute();
}
I made a few changes in your onCreate()method of your BusinessCardActivity. I check for hasExtra instead--a little more flexibility. I got rid of the Listener and packed all onClick listener below. I felt it was a bit too complicated using the Listener approach (So you can remove this process.setListener(null); from the onDestroy()method). I also added a few Log.e(); so you can see what is going on in the logcat.
(BTW "TAG" would be:
private static final Strting TAG = BusinessCardActivity.class.getSimpleName();)
With "BusinessCardActivity.class.getSimpleName();" written out just in case you refactor sometime.
This is part of your BusinessCardActivity onCreate() method:
// Set variable for selectedOrg from DirectoryActivity
Intent intent = this.getIntent();
if(intent.hasExtra(selectedOrg)){
String selectedOrg = intent.getStringExtra("selectedOrg")
Log.e(TAG, "selectedOrg : " + selectedOrg);
FetchOrg process = new FetchOrg();
process.execute(selectedOrg);
}
else{
Log.e(TAG, "No Extras!")
//You might what to call finish() here
return;
}
//Move all your onClick Listeners below...
I don't think this is the best case to use a Listener so lets use the AsyncTask like this (I also removed the static):
class FetchOrg extends AsyncTask<String, Void, String[]> {
#Override
protected String[] doInBackground(String... params) {
try {
Log.e(TAG, "doInBackground ... Started");
// assign passed string from main thread
String org_name = params[0];
String orgbyname = URL_GET_ORG_BY_NAME + "?org_name=" + org_name;
String line = "";
URL url = new URL(orgbyname);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
line = br.readLine();
br.close();
is.close();
conn.disconnect();
Log.e(TAG, "Data Returned : " + line);
/*
This JSON section contains a JSON Object that holds a JSON Array. The Array is created to
individualize each object within the JSON Array. Then, each JSON object is fetched and
assigned to a string variable.
*/
JSONObject JO = new JSONObject(line); // creates object from json response in data string
JSONObject Orgs = JO.getJSONObject("orgs"); // creates array for parsing of json data
// get items from JSONArray and assign for passing to onProgressUpdate
String Org = Orgs.getString("org_name");
String FirstName = Orgs.getString("contact_first_name");
String LastName = Orgs.getString("contact_last_name");
String Email = Orgs.getString("contact_email");
String Phone = Orgs.getString("contact_phone");
String Website = Orgs.getString("org_website");
String ServiceType = Orgs.getString("org_type");
String ServicesProvided = Orgs.getString("org_services");
String Address = Orgs.getString("org_street_address");
String City = Orgs.getString("org_city");
String State = Orgs.getString("org_state");
String Zip = Orgs.getString("org_zip");
String Lat = Orgs.getString("latitude");
String Long = Orgs.getString("longitude");
// Add items to string array
String[] org_data = new String[14]; // 14 is length of array, not the count
org_data[0] = Org;
org_data[1] = FirstName;
org_data[2] = LastName;
org_data[3] = Email;
org_data[4] = Phone;
org_data[5] = Website;
org_data[6] = ServiceType;
org_data[7] = ServicesProvided;
org_data[8] = Address;
org_data[9] = City;
org_data[10] = State;
org_data[11] = Zip;
org_data[12] = Lat;
org_data[13] = Long;
return org_data;
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
setTextView(result);
}
}
Also I would change your method goBusinessCard() a bit (and no need to be public):
private void goBusinessCard(String selectedOrg) {
//Java variables should written in lower case and Classes Capitalized
Intent businessCard = new Intent(this, BusinessCardActivity.class);
businessCard.putExtra("selectedOrg", selectedOrg);
startActivity(businessCard);
}
Please let me know if you have any issues! I typed this out in a standard Text Editor..so there might be a few typos.
Posting a new answer so I can add all the code for the BusinessCardActivity class.
I added some additional logging and changed getString() to optString() in order to be able to offer an alternative value. For example if the value or "key" is invalid or missing you would get an error.
public class BusinessCardActivity extends AppCompatActivity {
TextView tv_org, tv_name, tv_email, tv_phone, tv_website, tv_servicetype,
tv_servicesprovided, tv_address;
String Favorite, Latitude, Longitude, FavoriteChanged, dbPhone, phoneNum, dbWeb, orgWeb;
CheckBox cbFavorite;
List<String> arrlstID = new ArrayList<>();
String[] arrID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_business_card);
// Assign fields to variables
tv_org = findViewById(R.id.tv_org);
tv_name = findViewById(R.id.tv_name);
tv_email = findViewById(R.id.tv_email);
tv_phone = findViewById(R.id.tv_phone);
tv_website = findViewById(R.id.tv_website);
tv_servicetype = findViewById(R.id.tv_servicetype);
tv_servicesprovided = findViewById(R.id.tv_servicesprovided);
tv_address = findViewById(R.id.tv_address);
cbFavorite = findViewById(R.id.cbFavorite);
Intent intent = this.getIntent();
if(!intent.hasExtra("selectedOrg")){
Log.e(TAG, "No Extras!")
//You might what to call finish() here
return;
}
String selectedOrg = intent.getStringExtra("selectedOrg")
Log.e(TAG, "selectedOrg : " + selectedOrg);
FetchOrg process = new FetchOrg();
process.execute(selectedOrg);
// onClick for Email
tv_email.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
showEmailDialog();
}
});
// onClick for Call
tv_phone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Get phone number from DB
// Replace any non-digit in phone number to make call
phoneNum = dbPhone.replaceAll("\\D", "");
// make call
goCall(phoneNum);
}
});
// onClick for Web
tv_website.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Fix URL logic
orgWeb = "http://" + dbWeb;
goWeb(orgWeb);
}
});
// onClick for Address
tv_address.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
goMap();
}
});
// TODO add favorite functionality
// When checkbox status changes, change value of Favorite
cbFavorite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
});
/*
// if favorite = 1 then check box
if (Favorite.equals("1")) {
cbFavorite.setChecked(true);
} else {
cbFavorite.setChecked(false);
}
*/
}
#Override
protected void onDestroy() {
process.setListener(null); // PREVENT LEAK AFTER ACTIVITY DESTROYED
super.onDestroy();
}
// Method to assign text view items from async task
public void setTextView(String[] org_data) {
String name = org_data[1] + " " + org_data[2];
String address = org_data[8] + " " + org_data[9] + " " + org_data[10] + " " + org_data[11];
tv_org.setText(org_data[0]);
tv_name.setText(name);
tv_email.setText(org_data[3]);
tv_phone.setText(org_data[4]);
tv_website.setText(org_data[5]);
tv_servicetype.setText(org_data[6]);
tv_servicesprovided.setText(org_data[7]);
tv_address.setText(address);
}
public void showEmailDialog() {
// Get dialog_box_goals.xml view
LayoutInflater layoutInflater = LayoutInflater.from(BusinessCardActivity.this);
View promptView = layoutInflater.inflate(R.layout.dialog_box_send_email, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(BusinessCardActivity.this);
alertDialogBuilder.setView(promptView);
final EditText etEmailMessage = (EditText) promptView.findViewById(R.id.etMailMessage);
// setup a dialog window
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Submit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// my code
/* WONT USE THIS UNTIL EMAILS ARE FINAL
USING MY EMAIL FOR TESTING PURPOSES
// Get email
niagaraDB.open();
c2 = niagaraDB.getEmailByID(passedID);
if (c2.moveToFirst())
{
public String emailTo = c2.getString(0);
}
niagaraDB.close();
*/
// This is for final code
// String to = "mailto:" + emailTo;
String to = "snownwakendirt#yahoo.com";
String subject = "Mail From Connect & Protect Niagara App";
String message = etEmailMessage.getText().toString();
if (message.isEmpty()) {
Toast.makeText(BusinessCardActivity.this,
"Message must contain something",
Toast.LENGTH_LONG).show();
} else {
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
// email.putExtra(Intent.EXTRA_CC, new String[]{ to});
// email.putExtra(Intent.EXTRA_BCC, new String[]{to});
email.putExtra(Intent.EXTRA_SUBJECT, subject);
email.putExtra(Intent.EXTRA_TEXT, message);
// need this to prompt email client only
email.setType("message/rfc822");
try {
startActivity(Intent.createChooser(email, "Choose an Email client :"));
finish();
Log.i("Email Sent...", "");
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(BusinessCardActivity.this,
"There is no email client installed.",
Toast.LENGTH_SHORT).show();
}
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
// create an alert dialog
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
public void goCall(final String phoneNum) {
startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNum, null)));
}
public void goWeb(String orgWeb) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(orgWeb)));
}
public void goCloseBusinessCard(View v) {
finish();
startActivity(new Intent(this, DirectoryActivity.class));
}
public void goMap() {
/*
int locationAddressLatInt = Integer.parseInt(locationAddressLat);
int locationAddressLongInt = Integer.parseInt(locationAddressLong);
*/
// pass id to map view. only one item in array for ease of use in MapActivity
arrlstID.add(selectedOrg);
arrID = new String[arrlstID.size()];
arrlstID.toArray(arrID);
Bundle extras = new Bundle();
extras.putStringArray("arrID", arrID);
Intent Map = new Intent(BusinessCardActivity.this, MapActivity.class);
Map.putExtras(extras);
startActivity(Map);
}
// ASYNC TASK
class FetchOrg extends AsyncTask<String, Void, String[]> {
#Override
protected String[] doInBackground(String... params) {
HttpURLConnection con = null;
String[] org_data = null;
try {
Log.e(TAG, "FetchOrg doInBackground started");
// assign passed string from main thread
String org_name = params[0];
String orgbyname = URL_GET_ORG_BY_NAME + "?org_name=" + org_name;
URL url = new URL(orgbyname);
con = (HttpURLConnection) url.openConnection();
Log.e(TAG, "FetchOrg doInBackground Connected!");
//Check the response code of the server -
Integer replyCode = con.getResponseCode();
logMess += " Reply Code: " + replyCode.toString();
responseStream = new BufferedInputStream(con.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
stopTime = System.currentTimeMillis();
elapsedTime = stopTime - startTime;
logMess += " elapsed Time : " + elapsedTime + " ms";
Log.e(TAG, "FetchOrg logMess: --- " + logMess);
String line = "";
StringBuilder stringBuilder = new StringBuilder();
//Make sure you get everything!
while ((line = responseStreamReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
//this will close underlying streams
responseStreamReader.close();
String data = stringBuilder.toString();
Log.e(TAG, "FetchOrg Data: --- " + data);
/*
This JSON section contains a JSON Object that holds a JSON Array. The Array is created to
individualize each object within the JSON Array. Then, each JSON object is fetched and
assigned to a string variable.
*/
JSONObject obj = new JSONObject(data); // creates object from json response in data string
JSONObject orgs = obj.getJSONObject("orgs"); // creates array for parsing of json data
String nA = "not available";
// get items from JSONArray and assign for passing to onProgressUpdate
String Org = orgs.optString("org_name", nA);
String FirstName = orgs.optString("contact_first_name", nA);
String LastName = orgs.optString("contact_last_name", nA);
String Email = orgs.optString("contact_email", nA);
String Phone = orgs.optString("contact_phone", nA);
String Website = orgs.optString("org_website", nA);
String ServiceType = orgs.optString("org_type", nA);
String ServicesProvided = orgs.optString("org_services", nA);
String Address = orgs.optString("org_street_address", nA);
String City = orgs.optString("org_city", nA);
String State = orgs.optString("org_state", nA);
String Zip = orgs.optString("org_zip", nA);
String Lat = orgs.optString("latitude", nA);
String Long = orgs.optString("longitude", nA);
// Add items to string array
org_data = new String[14]; // 14 is length of array, not the count
org_data[0] = Org;
org_data[1] = FirstName;
org_data[2] = LastName;
org_data[3] = Email;
org_data[4] = Phone;
org_data[5] = Website;
org_data[6] = ServiceType;
org_data[7] = ServicesProvided;
org_data[8] = Address;
org_data[9] = City;
org_data[10] = State;
org_data[11] = Zip;
org_data[12] = Lat;
org_data[13] = Long;
} catch (Exception ex) {
Log.e(TAG, "FetchOrg doInBackground: " + ex.getMessage());
}
finally{
//just in case you get an error above
if(con != null){
con.disconnect();
}
}
return org_data;
}
#Override
protected void onPostExecute(String[] result) {
if(result != null){
setTextView(result);
}
else{
Log.e(TAG, "FetchOrg onPostExecute: result is null");
}
}
}
Be aware that I did not clean up things like maintaining minimal scope: For example :public void showEmailDialog() and public void goMap() which do not need to be public methods! Any method that does not need to be accessed outside the class (and that is rare!) should not be made public.
You have also defined many class variables at the beginning of the class like "Favorite, Latitude, Longitude, FavoriteChanged" do they need to have class wide scope?? And they are variables! So in java naming convention, variables and methods are written in lower case, while classes are capitalized--this helps reading code easier (for the SO community!)
When working with Indent extras often mistakes are made when entering the "key" like "selectedOrg". Therefore it is some times an advantage to create a global class to help keep things straight. Example public class GlobalExtras and just keep public static final String SELECTED_ORG = "selectedOrg"; Then just use intent.getString(SELECTED_ORG);
Another thing: I am not a big fan of String[] as you have used to store your "org" strings. They can be tricky with size and indexes. You might want to consider using another object.
I do not have access to your API and your data, so I was only able to make requests on my server trying to duplicate your user scenario, but I was unable to reproduce your issue. I hope this helps, let me know what the logcat spits out!
I want to show progress bar with percentage of the download the data from json. Right now I am getting the data from the url and store in the local database in other class and this class called in MainActivity. Now I want to show the progressbar with percentage of the download file from json url.
This is my code
public class Web_Product {
Context context;
List<Variable> list = new ArrayList<Variable>();
//List<Variable> list1;
String url = "https://api.androidhive.info/progressdialog/hive.jpg";
URL url1 = null;
InputStream is1 = null;
String product_id, product_name, product_image;
private byte[] logoImage;
private JSONArray jsonArray;
public Web_Product(Context context) {
this.context = context;
Log.e("hello", "Message");
}
public void product_insert() {
// new AsyncLogin().execute();
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.e("TEST", "jsonStr:-" + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonRootObject = new JSONObject(jsonStr);
//Get the instance of JSONArray that contains JSONObjects
JSONArray jsonArray = jsonRootObject.optJSONArray("product");
//Iterate the jsonArray and print the info of JSONObjects
for (int i = 0; i < jsonArray.length(); i++) {
Log.e("TEST_P", "in");
JSONObject details = jsonArray.getJSONObject(i);
product_id = details.getString("product_id");
product_name = details.getString("product_name");
product_image = details.getString("product_image");
logoImage = getLogoImage(product_image);
Variable variable_object = new Variable();
variable_object.setProduct_id(product_id);
variable_object.setProduct_name(product_name);
variable_object.setProduct_url_image(logoImage);
list.add(variable_object);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
Log.e("TEST1", " Ritunjay" + list.size());
Product_data product = new Product_data(context);
product.Insert_Product(list);
Log.e("listpo", "" + list);
}
public JSONArray json_web_prod() {
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.e("TEST", "jsonStr:-" + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonRootObject = new JSONObject(jsonStr);
//Get the instance of JSONArray that contains JSONObjects
jsonArray = jsonRootObject.optJSONArray("product");
} catch (JSONException e) {
e.printStackTrace();
}
}
return jsonArray;
}`
Main Activity
class add extends AsyncTask<String, Integer, String> {
ProgressDialog mProgressDialog;
#Override
protected void onProgressUpdate(Integer... values) {
mProgressDialog.setProgress(values[0]);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setTitle("Downloading Data...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected void onPostExecute(String aVoid) {
super.onPostExecute(aVoid);
mProgressDialog.dismiss();
flag = true;
Intent intent = getIntent();
startActivity(intent);
finish();
Log.e("flag , post", "" + flag);
}
#Override
protected String doInBackground(String... params) {
web_product = new Web_Product(getApplicationContext());
web_product.product_insert();
return null;
}
}`
In doInBackground , you need to publishProgress also . So that your progress bar can updated , like this
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
Here totalSize will help you to calculate your total remaining data and publishProgress will public it .
when i am doing offline login my app is crashing...and showing the error
Attempt to invoke virtual method 'java.lang.String org.json.JSONObject.getString(java.lang.String)' on a null object reference
In Online it is working fine no issues but in offline it is crashing not at all giving where the issue is please help me in this
public class MainActivity extends AppCompatActivity {
**// Initializing variables**
EditText login;
EditText password;
String statusRes;
String id;
String projectName;
String loginValue;
String stockPoint;
JSONObject myRespObject = null;
public static final String Passkey = "passKey";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("LOGIN");
setContentView(R.layout.login);
login = (EditText) findViewById(R.id.loginname);
password = (EditText) findViewById(R.id.Password);
final Button saveme = (Button) findViewById(R.id.save);
**SharedPreferences sharedpreferences = getSharedPreferences(AppConstants.MyPREFERENCES, Context.MODE_PRIVATE);
saveme.setOnClickListener(new Button.OnClickListener() {
public URL url;
public void onClick(android.view.View v) {
if (!CheckNetwork.isInternetAvailable(MainActivity.this){
if (!validate()) {
onLoginFailed();
return;
}
SharedPreferences prefs = getSharedPreferences(AppConstants.MyPREFERENCES, Context.MODE_PRIVATE);
String loginValue = prefs.getString(AppConstants.LOGIN_VALUE, "");
String Passkey = prefs.getString(AppConstants.PASS_KEY, "");
String Internet = prefs.getString("Internet", "false");
String projectName = prefs.getString(AppConstants.PROJECT_NAME, "");
String stockPoint = prefs.getString(String.valueOf(AppConstants.STOCK_POINT),"");
String id = prefs.getString(AppConstants.ID, "");
Intent profactivity = new Intent(MainActivity.this, View.class);
profactivity.putExtra("Internet", false);
profactivity.putExtra("loginValue", loginValue);
profactivity.putExtra("id", id);
profactivity.putExtra("projectName", projectName);
profactivity.putExtra("stockPoint", stockPoint);
startActivity(profactivity);
**Toast.makeText(MainActivity.this, "Offline Login ", Toast.LENGTH_SHORT).show();
finish();
}
****for the above code, here it is throughing the error**
try {
final String loginValue = URLEncoder.encode(login.getText().toString(), "UTF-8");
final String passValue = URLEncoder.encode(password.getText().toString(), "UTF-8");
try {
new Thread(new Runnable() {
**//Thread to stop network calls on the UI thread**
public void run() {
//Request the HTML
ArrayList<String> list = null;
try {
String loginValue = URLEncoder.encode(login.getText().toString(), "UTF-8");
String passValue = URLEncoder.encode(password.getText().toString(), "UTF-8");
String ROOT_URL = getResources().getString(R.string.ROOT_URL) + "/api/v1/user/signIn?loginName=" + loginValue + "&password=" + passValue;
Log.i("httpget", "################" + ROOT_URL);
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(ROOT_URL);
HttpResponse response = client.execute(request);
if (response.getStatusLine().getStatusCode() == 200) {
String server_response = EntityUtils.toString(response.getEntity());
myRespObject = new JSONObject(server_response);
//Do something with the response
//Toast.makeText(getBaseContext(),server_response,Toast.LENGTH_LONG).show();
statusRes = myRespObject.getString("status");
JSONObject respObject = myRespObject.getJSONObject("response");
id = respObject.getString("_id");
AppConstants._ID = id;
projectName = respObject.getString("projectName");
Actors actor = new Actors();
list = new ArrayList<>();
JSONArray jsonArray = respObject.getJSONArray("stockPoint");
Intent i = getIntent();
Serializable subject = i.getSerializableExtra("stockPoint");
if (jsonArray != null) {
int len = jsonArray.length();
for (int k = 0; k < len; k++)
list.add(jsonArray.get(k).toString());
}
actor.setStockPoint(list);
AppConstants.STOCK_POINT = stockPoint;
stockPoint = respObject.getString("stockPoint");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
final ArrayList<String> finalList = list;
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
statusRes = myRespObject.getString("status");
} catch (JSONException e) {
e.printStackTrace();
}
if (statusRes.equalsIgnoreCase("success")) {
SharedPreferences sharedpreferences = getSharedPreferences(AppConstants.MyPREFERENCES, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(AppConstants.LOGIN_VALUE, loginValue);
editor.putString(AppConstants.PASS_KEY, passValue);
editor.putString("Internet", "true");
editor.putString(AppConstants.ID, id);
editor.putString(AppConstants.PROJECT_NAME, projectName);
editor.putString(String.valueOf(AppConstants.STOCK_POINT), String.valueOf(stockPoint));
editor.commit();
**//Here move to next screen or home screen**
Intent profactivity = new Intent(MainActivity.this, View.class); profactivity.putExtra("Internet", true); profactivity.putExtra("loginValue", loginValue); profactivity.putExtra("id", id);
profactivity.putExtra("projectName", projectName);
profactivity.putExtra("stockPoint", finalList);
startActivity(profactivity);
Toast.makeText(MainActivity.this, "Login Successfully", Toast.LENGTH_LONG).show();
finish();
} else if (statusRes.equalsIgnoreCase("failed")) {
if (!validate()) {
onLoginFailed();
return;
}
}
}
});
}
}).start();
//return data;
} catch (Exception e) {
Log.i("httpget", "################Error1 -->" + e.getStackTrace());
**Toast.makeText(getBaseContext(), "ERROR : " + e.getMessage(), Toast.LENGTH_LONG).show();**
}
} catch (UnsupportedEncodingException ex) {
finish();
}
}
});
}
public boolean validate() {
boolean valid = true;
String email = login.getText().toString();
String passwor = password.getText().toString();
if (email.isEmpty() || email.length() < 2 || email.length() > 10) {
login.setError("enter valid username");
valid = false;
} else {
login.setError("Invalid username");
}
if (passwor.isEmpty() || passwor.length() < 2 || passwor.length() > 10) {
password.setError("enter valid password");
valid = false;
} else {
password.setError("Invalid password");
}
return valid;
}
public void onLoginFailed() {
**Toast.makeText(getBaseContext(), "Invalid login", Toast.LENGTH_LONG).show();**
}
}
--------------------------------------------------------------------------------
The error that you have mentioned says you have error on following line.
projectName = respObject.getString("projectName");
"responseObject" is null, hence you are getting NullPointerException.
Here i am fetch sms from phone and upload 10 sms on server all code working fine but instead of 10 sms upload to server only Specific one sms uploaded 10 time to server, pls tell me what i am missing in my code?
here is my message_class.Java code.
public class message_class extends Activity{
int j = 0;
Button btninbox;
ListView lstView;
SimpleCursorAdapter adapter;
ArrayList<Message_Item> msg_list;
String Str_Msg, Str_Phone,dated;
Msg_adapter msg_adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.msginbox_layout);
msg_list = new ArrayList<Message_Item>();
btninbox = (Button) findViewById(R.id.btn_inbox);
btninbox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(message_class.this, Msg_Recive.class);
startActivity(intent);
}
});
lstView = (ListView) findViewById(R.id.lv_msg);
fetchInbox();
final int arraysize = msg_list.size();
for (int j=0; j<10;j++){
Str_Msg = msg_list.get(j).getStrMsg().toString();
Str_Phone = msg_list.get(j).getStrNumber().toString();
Toast.makeText(message_class.this, Str_Phone+" "+Str_Msg, Toast.LENGTH_LONG).show();
new HttpAsyncTask()
.execute("http://demo.glowsosl.com/synchs_dsda_app/insert_details_msg.php");
msg_adapter.notifyDataSetChanged();
}
}
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
Contacts person = new Contacts();
person.setPhone(Str_Phone);
person.setName(Str_Msg);
return POST(urls[0], person);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), result + "Data Sent!",
Toast.LENGTH_LONG).show();
}
}
private static String convertInputStreamToString(InputStream inputStream)
throws IOException {
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream));
String line = "";
String result = "";
while ((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
public static String POST(String url, Contacts person) {
InputStream inputStream = null;
String result = "";
try {
// 1. create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 2. make POST request to the given URL
HttpPost httpPost = new HttpPost(url);
String json = "";
// 3. build jsonObject
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("contact_no", person.getPhone());
jsonObject.accumulate("sim_num", "Unknown");
jsonObject.accumulate("msg", person.getName());
// 4. convert JSONObject to JSON to String
json = jsonObject.toString();
// 5. set json to StringEntity
StringEntity se = new StringEntity(json);
// 6. set httpPost Entity
httpPost.setEntity(se);
// 7. Set some headers to inform server about the type of the
// content
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
// 8. Execute POST request to the given URL
HttpResponse httpResponse = httpclient.execute(httpPost);
// 9. receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
// 10. convert inputstream to string
if (inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
// 11. return result
return result + "," + person.getName() + ","
+ person.getPhone();
}
ArrayList<String> jsonStringToArray(String jsonString) throws JSONException {
ArrayList<String> stringArray = new ArrayList<String>();
JSONArray jsonArray = new JSONArray(jsonString);
for (int i = 0; i < jsonArray.length(); i++) {
stringArray.add(jsonArray.getString(i));
}
return stringArray;
}
public void fetchInbox() {
// ArrayList sms = new ArrayList();
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(uriSms,
new String[] { "_id", "address", "date", "body" }, null, null,
null);
//for (int i =0; i<((JSONArray) cursor).length();i++){
//Toast.makeText(getApplicationContext(), "work", Toast.LENGTH_SHORT).show();
//}
cursor.moveToFirst();
while (cursor.moveToNext()) {
String address = cursor.getString(1);
String date = cursor.getString(2);
String body = cursor.getString(3);
// Toast.makeText(getApplicationContext(), cursor.getString(2), Toast.LENGTH_SHORT).show();
msg_list.add(new Message_Item(address, body,date));
}
msg_adapter = new Msg_adapter(msg_list, message_class.this);
lstView.setAdapter(msg_adapter);
}
Instead of applying for loop out side async task use it in doInBackground method.
Your doInBackground method will look like follows.
#Override
protected String doInBackground(String... urls) {
String result="";
for(int i = 0; i < msg_list.size(); i++){
Str_Msg = msg_list.get(i).getStrMsg().toString();
Str_Phone = msg_list.get(i).getStrNumber().toString();
Contacts person = new Contacts();
person.setPhone(Str_Phone);
person.setName(Str_Msg);
result= result + POST(urls[0], person);
}
return result;
}
And call this async task only once.
Enjoy!!
I made class extends service and I wrote a separate thread sleeps for 1 sec
My service and Thread:
public class UpdaterService extends Service {
private static String TAG = UpdaterService.class.getSimpleName();
private Updater updater;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
updater = new Updater();
updater.start();
Log.d(TAG, "Create'd");
super.onCreate();
}
#Override
public synchronized int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Start'd");
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Log.d(TAG, "Destroy'd");
super.onDestroy();
}
class Updater extends Thread {
ArrayList<chatData> list = new ArrayList<chatData>();
ArrayList<String> getContactsList = new ArrayList<String>();
Boolean thereIsNewData = false;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String yourID = prefs.getString("KEY_USERNAME", "No login info available");
void getData(){
chatServiceHandler jsonParser = new chatServiceHandler();
ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
nvp.add(new BasicNameValuePair("yourID", yourID));
String json = jsonParser.makeServiceCall("http://example.com/getMSG.php", contactsServiceHandler.GET, nvp);
Log.d("Response: ", "> " + json);
if (json != null) {
try {
JSONObject jsonObj = new JSONObject(json);
if (jsonObj != null) {
list.clear();
JSONArray contactsArray = jsonObj.getJSONArray("MSGhandling");
for (int i = 0; i < contactsArray.length(); i++) {
JSONObject catObj = (JSONObject) contactsArray.get(i);
chatData cat = new chatData(catObj.getString("sender"), catObj.getString("receiver"),catObj.getString("msg"),catObj.getString("msgID"));
list.add(cat);
thereIsNewData = true;
}
}
} catch (JSONException e) {
e.printStackTrace();
thereIsNewData = false;
}
} else {
Log.e("JSON Data", "Didn't receive any data from server!");
thereIsNewData = false;
}
}
#Override
public void run() {
while (true) {
try {
DatabaseAdapter helper = new DatabaseAdapter(UpdaterService.this);
getData();
if(thereIsNewData){
for(int i =0; i < list.size(); i++){
chatData messages = list.get(i);
Log.d(TAG, "From: "+messages.getSenderID()+" TO:"+messages.getReceiverID()+" MSG: "+messages.getMSG());
helper.storeMSG(messages.getSenderID() , messages.getReceiverID() , messages.getMSG() , messages.getMsgID());
Intent newMessage = new Intent();
newMessage.setAction("NEW_MESSAGE");
sendBroadcast(newMessage);
}
list.clear();
thereIsNewData = false;
}else{
Log.d(TAG, "There is no new data");
}
sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
}
It works fine for like 10 secs it loops for 10 times but after that it stops for like 30 secs and shows this error:
LOG_CAT:
190-318/system_process E/ThrottleService﹕ problem during onPollAlarm: java.lang.IllegalStateException: problem parsing stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No such file or directory)
03
Then the same thing happen loops for 10 secs then stops for 30 more