Im trying to get data from json. Actually it is working but i have a problem with listview.Im getting error.
Here is the code;
MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView txt;
Places places=new Places();
ListView listView;
List<Places> PlacesList=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt= (TextView) findViewById(R.id.text);
listView= (ListView) findViewById(R.id.listView);
listView.setBackgroundColor(Color.BLACK);
new getData().execute("https://api.foursquare.com/v2/venues/search?ll=41,29&oauth_token=01ZV1VDLE41USSRAYJUXOWNJ2MXYCAVN1I2PQFLFBCD40XYI&v=20160304");
}
public class getData extends AsyncTask<String,String,List <Places>> {
HttpURLConnection conn=null;
URL url=null;
BufferedReader bReader=null;
String name=null;
#Override
protected List<Places> doInBackground(String... params) {
try {
//BURADA URL'E BAGLANDIK
url=new URL(params[0]);
conn= (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
//VERİ OKUMAK İÇİN STREAM KULLANACAZ
InputStream istream=conn.getInputStream();
bReader= new BufferedReader(new InputStreamReader(istream));
//VERİ DEPOLAMAK İÇİN StringBuffer
StringBuffer sBuffer=new StringBuffer();
String line="";
while((line=bReader.readLine())!=null){
sBuffer.append(line);
}
String JSONFinal=sBuffer.toString();
JSONObject jsonObject=new JSONObject(JSONFinal);
JSONArray jsonArray=jsonObject.getJSONObject("response").getJSONArray("venues");
StringBuffer finalBuffer=new StringBuffer();
for(int i=0;i<jsonArray.length();i++) {
JSONObject finalJsonObject = jsonArray.getJSONObject(i);
name = finalJsonObject.getString("name");
places.setName(name);
PlacesList.add(places);
}
return PlacesList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
finally {
conn.disconnect();
}
return null;
}
#Override
protected void onPostExecute( List<Places> PlacesList) {
super.onPostExecute(PlacesList);
ArrayAdapter adapter= new ArrayAdapter<Places>(getApplicationContext(),android.R.layout.simple_list_item_1,PlacesList);
listView.setAdapter(adapter);
}
}
Places.java
public class Places {
int id,lat,lng;
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
So what is the problem?
It displays like that because you have passed Places object to your list view, and you haven't provided which fields to show in your list view from Places object , you should probably provide toString() method in your Places object to see your list with name or you should create your own adapter implementation
To see your listview with names
add this in your Places class
public void toString(){
return name;
}
Looks to me like you haven't overridden the toString() method of your Places class.
Add this to your Places class:
#Override
public String toString(){
return name;
}
See if that helps.
The Adapter is calling the toString() method of Places Object superclass, which is returning a hash of the Places object.
That's what's being printed.
Related
I am New to the android studio and want to something more. Actually, I am trying to pass the string that I got from the spinner in onCreateMethod and pass to the onPostExecute function. I will be grateful for the help. Bellow is my code.
I tried making a global variable called First and store the string from spinner and pass it on the onPostExecute function.
public class Convert extends AppCompatActivity implements LocationListener
{
Spinner dropdown;
Button btn;
String text;
String first;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_convert);
dropdown = (Spinner) findViewById(R.id.spinner1);
btn = (Button)findViewById(R.id.btn);
String[] items = new String[]{"United States,USD", "Nepal,NPR", "Bangladesh,BDT","Brazil,BRL"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, items);
dropdown.setAdapter(adapter);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
text = dropdown.getSelectedItem().toString();
first = text.substring(text.length()-3);
Log.i("her", first);
}
});
new DownloadTask().execute("http://openexchangerates.org/api/latest.json?
app_id=XXXXXXXXXX");
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urls[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char counter = (char) data;
result += counter;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try{
JSONObject jsonObject = new JSONObject(result);
JSONObject curr = jsonObject.getJSONObject("rates");
String npr = curr.getString(first);
Log.i("money", npr );
} catch (JSONException e) {
e.printStackTrace();
}
}
}
What I want is to pass the string first on the onPostExecute function.
When you will call your DownloadTask, asyncTask fires with method execute, just pass param though him. Example:
How to pass url
new DownloadTask().execute("url for download");
How to receive url
protected String doInBackground(String... urls) {
String url = urls[0]; // url for download
}
Also you could send and array of params. Also be careful with AsyncTask, do not pass your context/view variable, it could arise memory leaks, read docs.
I have declared a private field in the MainActivity Class with getter and setter method. Now I want to setText from another class in this field. But after running the device the app is crushing. I want to fetch some json data by using this code. I am not getting how to call this field from another class and how to set the value to run the app smoothly. My code looks like this.
public class MainActivity extends AppCompatActivity {
private TextView tvData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnHit=(Button)findViewById(R.id.btnHit);
tvData=(TextView)findViewById(R.id.tvJsonItem);
btnHit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
JSONTask jsonTask=new JSONTask("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt"); //error showing this cannot be applied
jsonTask.execute();
}
});
}
The another class is
public class JSONTask extends AsyncTask<String,String,String>{
private TextView tvData;
public JSONTask(TextView tvData) {
this.tvData =tvData;
}
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
tvData.setText(result);
}
}
Make your AsyncTask like this:
class JSONTask extends AsyncTask<String ,String,String>{
private TextView textView;
public JSONTask(TextView textView) {
this.textView = textView;
}
#Override
protected String doInBackground(String... params) {
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
textView.setText(s);
}
}
now call this class from MainActivity
JSONTask jsonTask = new JSONTask(yourTextView);
jsonTask.execute();
Hope it will work for you .
#override
protected void onPostExecute(String result){
super.onPostExecute(result);
new MainActivity().setTvData().setText(result);
Use setTvData().setText() to set the value if you only one data in your json string .
I am trying to pass 2 String[] from doinbackground to fragment where i have RecyclerView. I also tried setter getter method but still no luck
Here is my Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.activity_friend_list,container,false);
recyclerView= (RecyclerView) view.findViewById(R.id.RecyclerViewForFriendList);
//WANTS TO REPLACE THESE TWO ARRAY WITH WHICH I AM GETTING IN DOINBACKGROUND
Name=getResources().getStringArray(R.array.left_Drawer_Menu);
Image=getResources().obtainTypedArray(R.array.user_image);
recyclerView.setHasFixedSize(true);
adapter=new RecyclerFriendListAdapter(getActivity(),Distance,Image,LastSeen,Name);
recyclerView.setAdapter(adapter);
layoutManager=new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
return view;
}
Here is my AsyncTask Class
protected String[] doInBackground(String... params) {
try {
URL url=new URL(URL_Path);
connection= (HttpURLConnection) url.openConnection();
connection.connect();
InputStream inputStream=connection.getInputStream();
reader=new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuffer stringBuffer=new StringBuffer();
while ((line=reader.readLine())!=null){
stringBuffer.append(line);
}
String completeJSON=stringBuffer.toString();
JSONArray parentArray=new JSONArray(completeJSON);
String[] Name=new String[parentArray.length()];
String[] ImagePath=new String[parentArray.length()];
for (int i = 0; i <parentArray.length() ; i++) {
JSONObject childObject=parentArray.getJSONObject(i);
String Fname=childObject.getString("First_Name") ;
String Lname=childObject.getString("Last_Name") ;
Name[i]=Fname+" "+Lname;
ImagePath[i]=childObject.getString("Image");
Log.d(TAG,"String Arrays "+Name[i]+" "+ ImagePath[i]);
//GETTING ALL VALUES IN LOG SUCCESSFULLY
}
return Name;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
try {
connection.disconnect();
if (reader!=null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String[] strings) {
super.onPostExecute(strings);
}
I am calling AsyncTask Execute Method in Toolbar of Parent Activity Of Fragment
UPDATE:
1) As #BryanDunlap Asked for onPostExecute (its just implemented,No code inside it) And How to return both arrays to get in Fragment
2) #IrisLouis suggested to implement interface that's how i did with setter and getter but i wasn't work
ublic class WrapperClass {
private String[] Name;
private String[] ImagePath;
public String[] getImagePath() {
return ImagePath;
}
public void setImagePath(String[] imagePath) {
ImagePath = imagePath;
}
public String[] getName() {
return Name;
}
public void setName(String[] name) {
Name = name;
}
How i set this in AsyncTask
Name[i]=Fname+" "+Lname;
ImagePath[i]=childObject.getString("Image");
Log.d(TAG,"String Arrays "+Name[i]+" "+ ImagePath[i]);
//LOG RETURNS VALUE OF BOTH ARRAYS
WrapperClass w=new WrapperClass();
w.setImagePath(ImagePath);
w.setImagePath(Name);
Getting in Fragment in onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
....
....
....
WrapperClass wrapperClass=new WrapperClass();
String[] Name=wrapperClass.getName();
String[] ImagePath=wrapperClass.getImagePath();
Log.d(TAG,Name.toString()+" "+ ImagePath.toString())
//IT RETURNS NULLS
Solution for you, can test it.
In class Asynctask make a interface callback results :
public class PageLoader extends AsyncTask<String, Void, String[] results> {
private Context context;
private LoaderListener mLoaderListener;
public PageLoader(Context context, LoaderListener mLoaderListener) {
this.context = context;
this.mLoaderListener = mLoaderListener;
}
public interface LoaderListener {
void onLoadCompleted(String[] results);
void onLoadFailed();
void onPreparing();
}
#Override
protected void onPreExecute() {
mLoaderListener.onPreparing();
}
#Override
protected String[] doInBackground(String... params) {
try {
URL url=new URL(URL_Path);
connection= (HttpURLConnection) url.openConnection();
connection.connect();
InputStream inputStream=connection.getInputStream();
reader=new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuffer stringBuffer=new StringBuffer();
while ((line=reader.readLine())!=null){
stringBuffer.append(line);
}
String completeJSON=stringBuffer.toString();
JSONArray parentArray=new JSONArray(completeJSON);
String[] Name=new String[parentArray.length()];
String[] ImagePath=new String[parentArray.length()];
for (int i = 0; i <parentArray.length() ; i++) {
JSONObject childObject=parentArray.getJSONObject(i);
String Fname=childObject.getString("First_Name") ;
String Lname=childObject.getString("Last_Name") ;
Name[i]=Fname+" "+Lname;
ImagePath[i]=childObject.getString("Image");
Log.d(TAG,"String Arrays "+Name[i]+" "+ ImagePath[i]);
//GETTING ALL VALUES IN LOG SUCCESSFULLY
}
return Name;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
try {
connection.disconnect();
if (reader!=null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String[] results) {
if (results!= null) {
mLoaderListener.onLoadCompleted(results);
} else {
mLoaderListener.onLoadFailed();
}
}
}
In Activity you execute Asynctask.
In Fragment you must implements LoaderListener and Override three function.
Ex : YourFragment extends Fragment implements LoaderListener
You can handle results callback in onLoadCompleted
Ex :
#Override
public void onLoadCompleted(String[] results){
//Do something with results
}
I need to build an android app for my final year project, (i am new to android development). Is there any idea to minimize the code or maybe separate into different classes.
I want to make my main activity shorter and cleaner for maintenance, and preferably if it can be coded using MVC architecture. There will be more UI components added later.
Thank you for ur attention.
public class MainActivity extends AppCompatActivity {
Button find_button;
EditText user_origin;
EditText user_destination;
private TextView json_output;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
find_button = (Button)findViewById(R.id.find_button);
json_output = (TextView)findViewById(R.id.json_output);
user_origin = (EditText)findViewById(R.id.user_origin);
user_destination = (EditText)findViewById(R.id.user_destination);
find_button.setOnClickListener(new View.OnClickListener(){
String origin;
String new_origin;
String destination;
String new_user_destination;
#Override
public void onClick(View v){
origin = user_origin.getText().toString();
new_origin = origin.replaceAll(" ", "+");
destination = user_destination.getText().toString();
new_user_destination = destination.replaceAll(" ", "+");
String link = "https://maps.googleapis.com/maps/api/directions/json?origin=" + new_origin + "&destination=" + new_user_destination + "&mode=transit&key=AIzaSyD83XCiGtJyo6Ln8c7yyyrQwmFDFZB_oiU";
//json_output.setText(link);
new JSONTask().execute(link);
}
});
}
public class JSONTask extends AsyncTask<String,String,String> {
#Override
protected String doInBackground(String... params){
HttpURLConnection connection = null;
BufferedReader reader = null;
try{
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while((line = reader.readLine()) != null ){
buffer.append(line);
}
String final_json = buffer.toString();
return buffer.toString();
} catch (MalformedURLException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
} finally {
if(connection != null) {
connection.disconnect();
}
try {
if(reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
json_output.setText("result:" +result);
}
}
}
You can separate your JSONTask as a simple class,and execute its task,then define an interface in this class to pass some message or data should be handled by other class,and add a parameter type is this interface for constructor and save it as a field.like this:
public class JSONTask extends AsyncTask<String,String,String>{
private OnHandleResult mResult;
private String[] mParams;
public JSONTask(OnHandleResult onHandleResult,String... params){
this.mResult = onHandleResult;
this.mParams = params;
}
protected String doInBackground(String... params){
//params is empty,get params from this.mParams
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
//json_output.setText("result:" +result);
this.mResult.handleResult(result);
}
public static interface OnHandleResult{
void handleResult(final String result);
}
}
then let your activity implement interface onHandleResult,and hanlde result:set text to textview:
public class MainActivity extends AppCompatActivity implements JSONTask.OnHandleResult{
void handleResult(final String result){
json_output.setText("result:" +result);
}
}
and execute task like this:
new JSONTask(this,link).execute();
Usually it's good practise to have 1 class per file.
You can make your MainActivity a bit more readable
public class MainActivity extends AppCompatActivity {
Button find_button;
EditText user_origin;
EditText user_destination;
private TextView json_output;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
find_button = (Button) findViewById(R.id.find_button);
json_output = (TextView) findViewById(R.id.json_output);
user_origin = (EditText) findViewById(R.id.user_origin);
user_destination = (EditText) findViewById(R.id.user_destination);
String link = build_link(user_origin, user_destination);
MyListener l = new MyListener(link);
find_button.setOnClickListener(l);
}
private String build_link(EditText user_origin, EditText user_destination) {
String origin = user_origin.getText().toString();
String new_origin = origin.replaceAll(" ", "+");
String destination = user_destination.getText().toString();
String new_user_destination = destination.replaceAll(" ", "+");
return "https://maps.googleapis.com/maps/api/directions/json?origin=" + new_origin + "&destination=" + new_user_destination + "&mode=transit&key=AIzaSyD83XCiGtJyo6Ln8c7yyyrQwmFDFZB_oiU";
}
by isolating your listener's implementation:
public class MyListener implements View.OnClickListener {
String link;
public MyListener(String link) {
this.link = link;
}
#Override
public void onClick(View v) {
new JSONTask().execute(link);
}
I have an AutoCompleteTextView that fetch's names from a database, my problem seems to be with the Array-Adapter or dropdown that binds 50% of the time. For instance if someone types in John then then you might get Suggestion for Jo but not with hn . The dropdown displays randomly even when I can see that data has come through this is my activity
public class tester extends Activity
{
EditText POST;
AutoCompleteTextView autobox;
String[] Arrays;
ArrayAdapter<String> adapters;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.mypage);
// set up Array with some initial values
autobox= (AutoCompleteTextView) findViewById(R.id.autobox);
String[] Arrays={"John Smith","Sam Austin"};
// create the adapter inside the Oncreate method
adapters = new ArrayAdapter<>(tester.this,
android.R.layout.simple_dropdown_item_1line,Arrays);
autobox.setAdapter(adapters);
autobox.setThreshold(1);
autobox.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) {
if(start>=1)
autobox.getText().toString();
new AutoText().execute();
}
#Override
public void afterTextChanged(Editable s) {}
});
}
public class AutoText extends AsyncTask<String,String,String> {
public String LOGIN_URL = "http://10.0.2.2:9999/api/namedata";
HttpURLConnection connection;
URL url;
StringBuilder sb= new StringBuilder();
String line="",nameList="";
String names="";
DataOutputStream DO;
#Override
protected void onPreExecute() {
super.onPreExecute();
names= autobox.getText().toString();
}
#Override
protected String doInBackground(String[] jsonData) {
String query= "names="+ names;
try {
url = new URL(LOGIN_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.connect();
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
DO = new DataOutputStream(connection.getOutputStream());
DO.writeBytes(query);
DO.flush();
DO.close();
InputStream in = new BufferedInputStream(connection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
while ((line = reader.readLine()) != null) {
sb.append(line);
}
nameList= sb.toString();
}
catch (Exception e) {
e.printStackTrace();
System.err.println("Why I am getting errors:");
}
return nameList;
}
protected void onPostExecute(String results) {
try
{
JSONObject jsonn = new JSONObject(nameList);
JSONArray jArray = jsonn.getJSONArray("name_updates");
JSONObject jobject = null;
String fullnames="";
JSONArray JA = new JSONArray();
for (int i = 0; i < jArray.length(); i++) {
fullnames+= jobject.getString("fullnames")+"-";
JA.put(jobject);
}
Arrays= fullnames.split("-");
// check the output values
System.out.println("ee " + java.util.Arrays.toString(Arrays));
adapters.clear();
adapters.addAll(Arrays);
adapters.notifyDataSetChanged();
}
catch(Exception e)
{
}
}
}
}
If you notice I use the System.out.println("ee " + java.util.Arrays.toString(Arrays)); onPostexecute and can see that all the data is coming in correctly,however the dropdown issue does not show at times that is the main issue. When the dropdown menu does show up everything is updated as it should be. I have tried to put autobox.showDropDown(); after the notifyDataSetChanged() but it still disappears at random times when there is new data. I have tried Android - AutoCompleteTextView, showDropDown() doesn't always work but it did not work for me and it seems like a bad idea to make an adapter null and keep recreating it.