Android - Error when storing parsed xml data to sql - java

I am getting a java.lang.NullPointerException error when storing xml data parsed from a URL on my localhost (http://10.0.0.22/cardealers.xml) to sql. Here is the xml am parsing:
<Providers>
<CarDealer name="BEFORWARD" id="1">
<CarMake name="Toyota" id="20">
<CarModel name="Belta" id="21"/>
<CarModel name="RunX" id="22"/>
<CarModel name="Corolla" id="23"/>
</CarMake>
<CarMake name="Nissan" id="30">
<CarModel name="Murano" id="31"/>
<CarModel name="Pathfinder" id="32"/>
<CarModel name="Navara" id="33"/>
</CarMake>
</CarDealer>
</Providers>
In my xml handler class, I passed my xml like so:
public class SAXXMLHandler extends DefaultHandler {
private List<CarMake> carMaker;
private String tempVal;
// to maintain context
private CarMake carmake;
public SAXXMLHandler() {
carMaker = new ArrayList<CarMake>();
}
public List<CarMake> getCarMake() {
return carMaker;
}
// Event Handlers
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equalsIgnoreCase("CarMake")) {
// create a new instance of CarMake
carmake = new CarMake();
carmake.setName(attributes.getValue("name"));
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equalsIgnoreCase("CarMake")) {
// add it to the list
carMaker.add(carmake);
} else if (qName.equalsIgnoreCase("CarModel")) {
carmake.setCarModel(tempVal);
}
}
}
Then using AsyncTask in Sell.java
public class Sell extends Activity implements
View.OnClickListener, AdapterView.OnItemClickListener {
static final String URL = "http://10.0.0.22/cardealers.xml";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sell);
//new GetXMLTask().execute();
new GetXMLTask(this).execute();
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
}
#Override
public void onClick(View view) {
GetXMLTask task = new GetXMLTask(this);
task.execute(new String[]{URL});
}
//private inner class extending AsyncTask
private class GetXMLTask extends AsyncTask<String, Void, List<Service>> {
private Activity context;
public GetXMLTask(Activity context) {
this.context = context;
}
/* uses HttpURLConnection to make Http request from Android to download
the XML file */
private String getXmlFromUrl(String urlString) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return output.toString();
}
#Override
protected List<CarMake> doInBackground(String... urls) {
List<CarMake> carMaker = null;
String xml = null;
for (String url : urls) {
xml = getXmlFromUrl(url);
InputStream stream = new ByteArrayInputStream(xml.getBytes());
carMaker = SAXXMLParser.parse(stream);
}
// stream.close();
return carMaker;
}
#Override
protected void onPostExecute(List<CarMake> carMaker) {
if (carMaker==null){
Toast.makeText(Sell.this, "carMaker is empty..", Toast.LENGTH_LONG).show();
} else {
E_VodaDB myE_Voda = new E_VodaDB(this.context);
myE_Voda.InsertData(carMaker);
}
}
}
}
As can be seen, my doInBackground() returns a result, carMaker. Then in my OnPostExecute(), I am passing the carMaker arraylist to my databases class to insert in db.
// Adding new service
public void InsertData(List<CarMake> carMaker) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(CARMAKE_NAME, carMaker.get(0).getCarMake()); // CarMake Names
// Inserting Row
db.insert(TABLE_CARDEALER, null, values);
db.close(); // Closing database connection
}
}
I get the following error when I run the app in Android Studio:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
Pointing to my Sell.java in my onPostExecute(). It seems the carMaker arraylist returned from doInBackground() is empty or it is in a different data type that cannot be directly stored into db. How would I go about fixing this error? Please note am a newbie to android

on doInBackground() you create arraylist but forget to initialize. try this.
#Override
protected List<CarMake> doInBackground(String... urls) {
List<CarMake> carMaker = new ArrayList<CarMake>();
String xml = null;
for (String url : urls) {
xml = getXmlFromUrl(url);
InputStream stream = new ByteArrayInputStream(xml.getBytes());
carMaker = SAXXMLParser.parse(stream);
}
// stream.close();
return carMaker;
}
you pass the null instance of current class context in this:
#Override
protected void onPostExecute(List<CarMake> carMaker) {
//E_DB myE_db = new E_DB(null);// replace this to
E_DB myE_db = new E_DB(this);
myE_db.InsertData(carMaker);
}
}
Happy coding!!

Related

Pull specific JSON objects from a specific array to put in another activity by an Intent in Android

I am creating a News Feed App, and I want to be able to pull information from a specific listing to a different layout that displays the title, source, image and content of the news listing. On the main page, the JSON will populate the list view with the title, source and image. I've sent an onItemClickListener, and when I click on each entry, I want it to open that entry in the new layout to display all the content. I have a class made just to pull the JSON info, so I'm not sure how to use that in the class with the onItemClick listener. I understand the putExtra, but I'm completely lost on the code to enter to transfer over what I need. Below is code from the page with the list, as well as the JsonQuery class. Thanks for any help!
TopHeadlinesFragment.java
public class TopHeadlinesFragment extends Fragment
implements LoaderManager.LoaderCallbacks<List<News>> {
public static final String NEWS_FEED_URL =
"https://newsapi.org/v2/top-headlines?country=us&apiKey=a3f791903c1a4163b223dd033563084b";
private static final int NEWS_LOADER_ID = 1;
private NewsAdapter mNewsAdapter;
private NewsAdapterListing mNewsAdapterListing;
public TopHeadlinesFragment(){
// Required empty public constructor
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.news_list, container, false);
mNewsAdapter = new NewsAdapter(getActivity(), new ArrayList<News>());
ListView listView = rootView.findViewById(R.id.list);
listView.setAdapter(mNewsAdapter);
final LoaderManager loaderManager = getLoaderManager();
loaderManager.initLoader(NEWS_LOADER_ID, null, this);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mNewsAdapterListing = new NewsAdapterListing(getActivity(), new ArrayList<News>());
News currentNews = mNewsAdapterListing.getItem(position);
Intent newsArticleDisplayIntent = new Intent(getActivity(), FullArticleListing.class);
startActivity(newsArticleDisplayIntent);
}
});
return rootView;
}
#Override
public Loader<List<News>> onCreateLoader(int id, Bundle args) {
return new NewsLoader(getActivity(), NEWS_FEED_URL);
}
#Override
public void onLoadFinished(Loader<List<News>> loader, List<News> data) {
mNewsAdapter.clear();
if (data != null && !data.isEmpty()){
mNewsAdapter.addAll(data);
}
}
#Override
public void onLoaderReset(Loader<List<News>> loader) {
mNewsAdapter.clear();
}
public static class NewsLoader extends AsyncTaskLoader<List<News>> {
private String[] mUrl;
public NewsLoader(Context context, String... url) {
super(context);
mUrl = url;
}
#Override
protected void onStartLoading() {
forceLoad();
}
#Override
public List<News> loadInBackground() {
if (mUrl.length < 1 || mUrl[0] == null) {
return null;
}
return JsonQueryUtils.fetchNewsData(mUrl[0]);
}
}
}
JsonQueryUtils.java
public class JsonQueryUtils {
/** Contains networking and JSON parsing code **/
private static final String LOG_TAG = "JsonQueryUtils";
private JsonQueryUtils(){
}
/** Helper method to fetch news data and call networking code within method **/
public static List<News> fetchNewsData(String requestUrl){
URL url = createUrl(requestUrl);
String jsonResponse = null;
try{
jsonResponse = makeHttpRequest(url);
} catch (IOException e){
Log.e(LOG_TAG, "Error closing input stream", e);
}
List<News> news = extractNews(jsonResponse);
Log.i(LOG_TAG, "fetchNewsData initialized");
return news;
}
private static List<News> extractNews (final String newsJSON) {
if (TextUtils.isEmpty(newsJSON)) {
return null;
}
List<News> news = new ArrayList<>();
try {
JSONObject jsonNewsObject = new JSONObject(newsJSON);
JSONArray newsArray = jsonNewsObject.getJSONArray("articles");
for (int i = 0; i < newsArray.length(); i++) {
JSONObject currentNews = newsArray.getJSONObject(i);
JSONObject source = currentNews.optJSONObject("source");
String imageUrl = currentNews.getString("urlToImage");
Bitmap newsImage = makeHttpRequest(imageUrl);
String title = currentNews.getString("title");
String sourceName = source.getString("name");
String content = currentNews.getString("content");
news.add(new News(newsImage, title, sourceName));
}
} catch (JSONException e) {
e.printStackTrace();
Log.e(LOG_TAG, "problem with parsing", e);
} catch (IOException e){
e.printStackTrace();
}
return news;
}
/**
* Make an HTTP request to the given imageURL and return a Bitmap as the response.
*/
private static Bitmap makeHttpRequest (String imageUrl) throws IOException {
Bitmap newsImage = null;
if (imageUrl == null){
return newsImage;
}
URL url = createUrl(imageUrl);
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.connect();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
newsImage = BitmapFactory.decodeStream(inputStream);
}
} catch (IOException e) {
Log.e(LOG_TAG, "Error reading bitmap input stream");
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return newsImage;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem reading input stream.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/** Helper method to create {#link} URL object **/
private static final URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "createUrl: error", e);
}
return url;
}
}
I noticed you extracted the 'content' from JSON response but I don't see anywhere the variable 'content' getting used to construct the News object... Is there a reason why you don't include it to News object?
Regarding sending the News object to the next activity, there are few ways to achieve this.
Use Parcelable to send the News to your next activity/fragment. For more details, click here.
Install GSON library and simple convert your News object to Json String. Put that String in your Intent as an extra and launch the next Activity. Retrieve the data by calling new Gson().fromJson(). However, since your object has Bitmap field, this won't be a suitable approach. For more details, click here
This is what I would have done, if the API allows: Simply call the API request again for more details about the current feed. For example, you can execute another API request in your FullArticleActivity along with an ID that is associated with the selected feed. (i.e. User clicks a feed with an id #3 -> Pass the id(Integer) to the next Activity as an extra -> Retrieve the id from extras and make another API request using the id to retrieve full article details.) However, this is possible only when your API provides a GET method like this.
Create a Singleton and let it hold your object temporarily. Retrieve the object in the next activity by simple calling something like YourSingletonClass.getInstance().getNews().

How do I make a call OK HttpRequest post from an isolated class using async?

I was using this in another place as async but I wanted to refactor to make it reusable, how can I reorganize the code in order to work as a consumable class?. It doesn't work if it's not async and the ip of the backend is well defined so it's not that. Any ideas?
public class HTTPRequestManager {
public static JSONArray fetchData(){
return null;
}
public static String postData(Context context, String url, String JSONData) {
return null;
}
/* #Override
protected Integer doInBackground(String... strings) {
try {
//1.create client Object
OkHttpClient client = new OkHttpClient();
//2.Define request being sent to server
RequestBody postData = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONData);
Request request = new Request.Builder()
.url(context.getResources().getString(R.string.backend_base_url) + url)
.post(postData)
.build();
//3.Transport the request and wait for response to process next
Response response = client.newCall(request).execute();
String resultData = response.body().string();
if (resultData.equals("OK")) {
} else {
//post failed
return "FAILED";
}
return resultData;
} catch (Exception e) {
Log.d("API_CONNECTION_ERROR", "Couldn't connect to the API");
return "API_CONNECTION_ERROR";
}
}*/
}
I used to have this annonymous class embeeded in another class and it works(it's a get request) but the problem is that it's not reusable in that way:
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
URL url = null;
#Override
protected void onPreExecute() {
getActivity().setProgressBarIndeterminateVisibility(true);
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
url = new URL (getResources().getString(R.string.backend_base_url) +
"api/flrcks/user/id/0/latitude/3000/longitude/300/within/9999999999999999999999999");
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
if (result == 1) {
adapter = new MyRecyclerAdapter_Nearby(getActivity(), feedsList);
mRecyclerView.setAdapter(adapter);
checkAdapterIsEmpty();
} else {
Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
t.setVisibility(View.VISIBLE);
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.getJSONArray("rows");
feedsList = new ArrayList<>();
JSONArray members;
for (int i = 0; i < posts.length(); i++) {
memberList = new ArrayList<>();
final JSONObject post = posts.optJSONObject(i);
members=post.getJSONArray("members");
final FeedItem item = new FeedItem();
//for (int i = 0; i < posts.length(); i++) {
//JSONObject post = posts.optJSONObject(i);
//FeedItem item = new FeedItem();
item.setId(post.optString("id"));
item.setTitle(post.optString("name"));
item.setDescription(post.optString("description"));
item.setPrivacy(post.optString("privacy_mode_description"));
item.setInitial_date(post.optString("initial_date"));
item.setThumbnail(post.optString("thumbnail"));
item.setColor_hex(post.optString("color_hex"));
item.setTag(post.optString("tag"));
item.setDistance(post.optInt("st_distance"));
//item.setThumbnail(post.optString("thumbnail"));
for(int k=0; k <members.length();k++)
{
MemberItem memberItem = new MemberItem();
JSONObject member = members.optJSONObject(k);
memberItem.setName(member.optString("name"));
memberItem.setUsername(member.optString("username"));
memberItem.setProfile_pic(member.optString("profile_pic"));
memberItem.setIs_moderator(member.optBoolean("is_moderator"));
memberItem.setFacebookId(member.optString("facebook_id"));
memberList.add(memberItem);
}
item.setMemberList(memberList);
feedsList.add(item);
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
What changes do I need to make to put it in an isolated file to be consumed by the whole app like for example in a file called OkHTTPRequests.class???
Create an interface
public interface OnWebResponseListener {
void onWebResponse(CommonUtilities.services service, String result);
}
create a public enum for identifying service. in my case i created a CommonUtilities java where i declared
public enum services {
LOGIN
}
Your Common File
public class CallAddr extends AsyncTask<String, Void, String> {
CommonUtilities.services service;
OnWebResponseListener onWebResponseListener;
String url;
FormBody.Builder body;
Request request;
OkHttpClient client;
final static String TAG = "CallAddr";
public CallAddr(Map<String, String> data, CommonUtilities.services service, OnWebResponseListener onWebResponseListener, String url) {
this.service = service;
this.onWebResponseListener = onWebResponseListener;
this.url = url;
body = new FormBody.Builder();
for (String key : data.keySet()) {
body.add(key, data.get(key));
}
client = new OkHttpClient();
}
#Override
protected String doInBackground(String... strings) {
String result = "";
request = new Request.Builder().url(url).post(body.build()).build();
try {
Response response = client.newCall(request).execute();
result = response.body().string();
} catch (Exception e) {
Log.e(TAG,Log.getStackTraceString(e));
}
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (onWebResponseListener != null) {
onWebResponseListener.onWebResponse(service, s);
}
}
}

Setter doesnt work [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Iam trying to make login activity
I got a problem. My setter doesnt work, i dont know why?
I have 3 classes.
1st one is Data with server data and getters and setters
public class Data{
String addressesURL = "/DataSnap/rest/TServerMethods1/LookupCustomers";
String articlesURL = "/DataSnap/rest/TServerMethods1/LookupArticle";
String invoicesURL = "/DataSnap/rest/TServerMethods1/LookupInvoice";
String invoicesDetailsURL = "/DataSnap/rest/TServerMethods1/LookupInvoicePos";
String invoicesDetailsAddressesURL = "/DataSnap/rest/TServerMethods1/LookupInvoiceAddress";
String ordersURL = "/DataSnap/rest/TServerMethods1/LookupOrders";
String ordersDetailsURL = "/DataSnap/rest/TServerMethods1/LookupOrdersPos";
String ordersDetailsAddressesURL = "/DataSnap/rest/TServerMethods1/LookupOrdersAddress";
public String serverURL;
//String serverURL = "http://10.10.10.75:8081";
String username = "admin";
String password = "admin";
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddressesURL() {
return addressesURL;
}
public void setAddressesURL(String addressesURL) {
this.addressesURL = addressesURL;
}
public String getArticlesURL() {
return articlesURL;
}
public void setArticlesURL(String articlesURL) {
this.articlesURL = articlesURL;
}
public String getInvoicesURL() {
return invoicesURL;
}
public void setInvoicesURL(String invoicesURL) {
this.invoicesURL = invoicesURL;
}
public String getInvoicesDetailsURL() {
return invoicesDetailsURL;
}
public void setInvoicesDetailsURL(String invoicesDetailsURL) {
this.invoicesDetailsURL = invoicesDetailsURL;
}
public String getInvoicesDetailsAddressesURL() {
return invoicesDetailsAddressesURL;
}
public void setInvoicesDetailsAddressesURL(String invoicesDetailsAddressesURL) {
this.invoicesDetailsAddressesURL = invoicesDetailsAddressesURL;
}
public String getOrdersURL() {
return ordersURL;
}
public void setOrdersURL(String ordersURL) {
this.ordersURL = ordersURL;
}
public String getOrdersDetailsURL() {
return ordersDetailsURL;
}
public void setOrdersDetailsURL(String ordersDetailsURL) {
this.ordersDetailsURL = ordersDetailsURL;
}
public String getOrdersDetailsAddressesURL() {
return ordersDetailsAddressesURL;
}
public void setOrdersDetailsAddressesURL(String ordersDetailsAddressesURL) {
this.ordersDetailsAddressesURL = ordersDetailsAddressesURL;
}
public String getServerURL() {
return serverURL;
}
public void setServerURL(String serverURL) {
this.serverURL = serverURL;
}}
2nd one is where I start my login Activity
public class Settings extends AppCompatActivity {
//declarations
//Edittext fields for username , server, password & port information
EditText edtIpurl, edtPort, edtUsername, edtPassword;
//Textviews that can be clicked
TextView databaseDel, databaseRef, magnumgmbh, contact, support;
//imagebuttons for bottom menu
ImageButton contacts, articles, invoices, orders;
//string for server URL
//String sURL = "http://";
Thread newSettingsThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
setTitle("Settings");
newSettingsThread = new Thread(){
public void run(){
runOnUiThread(new Runnable() {
#Override
public void run() {
String serverURL = "http://rest.magnumgmbh.de";
//edtIpurl = (EditText)findViewById(R.id.edtIpurl);
Data newD = new Data();
newD.setServerURL(serverURL);
}
});
}
};
newSettingsThread.start();
//start activitys if bottom buttons clicked
contacts = (ImageButton) findViewById(R.id.contacts);
//articles activity start
contacts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//start activity addresses
Intent startAddresses = new Intent(Settings.this, Addresses.class);
startActivity(startAddresses);
}
});
}}
And the next one is where i try to get my new serverURL
public class Address extends AppCompatActivity{
Thread newAddressThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addresses);
//set activity name
setTitle("Addresses");
//new thread for network operations
newAddressesThread = new Thread() {
public void run() {
//make text from json
jsonText = new StringBuilder();
try {
String str;
Data newData = new Data();
//json dates url
String addressesURL = newData.getAddressesURL();
String serverUrl = newData.getServerURL();
String username = newData.getUsername();
String password = newData.getPassword();
URL url = new URL(serverUrl + addressesURL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//String encoded = Base64.encode("admin:admin");
String encoded = Base64.encodeToString((username+":"+password).getBytes("UTF-8"), Base64.NO_WRAP);
urlConnection.setRequestProperty("Authorization", "Basic " + encoded);
//check http status code
try {
int statusCode = urlConnection.getResponseCode();
System.out.println(statusCode);
} catch (IOException e) {
}
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
while ((str = in.readLine()) != null) {
jsonText.append(str);
}
//cast stringbuilder to string
addressesJsonStr = jsonText.toString();
//close IOstream
in.close();
} catch (MalformedURLException e1) {
System.out.println(e1.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
};
//start thread
newAddressesThread.start();
}}
Hier in the third one by serverURL I got null and it thow me an exeption "Protocol not found: null/DataSnap/rest/TServerMethods1/LookupCustomers" so that is my problem.
What do I wrong?
you are creating a new Object in the third class, so the url has the initilize value because the url you've setted in the second class is stored in another object.
If you want that all Objects of Type Data have the same adress, make the variable static otherwise you have to access the object you have created in the second class in the third class.

XML parsing in android.not working

I have a few Java files that I have to try and get info from an XML on the internet. I made the files with the help of some tutorials online but I can't find the problem with what I have.
Below are the three classes I used.
MainXMLClass.java
public class News extends ActionBarActivity {
static final String baseURL = "http://coderdojo.com/rss.xml";
ListView News;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news);
getActionBar().setHomeButtonEnabled(true);
xmlRefs();
GetURLData();
ArrayList<String> XMLData = new ArrayList<>();
XMLData.add(XMLDataCollected.GetXMLData());
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.id.lvNews, XMLData);
News.setAdapter(adapter);
}
private void xmlRefs() {
// TODO Auto-generated method stub
News = (ListView) findViewById(R.id.lvNews);
}
private void GetURLData() {
// TODO Auto-generated method stub
try {
URL webPage = new URL(baseURL);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
XMLDataHandler Data = new XMLDataHandler();
reader.setContentHandler(Data);
reader.parse(new InputSource(webPage.openStream()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
My XMLHandler.java Class:
public class XMLDataHandler extends DefaultHandler {
XMLDataCollected Info = new XMLDataCollected();
public String getInformation() {
return XMLDataCollected.GetXMLData();
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("title")) {
String title = localName.getBytes().toString();
Info.setTitle(title);
} else if (localName.equals("link")) {
String link = localName.getBytes().toString();
Info.setLink(link);
} else if (localName.equals("description")) {
String description = localName.getBytes().toString();
Info.setDescription(description);
}
}
}
And finally my XMLDataCollected.java class:
public class XMLDataCollected {
static String title;
static String description;
static String link;
public void setTitle(String t) {
title = t;
}
public void setDescription(String d) {
description = d;
}
public void setLink(String l) {
link = l;
}
public static String GetXMLData() {
return title + description + link;
}
}
I've been trying for about three days to get this sorted but so far I haven't been able to find a solution anywhere.
This is my first time trying to use XML parsing so I'm aware there is bound to be a few things wrong with the files but any help is appreciated.
I may be missing something, but are you SURE about that URL, as I understand, this is the final URL : http://coderdojo.com/news?page=0 or some other number. But when I typed into the browser, the result is not XML format.

Return data from AsyncTask class

How do I get the data from my AsyncTask? My MainActivity is calling the DataCall.getJSON function that triggers the AsyncTask but I am not sure how to get the data back to the original Activity.
MainActivity with call to DataCall that should return a string and save it in state_data
String state_data = DataCall.getJSON(spinnerURL,spinnerContentType);
DataCall:
public class DataCall extends Activity {
private static final String TAG = "MyApp";
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
protected void onPostExecute(String result) {
//THIS IS WHERE I NEED TO RETURN MY DATA TO THE MAIN ACTIVITY. (I am guessing)
}
}
public void getJSON(String myUrlString, String contentType) {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.mywebsite.com/" + myUrlString });
}
}
modify your AsyncTask as below:
public class GetData extends AsyncTask<String, Void, String>
{
DataDownloadListener dataDownloadListener;
public GetData()
{
//Constructor may be parametric
}
public void setDataDownloadListener(DataDownloadListener dataDownloadListener) {
this.dataDownloadListener = dataDownloadListener;
}
#Override
protected Object doInBackground(Object... param)
{
// do your task...
return null;
}
#Override
protected void onPostExecute(Object results)
{
if(results != null)
{
dataDownloadListener.dataDownloadedSuccessfully(results);
}
else
dataDownloadListener.dataDownloadFailed();
}
public static interface DataDownloadListener {
void dataDownloadedSuccessfully(Object data);
void dataDownloadFailed();
}
}
and use it in your Activity
GetData getdata = new GetData();
getdata.setDataDownloadListener(new DataDownloadListener()
{
#SuppressWarnings("unchecked")
#Override
public void dataDownloadedSuccessfully(Object data) {
// handler result
}
#Override
public void dataDownloadFailed() {
// handler failure (e.g network not available etc.)
}
});
getdata.execute("");
NOTE: For the people who are reading this.
Please consider this post for the best and perhaps right implementation.
The key for me was to create a class called URLWithParams or something because AsyncTask will allow only 1 type to be sent IN, and I needed both the URL and the params for the HTTP request.
public class URLWithParams {
public String url;
public List<NameValuePair> nameValuePairs;
public URLWithParams()
{
nameValuePairs = new ArrayList<NameValuePair>();
}
}
and then I send it to a JSONClient:
public class JSONClient extends AsyncTask<URLWithParams, Void, String> {
private final static String TAG = "JSONClient";
ProgressDialog progressDialog ;
GetJSONListener getJSONListener;
public JSONClient(GetJSONListener listener){
this.getJSONListener = listener;
}
#Override
protected String doInBackground(URLWithParams... urls) {
return connect(urls[0].url, urls[0].nameValuePairs);
}
public static String connect(String url, List<NameValuePair> pairs)
{
HttpClient httpclient = new DefaultHttpClient();
if(url == null)
{
Log.d(TAG, "want to connect, but url is null");
}
else
{
Log.d(TAG, "starting connect with url " + url);
}
if(pairs == null)
{
Log.d(TAG, "want to connect, though pairs is null");
}
else
{
Log.d(TAG, "starting connect with this many pairs: " + pairs.size());
for(NameValuePair dog : pairs)
{
Log.d(TAG, "example: " + dog.toString());
}
}
// Execute the request
HttpResponse response;
try {
// Prepare a request object
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pairs));
response = httpclient.execute(httpPost);
// Examine the response status
Log.i(TAG,response.getStatusLine().toString());
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
return json;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String json ) {
getJSONListener.onRemoteCallComplete(json);
}
public interface GetJSONListener {
public void onRemoteCallComplete(String jsonFromNet);
}
}
Then call it from my main class like this
public class BookCatalog implements GetJSONListener {
private final String TAG = this.getClass().getSimpleName();
private String catalog_url = "URL";
private void getCatalogFromServer() {
URLWithParams mURLWithParams = new URLWithParams();
mURLWithParams.url = catalog_url;
try {
JSONClient asyncPoster = new JSONClient(this);
asyncPoster.execute(mURLWithParams);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onRemoteCallComplete(String jsonBookCatalogList) {
Log.d(TAG, "received json catalog:");
Log.d(TAG, jsonBookCatalogList);
JSONObject bookCatalogResult;
try {
bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue();
JSONArray books = bookCatalogResult.getJSONArray("books");
if(books != null) {
ArrayList<String> newBookOrdering = new ArrayList<String>();
int num_books = books.length();
BookCatalogEntry temp;
DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books.");
for(int book_id = 0; book_id < num_books; book_id++) {
JSONObject book = books.getJSONObject(book_id);
String title = book.getString("title");
int version = book.getInt("price");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Although i disagree creating a new activity for that simple task there is
startActivityForResult()
to get data from another activity.
Check this. You can store your data to the Intent's extras. But still if you have a large amount of data you better off write it to a file get the result from the other activity that is done downloading and then read the file.
Serialize it and then read it. The only way I'm aware of.
Some options:
a) Make your bean implement Serializable interface, you can then pass your bean through Intent.
b) Implement Application interface (you need to make an entry in manifest), Have setter\getter method in your Application class. You can set your bean in Application from AsyncTask and later retrieve from Activity.
Sorry for answering so late, i think by this time you might have solved this problem. when i was searching for something else, i came across your question. I'm pasting a link here which might of some help for others.

Categories