Pass JSoup to String [] - java

I want to get several images of a URL and move to a String [] and then play to a slide.
In the case I have already been able to do this with help is listing normal in the Log. However I am not sure how to transform into a String []. I did this with JSoup.
It would look like this: [http://teste.com/image1.png, http://teste.com/image2.png]
public class ImageScrapAsyncTask extends AsyncTask<String, Void, Document> {
#Override
protected Document doInBackground(String... urls) {
try {
return Jsoup.connect(urls[0]).get();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(Document document) {
if (document != null) {
Elements imgElements = document.select("img");
List<String> images = new ArrayList<>();
for (Element element : imgElements) {
String image = element.attr("data-src");
Log.d("IMAGE_URL", image);
if(image!=null && !image.equals("")){
images.add(image);
}
}
}
}
}

Try this,
String[] imagesArray = images.toArray(new String[0]);

Related

Pagination with Web Driver Selenium and JSoup

I'm developing an app that takes data from a website with JSoup. I was able to get the normal data.
But now I need to implement a pagination on it. I was told it would have to be with Web Driver, Selenium. But I do not know how to work with him, could someone tell me how I can do it?
public class MainActivity extends AppCompatActivity {
private String url = "http://www.yudiz.com/blog/";
private ArrayList<String> mAuthorNameList = new ArrayList<>();
private ArrayList<String> mBlogUploadDateList = new ArrayList<>();
private ArrayList<String> mBlogTitleList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Description().execute();
}
private class Description extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
// Connect to the web site
Document mBlogDocument = Jsoup.connect(url).get();
// Using Elements to get the Meta data
Elements mElementDataSize = mBlogDocument.select("div[class=author-date]");
// Locate the content attribute
int mElementSize = mElementDataSize.size();
for (int i = 0; i < mElementSize; i++) {
Elements mElementAuthorName = mBlogDocument.select("span[class=vcard author post-author test]").select("a").eq(i);
String mAuthorName = mElementAuthorName.text();
Elements mElementBlogUploadDate = mBlogDocument.select("span[class=post-date updated]").eq(i);
String mBlogUploadDate = mElementBlogUploadDate.text();
Elements mElementBlogTitle = mBlogDocument.select("h2[class=entry-title]").select("a").eq(i);
String mBlogTitle = mElementBlogTitle.text();
mAuthorNameList.add(mAuthorName);
mBlogUploadDateList.add(mBlogUploadDate);
mBlogTitleList.add(mBlogTitle);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Set description into TextView
RecyclerView mRecyclerView = (RecyclerView)findViewById(R.id.act_recyclerview);
DataAdapter mDataAdapter = new DataAdapter(MainActivity.this, mBlogTitleList, mAuthorNameList, mBlogUploadDateList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mDataAdapter);
}
}
}
Problem statement (as per my understanding): Scraper should be able to go to the next page until all pages are done using the pagination options available at the end of the blog page.
Now if we inspect the next button in the pagination, we can see the following html.
a class="next_page" href="http://www.yudiz.com/blog/page/2/"
Now we need to instruct Jsoup to pick up this dynamic url in the next iteration of the loop to scrap data. This can be done using the following approach:
String url = "http://www.yudiz.com/blog/";
while (url!=null){
try {
Document doc = Jsoup.connect(url).get();
url = null;
System.out.println(doc.getElementsByTag("title").text());
for (Element urls : doc.getElementsByClass("next_page")){
//perform your data extractions here.
url = urls != null ? urls.absUrl("href") : null;
}
} catch (IOException e) {
e.printStackTrace();
}
}

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0.. parse file incorrect?

I am trying to make an android application that parses pictures from online in a grid/list however Im coming up with some runtime errors.. its saying that i am parsing wrong for my FAMILY DOG BREED. Does anyone know where I am making my errors?? I know why an array would be out of bounds but i have no idea how to fix it!!
I am trying to parse http://www.dogbreedslist.info/family-dog-breeds/ this website data.. but am getting runtime errors at these sections of my
DogActivity.class
private class RetrieveDogsTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... urls) {
for (String url : urls) {
Parser parser = new Parser(url, DogsActivity.this);
Breed.Name breedName = breed.getName();
if (breedName == Breed.Name.HERDING_DOG_BREED) {
dogs.add(parser.parseProfile(new Dog(url, breedName)));
} else {
dogs.addAll(parser.parseDogsPage(breedName, DogsActivity.this));
}
}
return null;
}
Parser.class
public class Parser {
Document doc;
Context context;
Elements dogRows;
public Parser(String url, Context context) {
this.context = context;
try {
doc = Jsoup.connect(url).get();
} catch (IOException e) {
Log.e("Page", "Wrong URL or network problems", e);
}
}
public ArrayList<Dog> parseDogsPage(Breed.Name breedName, Context context) {
ArrayList<Dog> dogs = new ArrayList<>();
try {
Element dogContainer;
if (breedName == Breed.Name.FAMILY_DOG_BREED) {
dogContainer = doc.getElementsByClass("familybreed").get(0);
} else {
dogContainer = doc.getElementsByClass("toybreed").get(0);
}
Log.i("Page", "A page has been parsed successfully");
dogRows = dogContainer.getElementsByTag("a");
for (Element dogRow : dogRows) {
String dogName, dogURL;
Dog dog;
dogURL = dogRow.getElementsByTag("a").get(0).absUrl("href");
String dogThumbnailURL = dogRow.
getElementsByTag("img").get(0).absUrl("src");
if (breedName == Breed.Name.FAMILY_DOG_BREED) {
dogName = dogRow.getElementsByTag("span").get(0).text();
dog = new Dog(dogName, dogURL, dogThumbnailURL, breedName);
} else {
dogName = dogRow.getElementsByTag("strong").get(0).text();
Element details = dogContainer.getElementsByClass("details").get(0);
Elements children = details.children();
if (breedName == Breed.Name.TOY_DOG_BREED || breedName == Breed.Name.HOUND_DOG_BREED) {
String origin = children.get(1).text();
String lifespan = children.get(3).text();
dog= new Dog(dogName, origin , lifespan, dogURL, dogThumbnailURL, breedName);
} else {
//for herding
String sizetype = children.get(1).text();
dog = new Dog(dogName, sizetype, dogThumbnailURL, dogURL, breedName);
}
}
dogs.add(dog);
}
} catch (Exception e) {
Log.e("Breed activity", "Wrong parsing for " + breedName, e);
}
return dogs;
}
public Dog parseProfile(Dog dog) {
if (!dog.isDetailDataReady()) {
//coaches already read the data in the coaches page
try {
Element dogContainer = doc.getElementById("dogscontainer");
Element bioContainer = dogContainer.getElementById("biocontainer");
Element bioDetails = bioContainer.getElementById("biodetails");
dog.setOtherNames(bioDetails.getElementsByTag("h1").text());
ArrayList<Dog.Detail> dogDetails = new ArrayList<>();
Elements rows = bioDetails.getElementsByTag("tr");
for (Element row : rows) {
Elements tds = row.getElementsByTag("td");
if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED ||
dog.getBreed() == Breed.Name.TERRIER_DOG_BREED ||
dog.getBreed() == Breed.Name.HERDING_DOG_BREED) {
//coaches, manager and legends use th and td
Elements ths = row.getElementsByTag("th");
dogDetails.add(new Dog.Detail(ths.get(0).text(), tds.get(0).text()));
} else {
//dogs use two tds
dogDetails.add(new Dog.Detail(tds.get(0).text(), tds.get(1).text()));
}
}
dog.setDetails(dogDetails);
Element articleText = dogContainer.getElementsByClass("dogarticletext").get(0);
Elements paragraphs = articleText.getElementsByTag("p");
String text = "";
for (Element p : paragraphs) {
text = text + "\n\n\n" + p.text();
}
dog.setArticleText(dog.getArticleText() + text);
if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED ||
dog.getBreed() == Breed.Name.TERRIER_DOG_BREED ||
dog.getBreed() == Breed.Name.HERDING_DOG_BREED) {
//get main image url
dog.setMainImageURL(bioContainer.getElementsByTag("img").get(0).absUrl("src"));
if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED) {
dog.setThumbnailURL(dog.getMainImageURL());
//only need first name
dog.setName(dog.getOtherNames().split(" ")[1]);
}
} else {
dog.setMainImageURL(bioContainer.getElementsByClass("mainImage").get(0).absUrl("src"));
}
} catch (Exception e) {
Log.e("Profile activity", "Wrong parsing for " + dog.getUrl(), e);
}
if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED) {
dog.setBasicDataReady(true);
}
dog.setDetailDataReady(true);
}
return dog;
}
}
RetrieveDogTask:
private class RetrieveDogsTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... urls) {
for (String url : urls) {
Parser parser = new Parser(url, DogsActivity.this);
Breed.Name breedName = breed.getName();
if (breedName == Breed.Name.HERDING_DOG_BREED) {
dogs.add(parser.parseProfile(new Dog(url, breedName)));
} else {
dogs.addAll(parser.parseDogsPage(breedName, DogsActivity.this));
}
}
return null;
Logcat:
Wrong parsing for FAMILY_DOG_BREED
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at org.jsoup.select.Elements.get(Elements.java:544)
at com.example.shannon.popular.Parser.parseDogsPage(Parser.java:35)
at com.example.shannon.popular.DogsActivity$RetrieveDogsTask.doInBackground(DogsActivity.java:140)
at com.example.shannon.popular.DogsActivity$RetrieveDogsTask.doInBackground(DogsActivity.java:131)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Breed.class:
public class Breed implements Serializable {
private Name name;
private String url;
Breed(Name name, String url) {
this.name = name;
this.url = url;
}
public Name getName() {
return name;
}
public String getNameString(Context context) {
String nameString = "";
switch (name) {
case FAMILY_DOG_BREED:
nameString = context.getString(R.string.family_breed);
break;
case TOY_DOG_BREED:
nameString = context.getString(R.string.toy_breed);
break;
case HOUND_DOG_BREED:
nameString = context.getString(R.string.hound_breed);
break;
case TERRIER_DOG_BREED:
nameString = context.getString(R.string.terrier_breed);
break;
case WORKING_DOG_BREED:
nameString = context.getString(R.string.working_breed);
break;
case HERDING_DOG_BREED:
nameString = context.getString(R.string.herding_breed);
break;
}
return nameString;
}
public String getURL() {
return url;
}
public enum Name {FAMILY_DOG_BREED, TOY_DOG_BREED, HOUND_DOG_BREED, TERRIER_DOG_BREED, WORKING_DOG_BREED, HERDING_DOG_BREED}
}
You may be using a strict XML parser for a malformed HTML document. I just tried to XML-validate the URL you are parsing and it's failing because the <link> element is never closed (in strict XML, it should be ended by a </link> tag, but it's missing in that page).
This is very common for HTML pages as today's browsers tend to auto-correct these kinds of errors.
Since you use a strict XML parser, it is very likely for the parser to fail.
I suggest switching to different parser. I'd use a PULL parser (eg. http://www.xmlpull.org ) - this technique allows parsing with a lower-level of control, meaning you can easily ignore unwanted content from the HTML - like these link elements, or any others.
So you could do something like this:
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(new BufferedReader(
new InputStreamReader(
new URL("http://.....").openConnection().getInputStream()
)
)
);
while(XmlPullParser.END_DOCUMENT != parser.next()){
if(XmlPullParser.START_TAG == parser.getEventType()){
String tagName = parser.getName();
if(parser.getAttributeCount() > 0 {
// parse attributes, if needed
}
if(parser.nextToken() == XmlPullParser.TEXT){
String tagValue = parser.getText()
}
// etc.
}
}

Managing multiple Async tasks in android

Hey everyone so I am just starting a part two for online training app and trying to adapt my async task to get movie reviews from the movie db. Having a totally different async task just for that seems like there should be a better way. Here is the current async task implementation that only gets the movie data.
The question is how do I add another async task to this in order to retrive the movie reviews as well from this url /movie/{id}/videos.
public FetchMovieData(Context context, GridView grid, boolean sortType, ITaskCompleteListener listener) {
mContext = context;
this.mMoviesGrid = grid;
this.mSortByMostPopular = sortType;
this.mTaskCompleteListener = listener;
}
#Override
protected Void doInBackground(String... params) {
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
URL url;
if(mSortByMostPopular)
url = new URL(mContext.getString(R.string.picasso_url_popular_movies));
else
url = new URL(mContext.getString(R.string.picasso_url_highest_rated));
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
mMovieJsonStr = null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
mMovieJsonStr = null;
}
mMovieJsonStr = buffer.toString();
} catch (IOException e) {
Log.e("PlaceholderFragment", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attempting
// to parse it.
mMovieJsonStr = null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieJsonStr != null)
Constants.mMovies = MovieDataParser.getMovieData(mMovieJsonStr);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
So some one had suggested using Retrofit instead of having multiple async tasks. This seems like a good idea but I am having a lot of trouble understanding how it is supposed to work. Currently I have a WebService class an interface and am trying to use it to retrieve both movies and am going to add reviews then trailers. The issue is if I set the base url as "http://api.themoviedb.org" I get url must start with "/" in logcat.
Current code:
public class WebService {
public List<Movie> getMovies() {
RestAdapter retrofit = new RestAdapter.Builder()
.setEndpoint("http://api.themoviedb.org")
.build();
MovieDBService service = retrofit.create(MovieDBService.class);
return service.listMovies("movies");
}
}
public interface MovieDBService {
#GET("/3/discover/{switchterm}sort_by=popularity.desc&api_key=d273a1a1fb9390dab9 7ac0032b12366a")
List listMovies(#Path("switchterm") String switchterm);
}
//In code getting movies
WebService service = new WebService();
List movies = service.getMovies();
I think you have a lots of possibilities for doing this.You can follow this approach: add a second call to another AsyncTask when the first is finish, and pass to it a list of strings with the video ids:
public class FetchMovieData extends AsyncTask<Void, Void, Void> {
protected Boolean doInBackground() {
try {
String movieJSONString = getJSONMovies();
String[] ids = parseIdsFromJSON(movieJSONString);
if(ids.lenth != 0) {
FetchMovieReviews moviesReviewsAsyncTask = new FetchMovieReviews();
moviesReviewsAsyncTask.execute(ids);
} else {
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
protected String getJSONMovies() {
//with the code you post, return the json string
}
protected String[] parseIdsFromJSON(String JSON) {
//parse the json and get the ids and return
//return {"1","2","3"}
}
}
public class FetchMovieReviews extends AsyncTask<String[], Void, Void> {
protected Void doInBackground(String[]... params) {
for(String id : params[0]) {
//call the web service and pass the id
}
return null;
}
}
You can put all the functionality for manage the calls to the web services in a MoviesRESTCalls class, and for manage the json in a MoviesJSONParser class or something like that, and the code is going to be much more clear.
So what I ended up with was this using the the Retrofit library for the web service. Thanks for the help everyone and let me know your thoughts.
public Context mContext;
private MovieJSON mMovieData;
private ReviewJSON mMovieReviews;
private VideoJSON mMovieVideos;
public boolean mSortByMostPopular;
ITaskCompleteListener mTaskCompleteListener;
public FetchMovieData(Context context, boolean sortType, ITaskCompleteListener listener) {
mContext = context;
this.mSortByMostPopular = sortType;
this.mTaskCompleteListener = listener;
}
public void getMovies() {
new FetchMovies().execute();
}
public void getReviews() {
new FetchReviews().execute();
}
public void getVideos() {
new FetchTrailers().execute();
}
private class FetchMovies extends AsyncTask<String, Void, Void > {
#Override
protected Void doInBackground(String... params) {
WebService service = new WebService();
//TODO Re-Implement sorting
mMovieData = service.getMovies();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieData != null)
Constants.mMovies = MovieDataParser.getMovieData(mMovieData);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
}
private class FetchReviews extends AsyncTask<String, Void, Void > {
#Override
protected Void doInBackground(String... params) {
WebService service = new WebService();
mMovieReviews = service.getReviews();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieReviews != null)
Constants.mReviews = MovieDataParser.getReviewData(mMovieReviews);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
}
private class FetchTrailers extends AsyncTask<String, Void, Void > {
#Override
protected Void doInBackground(String... params) {
WebService service = new WebService();
mMovieVideos = service.getVideos();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mMovieVideos != null)
Constants.mTrailers = MovieDataParser.getVideoData(mMovieVideos);
mTaskCompleteListener.onTaskCompleted(); //Task completed alert UI that we have our data
}
}
//web service
public class WebService {
RestAdapter mRetrofit;
MovieDBService mService;
public WebService() {
mRetrofit = new RestAdapter.Builder()
.setEndpoint("http://api.themoviedb.org")
.build();
mService = mRetrofit.create(MovieDBService.class);
}
public MovieJSON getMovies() {
return mService.listMovies("");
}
public ReviewJSON getReviews() {
return mService.listReviews("76341");
}
public VideoJSON getVideos() {
return mService.listVideos("76341");
}
}

How to get value of jsonObject value in android?

I am building an android application and I am new to json. I am fetching below josn formate -
{
"contact"[
{
"key1": "hey1",
"key2": [
{
"key3": "hey2"
}
]
}
]
}
I am using below code to fetch key1 value. Now problem I am facing is how to fetch key3 value -
jsonString = http.makeServiceCall(url, ServiceHandler.GET, null);
if (jsonString != null) {
try {
JSONObject jsonObj = new JSONObject(jsonString);
// Getting JSON Array node
questions = jsonObj.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < questions.length(); i++) {
temp_obj = questions.getJSONObject(i);
key1Array.add(temp_obj.getString("key1").toString());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Please help me
If you want to use Gson to parse your json data. Let try it:
First of all, you must modify your json like this:
{
"contact":[
{
"key1": "hey1",
"key2": [
{
"key3": "hey2"
}
]
}
]
}
Second add Gson to your libs and sync build.gradle: download here extract it, and copy/past gson-2.2.4.gson to libs folder.
Third Create some class:
FullContents.java:
public class FullContents {
private List<ObjectKey> contact;
public List<ObjectKey> getContact() {
return contact;
}
public void setContact(List<ObjectKey> contact) {
this.contact = contact;
}
}
ObjectKey.java:
public class ObjectKey {
private String key1;
private List<ObjectKey3> key2;
public List<ObjectKey3> getKey2() {
return key2;
}
public void setKey2(List<ObjectKey3> key2) {
this.key2 = key2;
}
public String getKey1(){
return key1;
}
public void setKey1(String key1){
this.key1 = key1;
}
}
ObjectKey3.java:
public class ObjectKey3 {
private String key3;
public String getKey3(){
return key3;
}
public void setKey3(String key3){
this.key3 = key3;
}
}
And Finally, get data from url:
private class ParseByGson extends AsyncTask<String,Void,FullContents> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected FullContents doInBackground(String... params) {
FullContents fullContents = null;
try {
URL url=new URL(params[0]);
InputStreamReader reader=new InputStreamReader(url.openStream(),"UTF-8");
fullContents=new Gson().fromJson(reader,FullContents.class);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fullContents;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(FullContents results) {
super.onPostExecute(results);
ObjectKey objectKey = results.getContact().get(0);
Log.e(">>",objectKey.getKey1()+"--");
}
}
you can put below code to onCreate:
ParseByGson parseByGson = new ParseByGson();
parseByGson.execute(urlStringHere);
Update: Explain
1st of all: your json appears to be not valid (missing ':' after "content");
After reviewing thins:
You can use the named getters to retrieve many types of results (object, int, string, etc);
JSONObject contact = jsonObj.getJSONObject("contact"); // {"key1":"hey1","key2":[{"key3":"hey2"}]}
or
String key1 = jsonObj.getString("key1"); // hey1
To retrieve key3, you should use:
JSONObject contact = jsonObj.getJSONObject("contact");
JSONObject key2 = contact.getJSONObject("key2");
String key3 = key2.getString("key3");
Adapt the following code to what you are coding
for (int i = 0; i < questions.length(); i++) {
temp_obj = questions.getJSONObject(i);
key1Array.add(temp_obj.getString("key1"));
JSONObject temp_objKey2 = temp_obj.getJSONObject("key2");
Key2Object key2Object = new Key2Object();
key2Object.add(temp_objKey2.getString("key3"));
key1Array.add(key2Object);
}

How to convert from a List to Array ? Android

okay guys, here is the thing, I have one application consuming ODATA service, in SMP server, I'm getting this Data like this:
public class callService extends AsyncTask<Void, Void, ArrayList<String>>
{
public ArrayList<String> doInBackground(Void... params)
{
ODataConsumer c = ODataJerseyConsumer.create("http://MyUrlService:8080");
List<OEntity> listEntities = c.getEntities("MYENTITYTOCONSUME").execute().toList();
System.out.println("Size" + listEntities.size());
if (listEntities.size() > 0)
{
for (OEntity entity : listEntities)
{
zmob_kunnr.add((String) entity.getProperty("Name1").getValue()
+ " - "
+ entity.getProperty("Kunnr").getValue().toString());
}
}
return zmob_kunnr;
}
protected void onPostExecute(ArrayList<String> result)
{
super.onPostExecute(result);
adapter = new ArrayAdapter<String>(ConsumoKnuur.this, android.R.layout.simple_list_item_1, result);
list.setAdapter(adapter);
}
}
Okay I got this solution from web and could implement as list, and I need to store this entity which one is a List of customers and get the two attributes from this entity and save in my database so:
Entity Customer:Custormer_ID, Customer_Name
Here is my code to call my sqlite:
public void sqlite()
{
sql_obj.open();
sql_obj.deleteAll();
for(int i=0; i < zmob_kunnr.size(); i++)
{
sql_obj.insert(zmob_kunnr.get(i).toString(), zmob_kunnr.get(i).toString() );
}
sql_obj.close();
}
And my SQLite:
private static final String TABLE_CLIENTE = "CREATE TABLE "
+ TB_CLIENTE
+ "(ID_CLIENTE INTEGER PRIMARY KEY AUTOINCREMENT, " //Id for controller my logics
+ " Kunnr TEXT , " //customer ID
+ " Name1 TEXT );"; //customer_name
public long insert(String name1, String Kunnr)
{
ContentValues initialValues = new ContentValues();
initialValues.put("Name1", Name1); //Customer_Name
initialValues.put("Kunnr", Kunnr); //Customer_ID
return database.insert(TB_CLIENTE, null, initialValues);
}
And off course my other methods, that is not important, so whats happening when I run my "for" in the sql call method, I get the size() of the list and the rows of the list and store the entire row in the one column of the database each time, so I got two different tables with the same values,
how can I change solve this problem instead of consume in list I need to consume in array ? or I need to create a method that get the list values and after a ,(coma) , create two differents objects to store these data ??
I took a long look in the internet and didn't find nothing, probably it's because i don't know yet, how so, I don't know for what I'm looking for it, I'm using the odata4j API and here is the link of the documentation, http://odata4j.org/v/0.7/javadoc/
I'm new on programming, so I'm really in trouble with this, any suggestions any helps will be truly, appreciate,
Thanks a lot and have a nice day !!!
You can add each entity to the `ArrayList' array by doing the following:
for (OEntity entity : listEntities) {
zmob_kunnr.add(entity);
}
This will allow you to access the data contained in the entity via getProperty() when inserted into the database.
The following statement is also not needed, as the for each loop runs through every element in the list, thus for (OEntity entity : listEntities) will not execute if the list is empty.
if (listEntities.size() > 0) {
...
}
If you have multiple ODataConsumers, you have two choices, depending on your requirements (if I understand you question correctly):
You can sequentially get each ODataConsumer, get the listEntities, and add it to the zmob_kunnr list, and after the list items are added to the database, clear the zmob_kunnr list, and call doInBackground with a new URL. This is what your current solution allows.
It appears to need to know which property is associated with a URL when reading the values into the DB. You can use a POJO as a holder for the entity and its list of properties. You can now add and remove properties. Note that properties will be removed in the same order they where inserted.
public class OEntityHolder {
private final OEntity entity;
private Queue<String> properties;
public OEntityHolder(OEntity entity) {
this.entity = entity;
this.properties = new LinkedBlockingQueue<>();
}
public OEntity getEntity() {
return this.entity;
}
public void addProperty(String property) {
this.properties.add(property);
}
public void removeProperty() {
this.properties.poll();
}
}
This will require a change to the list holding the entities:
ArrayList<OEntityHolder> zmob_entity_holders = new ArrayList<>();
If you would like to add all the entities from the different URLs at the same time, you will need to have access to all the URLs when doInBackground is called. Something like this:
public ArrayList<OEntityHolder> doInBackground(Void... params) {
String [][] urls = {{"http:MyUrl/ZMOB_FECODSet", "Name1", "Fecod"},
{"http:MyUrl/ZMOB_OTEILSet", "Name2", "Oteil"},
{"http:MyUrl/ZMOB_KUNNRSet", "Name3", "Kunnr"},
{"http:MyUrl/ZMOB_BAULTSet", "Name4", "Bault"}};
for (String [] urlProp:urls) {
//Here you get the list of entities from the url
List<OEntity> listEntities = ODataJerseyConsumer.create(urlProp[0]).getEntities("MYENTITYTOCONSUME").execute().toList();
for (OEntity entity:listEntities) {
OEntityHolder holder = new OEntityHolder(entity);
for (int i = 1; i < urlProp.length; i++)
holder.addProperty(urlProp[i]);
zmob_entity_holders.add(holder);
}
}
//At this point, all of the entities associated with the list of URLS will be added to the list
return zmob_entity_holders;
}
You now have ALL of the entities associated with the list of URLs in zmob_kunnr. Before you can and can insert then into the DB like so:
for (OEntityHolder holder : zmob_entity_holders) {
sql_obj.insert(holder.getEntity().getProperty(holder.removeProperty()).toString(), holder.getEntity().getProperty(holder.removeProperty()).toString());
}
If each entity has a associated name, you can store the names in a map, where the key is the URL and the value the name.
HashMap<String, String> urlEntityNames = new HashMap<>();
urlEntityNames.put("http://MyUrlService:8080", "MYENTITYTOCONSUME");
...//Add more URLs and entity names
You can then, when running through the list of entities, do a look-up in the map to find the correct name:
List<OEntity> listEntities = ODataJerseyConsumer.create(url).getEntities(urlEntityNames.get(url)).execute().toList();
I hope this helps, if I misunderstood you just correct me in the comments.
EDIT: Added list of URLs, holder and DB insert.
I guess i found a solution, but my log cat, is giving an exception to me any updtades about my 2nd doInBackgroundBault (Material),
public class callServiceCliente extends AsyncTask<Void, Void, ArrayList<OEntity>> {
protected void onPreExecute() {
progressC = ProgressDialog.show(Atualizar_Dados.this, "Aguarde...", "Atualizando Clientes", true, true);
}
public ArrayList<OEntity> doInBackground(Void... params) {
ODataConsumer ccli = ODataJerseyConsumer.create(URL);
List<OEntity> listEntitiesKunnr = ccli.getEntities("ZMOB_KUNNRSet").execute().toList();
System.out.println("Size" + listEntitiesKunnr.size());
for (OEntity entityKunnr : listEntitiesKunnr) {
zmob_kunnr.add(entityKunnr);
}
return zmob_kunnr;
}
protected void onPostExecute(ArrayList<OEntity> kunnr) {
super.onPostExecute(kunnr);
try {
sql_obj.open();
sql_obj.deleteAll();
for (int k = 0; k < zmob_kunnr.size(); k++) {
sql_obj.insertCliente(zmob_kunnr.get(k).getProperty("Kunnr").getValue().toString().toUpperCase(), zmob_kunnr.get(k).getProperty("Name1").getValue().toString().toUpperCase());
}
sql_obj.close();
} catch (Exception e) {
}
try {
clienteAdapter = new ArrayAdapter<OEntity>(Atualizar_Dados.this, android.R.layout.simple_list_item_1, kunnr);
listCliente.setAdapter(clienteAdapter);
} catch (Exception eq) {
}
progressC.dismiss();
new callServiceMaterial().execute();
}
}
public class callServiceMaterial extends AsyncTask<Void, Void, ArrayList<OEntity>> {
protected void onPreExecute() {
progressM = ProgressDialog.show(Atualizar_Dados.this, "Aguarde...", "Atualizando Materiais", true, true);
}
public ArrayList<OEntity> doInBackground(Void... params) {
ODataConsumer cmat = ODataJerseyConsumer.create(URL);
List<OEntity> listEntitiesBault = cmat.getEntities("ZMOB_BAULTSet").filter("IErsda eq '20141101'").execute().toList();
System.out.println("Size" + listEntitiesBault.size());
for (OEntity entityBault : listEntitiesBault) {
zmob_bault.add(entityBault);
}
return zmob_bault;
}
protected void onPostExecute(ArrayList<OEntity> bault) {
super.onPostExecute(bault);
try {
sql_obj.open();
sql_obj.deleteAll();
for (int b = 0; b < zmob_bault.size(); b++) {
sql_obj.insertMaterial(zmob_bault.get(b).getProperty("Matnr").getValue().toString().toUpperCase(), zmob_bault.get(b).getProperty("Maktxt").getValue().toString().toUpperCase());
}
sql_obj.close();
} catch (Exception e) {
}
try {
materialAdapter = new ArrayAdapter<OEntity>(Atualizar_Dados.this, android.R.layout.simple_list_item_1, bault);
listMaterial.setAdapter(clienteAdapter);
} catch (Exception eq) {
}
progressM.dismiss();
new callServiceProblema().execute();
}
}
public class callServiceProblema extends AsyncTask<Void, Void, ArrayList<OEntity>> {
protected void onPreExecute() {
progressProb = ProgressDialog.show(Atualizar_Dados.this, "Aguarde...", "Atualizando Problemas", true, true);
}
public ArrayList<OEntity> doInBackground(Void... params) {
ODataConsumer cprob = ODataJerseyConsumer.create(URL);
List<OEntity> listEntitiesFecod = cprob.getEntities("ZMOB_FECODSet").execute().toList();
System.out.println("Size" + listEntitiesFecod.size());
for (OEntity entityFecod : listEntitiesFecod) {
zmob_fecod.add(entityFecod);
}
return zmob_fecod;
}
protected void onPostExecute(ArrayList<OEntity> fecod) {
super.onPostExecute(fecod);
try {
sql_obj.open();
sql_obj.deleteAll();
for (int f = 0; f < zmob_fecod.size(); f++) {
sql_obj.insertProblema(zmob_fecod.get(f).getProperty("Fecod").getValue().toString().toUpperCase(), zmob_fecod.get(f).getProperty("Kurztext").getValue().toString().toUpperCase());
}
sql_obj.close();
} catch (Exception e) {
}
try {
problemaAdapter = new ArrayAdapter<OEntity>(Atualizar_Dados.this, android.R.layout.simple_list_item_1, fecod);
listProblema.setAdapter(problemaAdapter);
} catch (Exception eq) {
}
progressProb.dismiss();
new callServiceProcedencia().execute();
}
}
public class callServiceProcedencia extends AsyncTask<Void, Void, ArrayList<OEntity>> {
protected void onPreExecute() {
progressProc = ProgressDialog.show(Atualizar_Dados.this, "Aguarde...", "Atualizando base de dados", true, true);
}
public ArrayList<OEntity> doInBackground(Void... params) {
ODataConsumer c = ODataJerseyConsumer.create(URL);
List<OEntity> listEntitiesProcedencia = c.getEntities("ZMOB_OTEILSet").execute().toList();
System.out.println("Size" + listEntitiesProcedencia.size());
for (OEntity entityProcedencia : listEntitiesProcedencia) {
zmob_oteil.add(entityProcedencia);
}
return zmob_oteil;
}
protected void onPostExecute(ArrayList<OEntity> oteil) {
super.onPostExecute(oteil);
try {
sql_obj.open();
sql_obj.deleteAll();
for (int o = 0; o < zmob_oteil.size(); o++) {
sql_obj.insertCliente(zmob_oteil.get(o).getProperty("Fecod").getValue().toString().toUpperCase(), zmob_oteil.get(o).getProperty("Kurztext").getValue().toString().toUpperCase());
}
sql_obj.close();
} catch (Exception e) {
}
try {
procedenciaAdapter = new ArrayAdapter<OEntity>(Atualizar_Dados.this, android.R.layout.simple_list_item_1, oteil);
// listCliente.setAdapter(clienteAdapter);
} catch (Exception eq) {
}
progressProc.show(Atualizar_Dados.this, "Finalizado", "Base de dados atualizada", true, true).dismiss();
Toast.makeText(Atualizar_Dados.this, "Base de dados atualizada com sucesso", Toast.LENGTH_LONG).show();
}
}
Okay, so here is the solution that i find, and i couldn't insert your solution because, when i put inser.add(entity), they didn't show me the properties but if you have a better way to do what i did, i will really appreciate,
and by the way i need to query this consume by range date in the filter(). like i did here...
List listEntitiesBault = cmat.getEntities("ZMOB_BAULTSet").filter("IErsda eq '20141101'").execute().toList(); but isn't working, so i don't have any ideas why, i saw couple close solution on the internet and saw fields like .top(1) and .first(); that i didn't understand...
thanks a lot !!!

Categories

Resources