How to know if my Jsoup element is being properly selected - android

I am trying to debug an issue I am having. I am using the following code to try to get the link to an image off of a page.
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... args) {
String urls = args[0];
Document doc = null;
try {
doc = Jsoup.connect(urls).ignoreContentType(true).get();
image = doc.select("img[src~=(?i)\\.(png|jpe?g|gif)]").last();
theurlstring = "test " + image.attr("src"); // I put test here to make sure it is being executed
} catch (IOException e) {
e.printStackTrace();
}
return urls;
}
}
I am usually getting an error from any way I am trying to get the link from the Element "image." It says
Attempt to invoke virtual method 'java.lang.String org.jsoup.nodes.Element.attr(java.lang.String)' on a null object reference
So with that error, I am now thinking that image is not getting selected properly. Does anyone see anything that looks wrong? Or how could I pinpoint the problem better?

Your query is not working, see http://try.jsoup.org/~I4Y0POaloHUtrNTMJO7IAiAUIRY
You could use:
image = doc.select("img[src$=.png],img[src$=.gif],img[src$=.jpg],img[src$=.jpeg]").last();
Not as compact, but at least selecting the images (see http://try.jsoup.org/~kjnlfvCzrxiqaGQqwcszLZswSNg).
If the error persists, use try.jsoup.org with your source url to verify, that the expected output is rendered in the received html, to rule out issues with javascript generated content.

Related

Getting error when use Android Koush Ion to call Laravel route

I'm trying to learn android development, I'm using Android Studio. I need to access an external database (to insert, get itens ... CRUD) and I've found a tutorial that tells me to use koush ion, from Android using Ion, I call a web page that is a Laravel 7 Route. When I call without parameters, it works very well and I can get in Android the returned value. But when I use "setBodyParameter", I get the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.gson.JsonElement com.google.gson.JsonObject.get(java.lang.String)' on a null object reference
My laravel route just calls this function:
function cadastrar(){
date_default_timezone_set('America/Sao_Paulo');
$resposta = array();
$myUser = null;
$nome = isset($_POST['nome']) ? $_POST['nome'] : 'Teste 2';
$email = isset($_POST['email']) ? $_POST['email'] : 'teste#gmail.com';
$myUser = new Usuario;
$myUser->nome = $nome;
$myUser->email = $email;
$myUser->save();
$resposta = array('id' => strval($myUser->id_usuario), 'nome' => $myUser->nome, 'email' => $myUser->email);
return json_encode($resposta);
}
My Laravel route is Route::get (but when I change it to Route::post I get an error too).
And my Android code that calls this page is:
final TextView txtErro = (TextView) findViewById(R.id.textView4);
txtErro.setText("");
final String strNome = nome.getText().toString();
final String strEmail = email.getText().toString();
String url = "**My URL to the route in laravel**";
Ion.with(MainActivity.this)
.load(url)
.setBodyParameter("nome", strNome)
.setBodyParameter("email", strEmail)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
try {
txtErro.setText(result.get("id").getAsString());
} catch (Exception erro) {
txtErro.setText(erro.toString());
}
}
});
When I comment the two lines of ".setBodyParameter", I get the returned value from laravel (if laravel route is Route::get). When I change the line of "load" to "load("POST", url)", I get an error.
I tried something related to CORS that I found here in StackOverflow and in my Laravel Kernel.php I commented the line that calls "VerifyCsrfToken", but still didn't working.
(Finally, I'm sorry if have something wrong in my english)
Did you try logging the Exception e and JsonObject result?
or set logging for the request and watch it in logcat
.setLogging("MyLogs", Log.DEBUG)

Is there a transformItems equivalent in the Android Java Libraries for Algolia?

I have a use case where i would like to render the image associated with the hits returned from an Algolia search using the Algolia Java library for Android. I am currently developing on Pie . Here is what i am doing :
I use com.algolia.instantsearch.core.helpers.Searcher
I bind the results to a fragment which has a layout with the algolia attributes for images
<ImageView
algolia:attribute='#{"image_url"}'
>
The trouble is that the response JSON only stores the name of the JPG image which needs to be displayed. I need to dynamically add the base site URL and some more path specifiers . I tried doing something like this
algolia:attribute='https://somedomain.com/somepath1/ProductImages/#{"BaseProductId"}/thumbnails/#{"image_url"}
But that was not accepted.
I am looking for a way to transform the results so i can build the complete URL and place it in the image_url and then use it in the layout as stated in the first code fragment.
Is there any way to do it ?
I solved it by adding a listener and updating the hits object as seen below.
searcher.registerResultListener(new AlgoliaResultsListener() {
#Override
public void onResults(#NonNull SearchResults results, boolean isLoadingMore) {
for (int i=0;i<results.hits.length();i++){
try {
JSONObject obj = results.hits.getJSONObject(i);
String image_url_file = obj.getString("image_url");
String base_product_id = obj.getString("BaseProductId");
String full_image_path = "https://somedomain.com/somPath/ProductImages/"+base_product_id+"/Original/"+image_url_file;
results.hits.getJSONObject(i).put("image_url",full_image_path);
}catch(Exception exx){
}
}
}
}
);

Convert html parser with multiple divs from swift to android using Jsoup

I am trying to convert iOS application into android. But I just start learning Java a few days ago. I'm trying to get a value from a tag inside html.
Here is my swift code:
if let url = NSURL(string: "http://www.example.com/") {
let htmlData: NSData = NSData(contentsOfURL: url)!
let htmlParser = TFHpple(HTMLData: htmlData)
//the value which i want to parse
let nPrice = htmlParser.searchWithXPathQuery("//div[#class='round-border']/div[1]/div[2]") as NSArray
let rPrice = NSMutableString()
//Appending
for element in nPrice {
rPrice.appendString("\n\(element.raw)")
}
let raw = String(NSString(string: rPrice))
//the value without trimming
let stringPrice = raw.stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: .RegularExpressionSearch, range: nil)
//result
let trimPrice = stringPrice.stringByReplacingOccurrencesOfString("^\\n*", withString: "", options: .RegularExpressionSearch)
}
Here is my Java code using Jsoup
public class Quote extends Activity {
TextView price;
String tmp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quote);
price = (TextView) findViewById(R.id.textView3);
try {
doc = Jsoup.connect("http://example.com/").get();
Element content = doc.getElementsByTag("//div[#class='round-border']/div[1]/div[2]");
} catch (IOException e) {
//e.printStackTrace();
}
}
}
My problems are as following:
I got NetworkOnMainThreatException whenever i tried any codes.
I'm not sure that using getElementByTag with this structure is correct.
Please help,
Thanks.
I got NetworkOnMainThreatException whenever i tried any codes.
You should use Volley instead of Jsoup. It will be a faster and more efficient alternative. See this answer for some sample code.
I'm not sure that using getElementByTag with this structure is correct.
Element content = doc.getElementsByTag("//div[#class='round-border']/div[1]/div[2]");
Jsoup doesn't understand xPath. It works with CSS selectors instead.
The above line of code can be corrected like this:
Elements divs = doc.select("div.round-border > div:nth-child(1) > div:nth-child(2)");
for(Element div : divs) {
// Process each div here...
}

Android Jsoup Table Index out of Bounds

When I try to parse the document from a html file it works fine.
But, when I try to parse a document from a url it gives the following error:
java.lang.IndexOutOfBoundsException: Invalid index 3, size is 2
I am sure the content from the file is the same from the url and I also tried using threads
Here, below is the website:
http://pucminas.br/relatorio_atividades_2014/arquivos/ensino_graduacao.htm
Here, below, is the code
class MyTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String title ="";
try {
URL url = new URL(getString(R.string.url));
Document doc = Jsoup.parse(url, 3000);
Element table = doc.select("table").get(3);
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
}
You should know that Jsoup has a size limit and a timeout limit also, therefor not every table is parsed.
Fortunately, there's a way to change this when connecting to the site and making your document object.
Solution
Document doc = Jsoup.connect(url).maxBodySize(0)
.timeout(0)
.followRedirects(true)
.get();
JSoup APIDocs
Connection#maxBodySize(int bytes)
Update the maximum body size, in bytes.
Connection#timeout(int millis)
Update the request timeout.

About how to pass the ParseObject(Object) using Rest API(service) in Installation class in android?

I am sagar, i am trying to implement the Parse Push-Notification in android using REST API (Service), and i am almost got success in implement the Push-Notification in Xamarin-Android using REST API. But i got stuck with one part in sending the Data into REST service. I trying to pass the ParseObject in service, but the in parse table there is a need of Object,(). I have tried to pass the ParseObject as below:
JsonConvert.SerializeObject(ParseUser.CurrentUser)
It convert ParseObject into array and array is not accepted in table and ,i got failed to save it in table. because there i a need of object.
I need solution or suggestion from developer guys. Yours help will be appreciated. I am trying the below code to achieve the result.
public static void RegisterPush(string regristrationId)
{
if (regristrationId != null) {
string appID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string restID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string masterID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try {
var client = new RestClient ("https://api.parse.com");
var request = new RestRequest ("1/installations", RestSharp.Method.POST);
request.AddHeader ("Accept", "application/json");
request.AddHeader ("X-Parse-Application-Id", appID);
request.AddHeader ("X-Parse-REST-API-Key", restID);
request.Credentials = new NetworkCredential (appID, masterID);
request.Parameters.Clear ();
Console.Error.WriteLine ("ParseUser.CurrentUser-->"+ (ParseObject) ParseUser.CurrentUser);
//JsonConvert.SerializeObject(ParseUser.CurrentUser)
string strJSONContent = "{\"user\" :"+ JsonConvert.SerializeObject(ParseUser.CurrentUser)+",\"owner\":\"" + ParseUser.CurrentUser.ObjectId + "\",\"deviceType\":\"android\",\"GCMSenderId\":\"1234567890\",\"appName\":\"abcdefgh\",\"pushType\":\"gcm\",\"deviceToken\":\"" + regristrationId + "\"}";
Console.Error.WriteLine("json string-->"+ strJSONContent);
request.AddParameter ("application/json", strJSONContent, ParameterType.RequestBody);
client.ExecuteAsync (request, response => {
Console.Error.WriteLine ("response for android parse installation-->" + response.Content);
});
} catch (Exception ex) {
Console.WriteLine (ex.Message);
}
}
}`
Output:{"user" :[{"Key":"dealOffered","Value":4},{"Key":"dealRequested","Value":5},{"Key":"displayName","Value":"Cook"},{"Key":"email","Value":"lorenzo#gmail.com"},{"Key":"firstName","Value":"Lorenzo"},{"Key":"lastName","Value":"Cook"},{"Key":"mobileNumber","Value":9999999999.0},{"Key":"picture","Value":{"IsDirty":false,"Name":"tfss-afd25c29-6679-4843-842c-fe01f7fcf976-profile.jpg","MimeType":"image/jpeg","Url":"http://files.parsetfss.com/profile.jpg"}},{"Key":"provider","Value":"password"},{"Key":"userType","Value":"Merchant"},{"Key":"username","Value":"merchant#sailfish.com"},{"Key":"zipCode","Value":2342343}],"owner":"3cF1vHUXkW","deviceType":"android","GCMSenderId":"1234567890123","appName":"Sailfish","pushType":"gcm","deviceToken":"APA91bE3bsTIInQcoloOBE4kdLVVHVTRVtNyA1A788hYSC15wAVu8mUg-lwk7ZPk370rngrK7J6OoLmiM9HRr1CGPaBo6LCNrSUL7erBku4vepaFFkQzgqS6BcAemp"}
Error:{"code":111,"error":"invalid type for key user, expected *_User, but got array"}
maven
I found the solution in , parse xamarin docs, in one query , the way is simple, but i little bit hard to found out.
The issue is with the data passing in json format in REST, to pass any pointer using REST API, use as below.
The solution is as below:
`{
"user":{
"__type":"Pointer",
"className":"_User",
"objectId":"qYvzFzGAzc"
},
"owner":"qYvzFzGAzc",
"deviceType":"android",
"GCMSenderId":"123456789",
"appName":"NiceApp",
"pushType":"gcm",
"deviceToken":"APA91bFeM10jdrCS6fHqGGSkON17UjEJEfvJEmGpRM-d6hq3hQgDxKHbyrqAIxMnEGgbLEZf0E9AllHxiQQQCdEFiNMF1_A8q0n9tGpBE5NKhvS2ZGJ9PZ7585puWqz_1Z1EjSjOvgZ1LQo708DeL2KzA7EFJmdPAA"
}`
It looks like your column user is set up wrong. It should show as a Pointer<_User> not Pointer
If you load this class in your Data Browser, is the "user" key defined as a string, or a Pointer <_User>
This error seems to indicate that this is a string column, which is why the Parse.User object is not being accepted as a valid value. You might have tried setting a string on this key before, which in turn type-locked the "user" key as a string column.
Found it on the examples given on this page - https://www.parse.com/docs/rest
Have you check your REST API connection while passing ParseObject?
Because your error says:
Error:{"code":111,"error":"invalid type for key user, expected *_User, but got array"}
Here "code":111This error code comes when server refuse for connection

Categories

Resources