AlertDialog not refreshing data - java

public void setFileName(String inMake, String inModel) {
//sets spinner to get year
filename = filename.concat(inMake);
filename = filename.concat(inModel);
filename = filename.concat(".txt");
spinner3 = (Spinner) findViewById(R.id.spinner3);
BufferedReader reader;
AssetManager assetManager = MainActivity.getContext().getAssets();
List<String> testYears = new ArrayList<String>();
try {
InputStream istr = assetManager.open(filename);
reader = new BufferedReader(new InputStreamReader(istr));
String line;
while((line = reader.readLine()) != null) {
testYears.add(line);
}
}
catch (IOException e){
Log.e("message: ",e.getMessage());
}
AlertDialog.Builder yearDialog = new Builder(this);
yearDialog.setTitle("Select Year");
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.select_dialog_singlechoice, testYears);
adapter.notifyDataSetChanged();
yearDialog.setAdapter(adapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
year = Integer.parseInt(adapter.getItem(which));
Toast.makeText(getApplicationContext(),
"Year : " + year, Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = yearDialog.create();
alert.show();
}
I'm attempting to retrieve a user choice via an alertdialog. The array it uses for the arrayAdapter is based on the input of the function(string inmake, string inmodel) which are passed from outside the activity. This method seems to work perfectly - but only the first time. If I send in new string information to the method, it doesn't show any options in the alertdialog.
Any help would be much obliged.

Related

can not display file content in text view

i am trying to select a file from the alert dialog and when i press OK i should display the content of the selected file in a text View by using the method display Content() that take the selected file read it and display the content line by line, but it does not display anything and i think the problem is with the call because i already use the method in another app and it work.
this is the code i have and how i call displayContent()
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle("Single Choice List")
.setSingleChoiceItems(files, 0, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
selectionID = which;
}
})
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//display the content of the selected file
displayContent();
Toast.makeText(View_Records.this, "You selected " + files[selectionID], Toast.LENGTH_SHORT).show();
}
})
this is the code for displayContent():
private void displayContent(){
try {
myFilesDirectory = new File(getFilesDir(), "MyFiles");
String fileName = files[selectionID] + ".txt";
File file = new File(myFilesDirectory, fileName);
String text;
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((text = br.readLine()) != null) {
sb.append(text).append("\n");
}
txtViewRecords.setText(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Replace
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle("Single Choice List")
.setSingleChoiceItems(files, 0, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
selectionID = which;
}
})
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//display the content of the selected file
displayContent();
Toast.makeText(View_Records.this, "You selected " + files[selectionID], Toast.LENGTH_SHORT).show();
}
})
with calling for another Activity (startActivityForResult()) with dialog style where you will pick a File and return it's path with Intent and then inside onActivityResult() you just use it to open File and then display it's content inside TextView.
Otherwise you can try to use create() first and add onDismissListener(). Like this:
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
// do you things with builder
AlertDialog ad = builder.create();
ad.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
// here you open file, read content and put it inside TextView`
}
});
ad.show()
I'm not sure, but this should do the job with AlertDialog without creating Activity for this.
This is for getting all files from directory:
public static ArrayList<File> listFiles(File folder) {
if (folder.isDirectory()) {
ArrayList<File> tempList = new ArrayList<>();
File[] files = folder.listFiles();
for (File inFile : files) {
if (!inFile.isDirectory()) {
tempList.add(inFile);
}
}
/*Collections.sort(tempList, new Comparator<File>() { //you can sort by name
#Override
public int compare(File file1, File file2) {
return file1.getName().compareTo(file2.getName());
}
});*/
return tempList;
}
return null;
}
And you just send myFilesDirectory as a parameter.
Also you can skip checking if(!inFile.isDirectory()) if you are 100% sure that all files are files, not directories and return Array.
And then you just get your file using list.get(selectionID) or array[selectionID] depending what you are going to return from method.
Also method doesn't need to be static. I've got it static for my project needs.

EditView only displays the last line of the text file

my App saves the text of a multi-line EditView to a text file, but the problem is that if I restart my app, only the last line gets restored. (Perhaps it's also possible that the FileOutputStream only saves the last line, I am not sure ¯_(ツ)_/¯)
Here is my code:
private static final String TAG = "EditDataActivity";
public static String Textfile = "test.txt";
private Button btnSave,btnDelete;
private EditText editable_item;
EditText Zutaten, Zubereitung;
DatabaseHelper mDatabaseHelper;
private String selectedName;
private int selectedID;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_data_layout);
btnSave = (Button) findViewById(R.id.btnSave);
btnDelete = (Button) findViewById(R.id.btnDelete);
editable_item = (EditText) findViewById(R.id.editable_item);
mDatabaseHelper = new DatabaseHelper(this);
Zutaten = (EditText)findViewById(R.id.editText4);
Zubereitung = (EditText)findViewById(R.id.editText2);
Zutaten.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try{
EditText test = (EditText)findViewById(R.id.editable_item);
String testText = test.getText().toString();
String Textfile2 = testText + ".txt";
EditText field = (EditText)findViewById(R.id.editText4);
String text = field.getText().toString();
FileOutputStream fos = openFileOutput(Textfile2, Context.MODE_PRIVATE);
fos.write(text.getBytes());
fos.close();
}catch (IOException e){
System.out.println("Error");
}
}
});
Intent receivedIntent = getIntent();
selectedID = receivedIntent.getIntExtra("id",-1); //NOTE: -1 is just the default value
selectedName = receivedIntent.getStringExtra("name");
editable_item.setText(selectedName);
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
EditText test = (EditText)findViewById(R.id.editable_item);
String testText = test.getText().toString();
String Textfile2 = testText + ".txt";
EditText field = (EditText)findViewById(R.id.editText4);
String text = field.getText().toString();
FileOutputStream fos = openFileOutput(Textfile2, Context.MODE_PRIVATE);
fos.write(text.getBytes());
fos.close();
}catch (IOException e){
System.out.println("Error");
}
Toast.makeText(getApplicationContext(), "Rezept erfolgreich gespeichert!", Toast.LENGTH_SHORT).show();
Intent back = new Intent(EditDataActivity.this, MainActivity.class);
startActivity(back);
String item = editable_item.getText().toString();
if (!item.equals("")) {
mDatabaseHelper.updateName(item, selectedID, selectedName);
} else {
toastMessage("Du musst das Rezept benennen!");
}
}
});
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
EditText test = (EditText)findViewById(R.id.editable_item);
String testText = test.getText().toString();
String Textfile2 = testText + ".txt";
EditText field = (EditText)findViewById(R.id.editText4);
String text = field.getText().toString();
FileOutputStream fos = openFileOutput(Textfile2, Context.MODE_APPEND);
fos.write("".getBytes());
fos.close();
System.out.println("did it");
}catch (IOException e){
System.out.println("Error");
}
Intent back = new Intent(EditDataActivity.this, MainActivity.class);
startActivity(back);
mDatabaseHelper.deleteName(selectedID,selectedName);
editable_item.setText("");
toastMessage("Rezept erfolgreich gelöscht!");
}
});
}
private void toastMessage(String message){
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
public void loadsavedfile(){
try {
EditText test1 = (EditText) findViewById(R.id.editable_item);
String test1Text = test1.getText().toString();
String Textfile2 = test1Text + ".txt";
if (!Textfile2.isEmpty()) {
FileInputStream fis = openFileInput(Textfile2);
BufferedReader reader = new BufferedReader(new InputStreamReader(new DataInputStream(fis)));
String test;
EditText Test = (EditText) findViewById(R.id.editText4);
while ((test = reader.readLine()) != null) {
Test.setText(test);
}
}else{
}
}catch(IOException e){
}
Hope fully you can help me :)
Thanks!
Just do
while ((test = reader.readLine()) != null) {
Test.setText(Test.getText()+"\n" + test);
}
When you had setText(test) only it was replacing the text from the edit text every time the loop ran but you have to append the new text to the last line. A better way to do this would be to create the String first and then set it to EditText as it is better for performance.
StringBuilder str = new StringBuilder();
while((test = reader.readLine()) != null)
str.append('\n' + test);
Test.setText(str.toString());
Hope this solves your problem.

HttpURLConnection won't work after pausing on activity

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!

Spinners - get item selected from array

I have a spinner that gets populated from a text file stored on a web server. The contents of this text file are then stored in an ArrayList. My app is going to have the user add an item to this text file that they name themselves and therefore update the spinner. What I need to be able to do is have the spinner do something when an item is selected. As the user can give any name to an item they add, how can my app do something when that particular item is selected from the spinner if it doesn't know what they named it?
Right now I have my app set up so that if spinner item equals "string" do this... but this obviously won't work if the user has named an item themselves. I hope I have explained my question ok! This is my code so far:
public class MainActivity extends AppCompatActivity {
String statusLink = "http://redacted.uk/pmt/status.txt";
String deviceLink = "http://redacted.uk/pmt/devices.txt";
String status;
final String degree = "\u00b0";
ArrayList<String> devicesAL = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
// Set up connection to device.txt on web server
URL deviceUrl = new URL (deviceLink);
URLConnection deviceConn = deviceUrl.openConnection();
deviceConn.setDoOutput(true);
deviceConn.connect();
InputStream dis = deviceConn.getInputStream();
InputStreamReader disr = new InputStreamReader(dis, "UTF-8");
BufferedReader dbr = new BufferedReader(disr);
String deviceLine;
// Set up connection to status.txt on web server
URL statusUrl = new URL(statusLink);
URLConnection statusConn = statusUrl.openConnection();
statusConn.setDoOutput(true);
statusConn.connect();
InputStream sis = statusConn.getInputStream();
InputStreamReader sisr = new InputStreamReader(sis, "UTF-8");
BufferedReader sbr = new BufferedReader(sisr);
String statusLine;
try {
while ((deviceLine = dbr.readLine()) != null) {
//System.out.println(deviceLine);
devicesAL.add(deviceLine);
for (String str : devicesAL) {
System.out.println(str);
}
}
while ((statusLine = sbr.readLine()) != null) {
System.out.println(statusLine);
status = statusLine;
System.out.println("Status = " + status);
TextView output = (TextView) findViewById(R.id.textView);
System.out.println(status);
}
for (String str : devicesAL) {
System.out.println(str);
}
runOnUiThread(new Runnable() {
#Override
public void run() {
//LOAD SPINNER
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter adp = new ArrayAdapter(MainActivity.this, android.R.layout.simple_spinner_item, devicesAL);
adp.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adp);
adp.notifyDataSetChanged();
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
TextView output = (TextView) findViewById(R.id.textView);
if (parent.getItemAtPosition(position).equals("Water Cooler")) {
System.out.println("Water cooler selected");
output.setText(status);
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
});
} finally {
sbr.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
}
Since you say you want to :
If the user then selects "fridge" from the spinner, the data inside fridge.txt gets displayed
So i think you can just get the file name from the spinner then show the content. It will be like this :
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selectedFileName = parent.getItemAtPosition(position);
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, selectedFileName+".txt");
//Read text from file
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {}
TextView tvText = (TextView)findViewById(R.id.tvText);
tvText.setText(text.toString());
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});

fetching data from an URL asynchronously

Hi I am writting an android application to get information from a url and show it in a ListView. All are working well. but it takes long time to show the View because i read the file from url on onCreate() method.
I want read from the URL asynchronously, so view response time will not harmed.
Am I using the ProgressBar correctly?.
public class cseWatch extends Activity {
TextView txt1 ;
Button btnBack;
ListView listView1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.searchresult);
Button btnBack=(Button) findViewById(R.id.btn_bck);
btnBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent MyIntent1 = new Intent(v.getContext(),cseWatchMain.class);
startActivity(MyIntent1);
}
});
ArrayList<SearchResults> searchResults = GetSearchResults();
//after loaded result hide progress bar
ProgressBar pb = (ProgressBar) findViewById(R.id.progressBar1);
pb.setVisibility(View.INVISIBLE);
final ListView lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(new MyCustomBaseAdapter(cseWatch.this, searchResults));
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = lv.getItemAtPosition(position);
SearchResults fullObject = (SearchResults)o;
Toast.makeText(cseWatch.this, "You have chosen: " + " " + fullObject.getName(), Toast.LENGTH_LONG).show();
}
});
}//end of onCreate
private ArrayList<SearchResults> GetSearchResults(){
ArrayList<SearchResults> results = new ArrayList<SearchResults>();
SearchResults sr;
InputStream in;
try{
txt1 = (TextView) findViewById(R.id.txtDisplay);
txt1.setText("Sending request...");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.myurl?reportType=CSV");
HttpResponse response = httpclient.execute(httpget);
in = response.getEntity().getContent();
txt1.setText("parsing CSV...");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
try {
String line;
reader.readLine(); //IGNORE FIRST LINE
while ((line = reader.readLine()) != null) {
String[] RowData = line.split(",");
sr = new SearchResults();
String precent = String.format("%.2g%n",Double.parseDouble(RowData[12])).trim();
double chng=Double.parseDouble(RowData[11]);
String c;
if(chng > 0){
sr.setLine2Color(Color.GREEN);
c="▲";
}else if(chng < 0){
sr.setLine2Color(Color.rgb(255, 0, 14));
c="▼";
}else{
sr.setLine2Color(Color.rgb(2, 159, 223));
c="-";
}
sr.setName(c+RowData[2]+"-"+RowData[1]);
DecimalFormat fmt = new DecimalFormat("###,###,###,###.##");
String price = fmt.format(Double.parseDouble(RowData[6])).trim();
String tradevol = fmt.format(Double.parseDouble(RowData[8])).trim();
sr.setLine1("PRICE: Rs."+price+" TRADE VOL:"+tradevol);
sr.setLine2("CHANGE:"+c+RowData[11]+" ("+precent+"%)");
results.add(sr);
txt1.setText("Loaded...");
// do something with "data" and "value"
}
}
catch (IOException ex) {
Log.i("Error:IO",ex.getMessage());
}
finally {
try {
in.close();
}
catch (IOException e) {
Log.i("Error:Close",e.getMessage());
}
}
}catch(Exception e){
Log.i("Error:",e.getMessage());
new AlertDialog.Builder(cseWatch.this).setTitle("Watch out!").setMessage(e.getMessage()).setNeutralButton("Close", null).show();
}
return results;
}
}
AsyncTask should be used to move the heavylifting away from UI thread. http://developer.android.com/reference/android/os/AsyncTask.html
I think you should use a runable.
demo code:
final ListView lv = (ListView) findViewById(R.id.listView1);
Handler handler = new Handler(app.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
lv.setAdapter(new MyCustomBaseAdapter(cseWatch.this, searchResults));
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = lv.getItemAtPosition(position);
SearchResults fullObject = (SearchResults)o;
Toast.makeText(cseWatch.this, "You have chosen: " + " " + fullObject.getName(), Toast.LENGTH_LONG).show();
}
});
}
}, 1000);
try it.^-^

Categories