Hi this is my first app.
I am a beginner when it comes to programming and to android.
My app is similar to the twitter app. But instead of getting values from twitter it would get values from my database. The app will be loaded with images and links to web pages.
My question.
Lets say my app is on the app store and someone downloads it.
My app get most of its content from my mysql db via Json. Every time i add new content to the db, must the user update the app to get the new content or will it automatically update its self.
Can someone just take a look at my code. I am not sure about the Async() and the doInBackground(). If you have any other helpful coding suggestions please let me know. I would like to put this app on the app store when it is complete.
Kind regards
public class TwitterFeedActivity extends ListActivity {
private ArrayList<Tweet> tweets = new ArrayList<Tweet>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new MyTask().execute();
}
private class MyTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
protected void onPreExecute() {
progressDialog = ProgressDialog.show(TwitterFeedActivity.this,
"", "Loading. Please wait...", true);
}
#Override
protected Void doInBackground(Void... arg0) {
try {
HttpClient hc = new DefaultHttpClient();
HttpGet get = new HttpGet("http://myurl.com");
HttpResponse rp = hc.execute(get);
if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
String result = EntityUtils.toString(rp.getEntity());
JSONObject root = new JSONObject(result);
JSONArray sessions = root.getJSONArray("results");
for (int i = 0; i < sessions.length(); i++) {
JSONObject session = sessions.getJSONObject(i);
Tweet tweet = new Tweet();
tweet.n_text = session.getString("n_text");
tweet.n_name = session.getString("n_name");
tweet.Image = session.getString("Image");
tweets.add(tweet);
}
}
} catch (Exception e) {
Log.e("TwitterFeedActivity", "Error loading JSON", e);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
setListAdapter(new TweetListAdaptor(TwitterFeedActivity.this, R.layout.list_item, tweets));
}
}
private class TweetListAdaptor extends ArrayAdapter<Tweet> {
private ArrayList<Tweet> tweets;
public TweetListAdaptor(Context context, int textViewResourceId, ArrayList<Tweet> items) {
super(context, textViewResourceId, items);
this.tweets = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item, null);
}
final Tweet o = tweets.get(position);
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);
ImageView image = (ImageView) v.findViewById(R.id.avatar);
bt.setText(o.n_name);
tt.setText(o.n_text);
image.setImageBitmap(getBitmap(o.Image));
image.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse(o.n_text));
startActivity(intent);
}
});
return v;
}
}
public Bitmap getBitmap(String bitmapUrl) {
try {
URL url = new URL(bitmapUrl);
return BitmapFactory.decodeStream(url.openConnection().getInputStream());
}
catch(Exception ex) {return null;}
}
}
Ok I am posting the Async related code. I hope, you will find it helping. First of all, make a class as follows:
package com.example.pre;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import android.util.Log;
public class JSONFunctions {
public String CreateCon(String url){
String res="";
try{
URL u=new URL(url);
HttpURLConnection con = (HttpURLConnection) u.
openConnection();
res=readStream(con.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return res;
}
private String readStream(InputStream is) {
// TODO Auto-generated method stub
String result = "";
BufferedReader reader=null;
try{
reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
result=result+line;
}
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}finally{
if(reader!=null)
{
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return result;
}
}
Second in your main class, paste the following method:
private class PostTask extends AsyncTask<String, Integer, String>{
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
readJson();
//progress_dialog.dismiss();
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
JSONFunctions jsonf=new JSONFunctions();
str1=jsonf.CreateCon(cat_url);
return null;
}
}
where readJson is the method where you define your functionality and str1 is the string where you provide the address of the json. Don't forget call to the PostExecute class.
Related
Hello i'm new to android studio and i have code which is showing recycler view list from json data. Now i want to open items in new activity.I want to open item from recyclerview and show image and some text in new activity. I need solution code.
I have tried some ways but it doesn't work.
This is my code:
public class MainActivity extends AppCompatActivity {
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView mRVFishPrice;
private AdapterFish mAdapter;
SwipeRefreshLayout mSwipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swifeRefresh);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new AsyncFetch().execute();
}
});
new AsyncFetch().execute();
}
private class AsyncFetch extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String... params) {
try {
url = new URL("https://MYURL.com");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
mSwipeRefreshLayout.setRefreshing(false);
pdLoading.dismiss();
List<DataFish> data=new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
DataFish fishData = new DataFish();
fishData.fishImage= json_data.getString("fish_img");
fishData.fishName= json_data.getString("fish_name");
fishData.catName= json_data.getString("cat_name");
fishData.sizeName= json_data.getString("size_name");
fishData.price= json_data.getInt("price");
data.add(fishData);
}
mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
mAdapter = new AdapterFish(MainActivity.this, data);
mRVFishPrice.setAdapter(mAdapter);
mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this));
} catch (JSONException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
I expect to open item from recyclerview list in new activity and show image item and some text.
You can archive this by passing an instance of the interface in your adapter class and implement that interface in your activity.
refer this to get insights link
Sample Snippets
Declare interface:
public interface AdapterCallback {
void onFishClick(DataFish item);
}
Pass interface instance via setup your adapter in activity.
new AdapterFish(MainActivity.this, data, new AdapterCallback() {
#Override
void onfishClick(DataFish item) {
// herer do your work
}
});
In your adapter constructor
private AdapterCallback callback;
AdapterFish(Context contex, data, AdapterCallback callback) {
...
this.callback = callback;
}
define click listener in a holder and inside a method call callback.onFishCall(selectedItem);
OnBindViewHolder(...) {
holder.button.onClicklistener(new OnClickListener{
...
if(callback != null) { // for null check
callback.onFishClikc(item);
}
});
}
I tried to get help on this post without any luck, I played around with code but still no luck. My list for example is as follows: Blue, Red, Purple from Json remote server.
When I type B.. it returns Blue. OK
When I type X.. it returns no results because no color matched "X". OK
When I type R.. (or RE.. or RED) it returns Blue instead of returning Red.
Conclusion - The code always returns the first item on the list when filtered.
My code:
JSON:
private class JsonReadTask extends AsyncTask<String, Void, String> {
//Pending 01
private ProgressDialog dialog = new ProgressDialog(getActivity());
#Override
protected void onPreExecute() {
this.dialog.setMessage("Loading Rooms, Please Wait");
this.dialog.show();
}
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
}
catch (IOException e) {
// e.printStackTrace();
Toast.makeText(getActivity(),"Error..." + e.toString(), Toast.LENGTH_LONG).show();
}
return answer;
}
#Override
protected void onPostExecute(String result) {
//Pending 02
if (dialog.isShowing()) {
dialog.dismiss();
}
adapter.notifyDataSetChanged();
try{
ListDrwaer(); //has ConnectionException (when it cannot reach server)
}catch (Exception e){
Toast.makeText(getActivity(), "Please check your connection..", Toast.LENGTH_LONG).show();
}
}
}// end async task
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
// passes values for the urls string array
task.execute(new String[] { "http://www.website.com/file.php?psortby="+sortby});
}
// build hash set for list view
public void ListDrwaer() {
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("room_info");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String request_title = jsonChildNode.optString("Title");
String request_members = jsonChildNode.optString("Members");
request_title_replaced = request_title.replace("room_", "");
arrRequest_Title.add(request_title_replaced);
arrRequest_Members.add(request_members);
}
} catch (JSONException e) {
System.out.println("Json Error Rooms" +e.toString());
//Toast.makeText(getApplicationContext(), "No Rooms To Load", Toast.LENGTH_SHORT).show();
}
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
adapter.getFilter().filter(cs);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
}
Adapter:
class RoomsAdapter extends ArrayAdapter<String>
{
#Override
public void clear() {
super.clear();
arrRequest_Title.clear();
arrRequest_Members.clear();
}
Context context;
List<String> Request_Title;
List<String> Request_Members;
RoomsAdapter(Context c, List<String> Request_Title, List<String> Request_Members)
{
super(c, R.layout.activity_rooms_single, R.id.textTitle, Request_Title);
this.context=c;
this.Request_Title=Request_Title;
this.Request_Members=Request_Members;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row=convertView;
if(row==null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.activity_rooms_single, parent, false);
}
TextView txtTitle = (TextView) row.findViewById(R.id.textTitle);
TextView txtMembers = (TextView) row.findViewById(R.id.textMembers);
txtTitle.setText(Request_Title.get(position));
txtMembers.setText(Request_Members.get(position));
return row;
}
}
Fragment Class:
public class Fragment_01_Rooms extends Fragment
I'm working on a big program for Android and I'm trying to get the currency converter part of the program to work. For full disclosure: I found it from http://firstamong.com/building-android-currency-converter/, and it's a tutorial on how to build a real-time currency converter. I'll post the code in question followed by the logcat. The error that occurs is when I try to convert from one currency to another, the application says it was forced to stop. However, the "Invalid" portion works (the case where both currency fields are the same.) Any help would truly be appreciated:
Code:
public class currency_converter extends Activity {
public int to;
public int from;
public String [] val;
public String s;
public Handler handler;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_currency_converter);
Spinner s1 = (Spinner) findViewById(R.id.spinner1);
Spinner s2 = (Spinner) findViewById(R.id.spinner2);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.name, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
val = getResources().getStringArray(R.array.value);
s1.setAdapter(adapter);
s2.setAdapter(adapter);
s1.setOnItemSelectedListener(new spinOne(1));
s2.setOnItemSelectedListener(new spinOne(2));
Button b = (Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
TextView t = (TextView) findViewById(R.id.textView4);
if(from == to)
{
Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
}
else
{
try {
s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
JSONObject jObj;
jObj = new JSONObject(s);
String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
t.setText(exResult);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
public String getJson(String url)throws ClientProtocolException, IOException {
StringBuilder build = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String con;
while ((con = reader.readLine()) != null) {
build.append(con);
}
return build.toString();
}
private class spinOne implements OnItemSelectedListener
{
int ide;
spinOne(int i)
{
ide =i;
}
public void onItemSelected(AdapterView<?> parent, View view,
int index, long id) {
if(ide == 1)
from = index;
else if(ide == 2)
to = index;
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
class GetResponseData extends AsyncTask<String, String, String> {
private ProgressDialog dialog;
private ArrayList<String> titleList;
private TextView textView;
public GetResponseData(TextView textView) {
this.textView = textView;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = ProgressDialog.show(currency_converter.this, "", "Loading",
false);
}
#Override
protected String doInBackground(String... params) {
try {
String s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22" + val[from] + val[to] + "%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
JSONObject jObj;
jObj = new JSONObject(s);
String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
return exResult;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (dialog != null)
dialog.dismiss();
if (result != null) {
textView.setText(result);
}
}
}
}
}
Logcat:
10-30 00:59:48.164 20591-20591/com.example.travelapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:587)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:511)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:489)
at com.example.travelapplication.currency_converter.getJson(currency_converter.java:93)
at com.example.travelapplication.currency_converter$1.onClick(currency_converter.java:68)
at android.view.View.performClick(View.java:4222)
at android.view.View$PerformClick.run(View.java:17620)
at android.os.Handler.handleCallback(Handler.java:800)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5391)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Try this,,
Your performing a networking operation on its main thread. That why your getting NetworkOnMainThreadException
b.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
TextView t = (TextView) findViewById(R.id.textView4);
if(from == to)
{
Toast.makeText(getApplicationContext(), "Invalid", 4000).show();
}
else
{
GetResponseData abcd = GetResponseData(t);
abcd.execute();
}
}
});
You are getting:
NetworkOnMainThreadException
Issue is that you are calling your function getJson() in your Activity.
Use AsyncTask:
public class ProcessTask extends AsyncTask<Void, Integer, String>{
public ProcessTask() {
// TODO Auto-generated constructor stub
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
//your code of parsing
StringBuilder build = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url); //your yahooapi url goes here
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String con;
while ((con = reader.readLine()) != null) {
build.append(con);
}
return build.toString();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
It looks like you have strict mode on in your android manifest. Strict mode will complain when you are doing network calls on you main thread. You can just disable strict mode or a better approach is to put your network call into an async task. The network call in question is
HttpResponse response = client.execute(httpGet);
inside public String getJson(String url)
The async task you need is already there you just need to use it
Change this else statement
else
{
try {
s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
JSONObject jObj;
jObj = new JSONObject(s);
String exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
t.setText(exResult);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
To this
else {
new GetResponseData().execute("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
}
It will help use this :
public class CurrencyConverter extends Fragment {
public CurrencyConverter() {
}
TextView t;
public int to;
public int from;
public String[] val;
public String s;
String exResult;
public Handler handler;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.currency_converter, container, false);
t= (TextView) rootView.findViewById(R.id.textView4);
Spinner s1 = (Spinner) rootView.findViewById(R.id.spinner1);
Spinner s2 = (Spinner) rootView.findViewById(R.id.spinner2);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this.getActivity(), R.array.name, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);
val = getResources().getStringArray(R.array.value);
s1.setAdapter(adapter);
s2.setAdapter(adapter);
s1.setOnItemSelectedListener(new spinOne(1));
s2.setOnItemSelectedListener(new spinOne(2));
Button b = (Button) rootView.findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View View) {
if (from == to) {
Toast.makeText(getActivity().getApplicationContext(), "Invalid", 4000).show();
} else {
new calculate().execute();
}
}
});
return rootView;
}
public class calculate extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... args) {
try {
s = getJson("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22"+val[from]+val[to]+"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=");
JSONObject jObj;
jObj = new JSONObject(s);
exResult = jObj.getJSONObject("query").getJSONObject("results").getJSONObject("rate").getString("Rate");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return exResult;
}
#Override
protected void onPostExecute(String exResult) {
t.setText(exResult);
}
}
public String getJson(String url)throws IOException {
StringBuilder build = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String con;
while ((con = reader.readLine()) != null) {
build.append(con);
}
return build.toString();
}
public class spinOne implements AdapterView.OnItemSelectedListener
{
int ide;
spinOne(int i)
{
ide =i;
}
public void onItemSelected(AdapterView<?> parent, View view,
int index, long id) {
if(ide == 1)
from = index;
else if(ide == 2)
to = index;
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
}
I tried the code below and also tried the AsyncTaskLoader approach. The app crashes when I instantiate the AsyncTask. Pleas advise me on the best approach to load JSON in a list fragment inside tab host.
The code below is the tab fragment (I use action bar tabs in main activity):
public class TabTop extends ListFragment {
Context context = getActivity().getBaseContext();
String API_URL = "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json?apikey=crhhxb4accwwa6cy6fxrm8vj&limit=1";
ArrayList<Deal> deals;
DealsListAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
#SuppressWarnings("unused")
int a = 0;
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
GetTopDeals getTopDeals = new GetTopDeals(context);
getTopDeals.execute(API_URL);
super.onActivityCreated(savedInstanceState);
}
class GetTopDeals extends AsyncTask<String, Void, ArrayList<Deal>>{
ProgressDialog progressDialog;
public GetTopDeals(Context activity) {
this.progressDialog = new ProgressDialog(activity);
}
#Override
protected void onPostExecute(ArrayList<Deal> result) {
adapter = new DealsListAdapter(context, result);
setListAdapter(adapter);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
progressDialog.setCancelable(true);
progressDialog.setProgress(0);
progressDialog.setMessage("loading Top deals...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
super.onPreExecute();
}
#Override
protected ArrayList<Deal> doInBackground(String... urls) {
String response = sendRequest(urls[0]); // make request for json
return processResponse(response); // parse the Json and return ArrayList to postExecute
}
private String sendRequest(String apiUrl) {
BufferedReader input = null; // get the json
HttpURLConnection httpCon = null; // the http connection object
StringBuilder response = new StringBuilder(); // hold all the data from the jason in string separated with "\n"
try {
URL url = new URL(apiUrl);
httpCon = (HttpURLConnection) url.openConnection();
if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) { // check for connectivity with server
return null;
}
input = new BufferedReader(new InputStreamReader(httpCon.getInputStream())); // pull all the json from the site
String line;
while ((line = input.readLine()) != null) {
response.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpCon != null) {
httpCon.disconnect();
}
}
return response.toString();
}
}
public ArrayList<Deal> processResponse(String response) {
try {
JSONObject responseObject = new JSONObject(response); // Creates a new JSONObject with name/value mappings from the JSON string.
JSONArray results = responseObject.getJSONArray("movies"); // Returns the value mapped by name if it exists and is a JSONArray.
deals = new ArrayList<Deal>();
for (int i = 0; i < results.length(); i++) { // in this loop i copy the json array to movies arraylist in order to display listView
JSONObject jMovie = results.getJSONObject(i);
int api_id = jMovie.getInt("id");
String name = jMovie.getString("title");
String content = jMovie.getString("synopsis");
JSONObject posters = jMovie.getJSONObject("posters");
String image_url = posters.getString("profile");
}
}catch (JSONException e) {
e.printStackTrace();
}
return deals;
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(getActivity().getBaseContext(), DealInformation.class);
startActivity(intent);
super.onListItemClick(l, v, position, id);
}
}
Make your asynctask in his own file.
And when your asynctask is finish, implement OnPostExecute which is automatically call. Notify your adapter by a notifyDataSetChanged like that :
#Override
protected void onPostExecute(List<NewItem> list) {
Adapter.getListe().clear();
Adapter.getListe().addAll(list);
Adapter.notifyDataSetChanged();
}
thank you guys,
i want to post my answer. after some research i decided to go with AsyncTaskLoader.
this is my code
public class TabOurPicks extends ListFragment implements LoaderCallbacks<String[]> {
// when activity loads- onActivityCreated() calls the initLoader() who activate onCreateLoader()
#Override
public void onActivityCreated(Bundle savedInstance) {
super.onActivityCreated(savedInstance);
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, new String[]{}));
getLoaderManager().initLoader(0, null,this).forceLoad();
}
// onCreateLoader instantiate the asynctaskloaser who work in bg
#Override
public RSSLoader onCreateLoader(int arg0, Bundle arg1) {
return new RSSLoader(getActivity()); //
}
// after bg process invoke onLoadFinished() who work in ui thread
#Override
public void onLoadFinished(Loader<String[]> loader, String[] data) {
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, data
) );
}
#Override
public void onLoaderReset(Loader<String[]> arg0) {
// TODO Auto-generated method stub
}
and this is the inner class for the loader:
static public class RSSLoader extends AsyncTaskLoader<String[]>
{
public RSSLoader(Context context) {
super(context);
}
#Override
public String[] loadInBackground() {
String url = "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json?apikey=crhhxb4accwwa6cy6fxrm8vj&limit=1";
String response = sendRequest(url);
return processResponse(response);
}
private String sendRequest(String url) {
BufferedReader input = null; // get the json
HttpURLConnection httpCon = null; // the http connection object
StringBuilder response = new StringBuilder(); // hold all the data from the jason in string separated with "\n"
try {
URL apiUrl = new URL(url);
httpCon = (HttpURLConnection) apiUrl.openConnection();
if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) { // check for connectivity with server
return null;
}
input = new BufferedReader(new InputStreamReader(httpCon.getInputStream())); // pull all the json from the site
String line;
while ((line = input.readLine()) != null) {
response.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpCon != null) {
httpCon.disconnect();
}
}
return response.toString();
}
private String[] processResponse(String response) {
String[] deals = null;
try {
JSONObject responseObject = new JSONObject(response); // Creates a new JSONObject with name/value mappings from the JSON string.
JSONArray results = responseObject.getJSONArray("movies"); // Returns the value mapped by name if it exists and is a JSONArray.
deals = new String[10];
for (int i = 0; i < 9; i++) { // in this loop i copy the json array to movies arraylist in order to display listView
JSONObject jMovie = results.getJSONObject(i);
String name = jMovie.getString("title");
deals[i] = name;
}
}catch (JSONException e) {
e.printStackTrace();
}
return deals;
}
}
}
It doesn't matter if your asynctask has its own file. You just don't want your activity to extends asynctask as this would make your activity asynchronous - but this is impossible to do anyways due to java's double inheritance rule.
Based on the architecture of your app and your programming style the asyntask can be an inner class in the activity. on the PostExecute method make sure you have given data to your adapter and that the adapter is set to the list, then just run notifyDataSetChanged().
Assuming your asynctask is loading data from cache or the network you are on the right track with your approach to this.
I have a class extending listFragment. I have written code for fetching json response in a method which is called in oncreate of the class. For fetching json in background I have created new inner class which extends asyncTask. I can get the jsonarrays and strings in the json response in the logcat. But when I try to save them in a string array and pass them my custom baseadapter, I get a nullpointer exception.
public class OnlineInfo extends ListFragment {
public static String result;
public String[] Technologies1;
public String[] TechnologyDescription1;
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
}
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
downloadjsonresponse();
}
public class Download extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
StringBuilder stringbuilder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet url = new HttpGet(params[0]);
try
{
Log.d("in background", "in background");
HttpResponse response = client.execute(url);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line ;
while((line = reader.readLine()) != null)
{
stringbuilder.append(line);
}
}
catch(ClientProtocolException e)
{
Log.d("error in clientprotocol", "error");
e.printStackTrace();
}
catch(IOException e)
{
Log.d("error in IO", "error");
e.printStackTrace();
}
return stringbuilder.toString();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
OnlineInfo.result = result;
try {
JSONObject jsonobject = new JSONObject(result);
JSONArray raja = jsonobject.getJSONArray("Technologies");
//String raja = jsonobject.getJSONArray("Technologies").getJSONObject(0).getString("desc");
//Log.d("desc:", raja);
for(int i=0; i<raja.length();i++)
{
Technologies1[i] = raja.getJSONObject(i).getString("name");
TechnologyDescription1[i] = raja.getJSONObject(i).getString("desc");
Log.d("technology :", raja.getJSONObject(i).getString("name"));
Log.d("technologydescription :", raja.getJSONObject(i).getString("desc"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("desc:", "error");
}
getListView().setAdapter(new AdapterForOnlineInfo(getActivity(), OnlineInfo.this.Technologies1, OnlineInfo.this.TechnologyDescription1));
}
}
public void downloadjsonresponse()
{
Download jsonresponse = new Download();
jsonresponse.execute("http://www.avantajsoftwares.com/result.json");
}
}
I could get the results in logcat whenever I comment these two lines in for-loop:
Technologies1[i] = raja.getJSONObject(i).getString("name");
TechnologyDescription1[i] = raja.getJSONObject(i).getString("desc");
Don't know what's going wrong. Please somebody provide me some insight....:-(
I think you need to allocate space in your string arrays to hold the new strings.
Just before your for loop, try putting something like this:
Technologies1 = new String[raja.length()];
TechnologyDescription1 = new String[raja.length()];