Converting a J2ME URLCaller Class to Android equivalent - android

I got a Class from a friend for a URlCaller class for connecting to a webservice. My assumption was that all will work well, but it contains error below is the J2ME implementation
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package main;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
public class URLCaller extends Thread{
private String url ;
private String action;
private URLEncoder urle;
private String res;
public URLCaller() {
}
public URLCaller(String action,String url) {
urle = new URLEncoder();
this.url = url;
this.action = action;
start();
}
//replace
void authenticate(String action,String url) {
HttpConnection connection = null;
InputStream is = null;
OutputStream os = null;
StringBuffer stringBuffer = new StringBuffer();
try {
connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("IF-Modified-Since","20 Jan 2001 16:19:14 GMT");
connection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Confirguration/CLDC-1.0");
connection.setRequestProperty("Content-Language", "en-CA");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
os = connection.openOutputStream();
is = connection.openDataInputStream();
int ch;
while ((ch = is.read()) != -1) {
stringBuffer.append((char) ch);
}
res = stringBuffer.toString() ;
System.out.println(res);
//textBox = new TextBox("Simple GET Test", stringBuffer.toString(), 1024, 0);
}
catch(Exception e ){
}
finally {
try{
if(is!= null) {
is.close();
}
if(os != null) {
os.close();
}
if(connection != null) {
connection.close();
}
//display.setCurrent(textBox);
}
catch(Exception e ){
}
}
}
void sendSMS(String action,String url) {
HttpConnection connection = null;
InputStream is = null;
OutputStream os = null;
StringBuffer stringBuffer = new StringBuffer();
//TextBox textBox = null;
try {
connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("IF-Modified-Since","20 Jan 2001 16:19:14 GMT");
connection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Confirguration/CLDC-1.0");
connection.setRequestProperty("Content-Language", "en-CA");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
os = connection.openOutputStream();
is = connection.openDataInputStream();
int ch;
while ((ch = is.read()) != -1) {
stringBuffer.append((char) ch);
}
res = stringBuffer.toString() ;
System.out.println(res);
//textBox = new TextBox("Simple GET Test", stringBuffer.toString(), 1024, 0);
}
catch(Exception e ){
}
finally {
try{
if(is!= null) {
is.close();
}
if(os != null) {
os.close();
}
if(connection != null) {
connection.close();
}
//display.setCurrent(textBox);
}
catch(Exception e ){
}
}
}
public void run(){
//http://message url?user=mu&password=my&from=Muyiwa&to=23475061254040&message=i+love+this.
System.out.println(Thread.currentThread().toString() + " is running...") ;
if (action.equals("login")){
System.out.println(action);
authenticate(action,url);
}
else if(action.equals("sendsms")) {
System.out.println(action);
sendSMS(action,url);
}
}
public void callURL(){
HttpConnection c = null;
InputStream is = null;
StringBuffer sb = new StringBuffer();
try{
System.out.println(url);
//url = (urle.encode(url,"UTF-8"));
//System.out.println(url);
c = (HttpConnection)Connector.open(url, Connector.READ_WRITE, true);
c.setRequestMethod(HttpConnection.POST); //default
is = c.openInputStream(); // transition to connected!
int ch = 0;
for(int ccnt=0; ccnt < 150; ccnt++) { // get the title.
ch = is.read();
if (ch == -1){
break;
}
sb.append((char)ch);
}
res = sb.toString();
}catch(Exception e){
e.printStackTrace();
}
}
public String getRes() {
return res;
}
public void setRes(String res) {
this.res = res;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public URLEncoder getUrle() {
return urle;
}
public void setUrle(URLEncoder urle) {
this.urle = urle;
}
}
Ps could someone convert this to an android implementation. Currently facing a deadline

In android there are classes, HttpClient and DefaultHttpClient. So you make a web request using these.
Same as your code make a HttpGet request, And also in Like your J2ME code, instead of Thread class you can use AsyncTask (You can also use Thread, Handler but Asynctask is better to use) to perform a web request in Non-UI thread.
Example:
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
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;
}
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
Now from your Android activity code you have to just execute() this DownloadWebPageTask.
Like,
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { url });
For more information look at this Tutorial

Related

Android - Call Thread synchronized on UI thread

I try to create synchronized threads, but I always get the following error: android.os.NetworkOnMainThreadException.
I've read more posts, but they don't work for me.
Below I write the code blocks that do not work for me:
1.
final SyncApp syncJob = new SyncApp();
Thread t = new Thread (new Runnable () {
                         #Override
                         public void run () {
                             synchronized (syncJob) {
                                 String s = syncJob.insert (newJobs, GlobalVariables.URL_LOCALHOST + "jobs");
                                 txtState.setText (s);
                             }}});
                         }
                     });
                     t.Start ();
// t.run ();
2.
myClass.runOnUiThread(new Runnable() {
public void run() {...}
})
3.
Running code in main thread from another thread
SyncApp:
public class SyncApp {
synchronized public String insert(List<Jobs> job, String... params) {
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
String str = new Gson().toJson(job);
byte[] outputInBytes = str.getBytes();
OutputStream os = conn.getOutputStream();
os.write( outputInBytes );
os.flush();
int responseCode=conn.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line=br.readLine()) != null) {
response+=line;
}
}
else {
response=conn.getResponseMessage();
}
return response;
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
}
return null;
}
}
I need to call a thread, wait for the answer and call another thread. Their answers I must use them in the activity
I need to call a thread, wait for the answer and call another thread.
Their answers I must use them in the activity
Example using async tasks to accomplish objective.
In this code, let A be your activity which needs to call a thread,
wait for the answer and call another thread. Customize as needed.
Since you never wait in UI threads, callbacks are used to accomplish synchronization.
Let A be your activity class:
public class A extends Activity {
// some method in activity where you launch a background thread (B)
// which then completes and invokes callback which then creates and launches
// a background thread (C) which then completes and invokes a callback.
//
// In callback C, you are on the UI thread.
protected void someMethod() {
new B(new B.CallbackB() {
public void result(Object o) {
new C(new C.CallbackC() {
public void result(Object o, Object answerFromB) {
// OK - C is now done and we are on UI thread!
// 'o' is answer from C
// 'answerFromB' also provided
}
}, o).execute(new Object());
}
).execute(new Object());
}
}
Define a class B:
public class B extends AsyncTask<Object, Void, Object> {
public static interface CallbackB {
void result(Object o);
}
private CallbackB cb;
public B (CallbackB cb) {
this.cb = cb;
}
protected Object doInBackground(Object... params) {
// do work and return an answer.
return new Object();
}
protected void onPostExecute(Object result) {
if (cb != null) {
cb.result(result);
}
}
}
Define a class C:
public class C extends AsyncTask<Object, Void, Object> {
public static interface CallbackC {
void result(Object o, Object answerFromB);
}
private CallbackC cb;
private Object answerFromB;
public C (CallbackC cb, Object answerFromB) {
this.cb = cb;
this.answerFromB = answerFromB;
}
protected Object doInBackground(Object... params) {
// do work and return an answer.
return new Object();
}
protected void onPostExecute(Object result) {
if (cb != null) {
cb.result(result, answerFromB);
}
}
}
For reference:
https://stackoverflow.com/a/9963705/2711811
My solution is:
public class Sync extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync_server);
dao = new DAO(this);
txtState = findViewById(R.id.txt_log);
btnSincro = findViewById(R.id.btn_sincro);
btnSincro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
countCall = 0;
callFlow();
}
});
btnHome = findViewById(R.id.btn_home);
btnHome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(SyncServerActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
private void callFlow() {
switch (countCall) {
case 0:
templates = toTemplate("url");
break;
case 1:
jobs = toJobs("url");
break;
case 2:
job = ... //select item
res = sendJobs(jobs, "url");
break;
default:
runOnUiThread(new Runnable() {
#Override
public void run() {
btnSincro.setEnabled(true);
txtState.append("\n\nEND");
}
});
}
}
private void nextStep() {
setText(txtState, "\nSync \n" + countCall + "/3");
countCall++;
callFlow();
}
private void setText(final TextView text, final String value) {
runOnUiThread(new Runnable() {
#Override
public void run() {
text.setText(value);
}
});
}
public List<Templates> toTemplate(final String... params) {
final List<Templates> list = new ArrayList<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
try {
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
int responseCode = connection.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("data");
for (int i = 0; i < parentArray.length(); i++) {
Templates item = new Gson().fromJson(parentArray.get(i).toString(), Templates.class);
list.add(item);
}
} else {
response = connection.getResponseMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
nextStep(); //call next Thread
}
}
});
t.start();
return list;
}
public List<Jobs> toJobs(final String... params) {
final List<Jobs> list = new ArrayList<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
BufferedReader reader = null;
HttpURLConnection connection = null;
try {
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
int responseCode = connection.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("data");
for (int i = 0; i < parentArray.length(); i++) {
Jobs item = new Gson().fromJson(parentArray.get(i).toString(), Jobs.class);
list.add(item);
}
} else {
response = connection.getResponseMessage();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
nextStep();
}
}
});
t.start();
return list;
}
public Boolean sendJobs(final List<Jobs> job, final String... params) {
final Boolean[] result = {false};
Thread t = new Thread(new Runnable() {
#Override
public void run() {
URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
String str = new Gson().toJson(job);
Log.d(TAG, str);
byte[] outputInBytes = str.getBytes();
OutputStream os = conn.getOutputStream();
os.write(outputInBytes);
os.flush();
int responseCode = conn.getResponseCode();
String response = null;
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
result[0] = true;
} else {
response = conn.getResponseMessage();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
conn.disconnect();
nextStep();
}
}
});
t.start();
return result[0];
}
}
Whenever a thread ends, it calls the nextStep() method, which starts the next trhead.

Sending data from esp8266 to android app

I'm simply trying to send String text from my android app to Nodemcu esp8266 and the esp8266 response with another text.
I can receive the text on esp8266 but on android app I'm not get any response text! and I don't knew what is the problem.
my android code is
public class MainActivity extends Activity {
TextView textResponse;
Button buttonConnect;
EditText welcomeMsg;
String IpAddress = "192.168.0.117";
int Port = 8090;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonConnect = (Button) findViewById(R.id.connect);
textResponse = (TextView) findViewById(R.id.response);
welcomeMsg = (EditText)findViewById(R.id.welcomemsg);
buttonConnect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
MyClientTask myClientTask = new MyClientTask(welcomeMsg.getText().toString());
myClientTask.execute();
}
});
}
#SuppressLint("StaticFieldLeak")
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String response = "";
String msgToServer;
MyClientTask(String msgTo) {
msgToServer = msgTo;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(IpAddress, Port);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
if(!msgToServer.equals(""))
dataOutputStream.writeUTF(msgToServer + "$");
response = dataInputStream.readUTF();
} catch (IOException e) { }
finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
my esp8266 code is
#include <ESP8266WiFi.h>
WiFiServer server(8090);
IPAddress ip(192, 168, 0, 117);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
void setup() {
Serial.begin(115200);
WiFi.config(ip, gateway, subnet);
WiFi.begin("TP-LINK", "55555555");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
server.begin();
Serial.println("Connected");
}
void loop() {
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println(client.readStringUntil('$'));
String x = "esp8266";
client.println(x);
delay(100);
client.flush();
}
and this is how my app locks like
anyone have any idea?
use the code bellow to send data:
example: sendData("http://192.168.0.117:8090/data");
private void sendData(final String requestURL) {
reply = "";
new AsyncTask<Object, Void, String>() {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(Object... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(requestURL);
try {
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputstream = entity.getContent();
BufferedReader bufferedreader =
new BufferedReader(new InputStreamReader(inputstream));
StringBuilder stringbuilder = new StringBuilder();
String currentline = null;
while ((currentline = bufferedreader.readLine()) != null) {
stringbuilder.append(currentline + "\n");
}
String result = stringbuilder.toString();
reply = result;
inputstream.close();
}
} catch (NetworkOnMainThreadException ne) {
String err = (ne.getMessage() == null) ? "Network" : ne.getMessage();
reply = err;
} catch (MalformedURLException me) {
String err = (me.getMessage() == null) ? "Malform" : me.getMessage();
reply = err;
} catch (ProtocolException pe) {
String err = (pe.getMessage() == null) ? "Protocol" : pe.getMessage();
reply = err;
} catch (IOException ioe) {
String err = (ioe.getMessage() == null) ? "IOError" : ioe.getMessage();
reply = err;
}
return reply;
}
#Override
protected void onPostExecute(String result) {
Log.v(reply);
}
}.execute();
}

Convert AsyncTask to RxJava

Bit new to Rx, so am looking for some help on converting the following AsyncTask to Rx, hopefully so I can visualize Rx a bit more with code that I already know that does something. I've found a few other SO answers that were somewhat relevant, but alot of them werent network requests and many used different operators for different answers, so am a bit confused.
Heres the AsyncTask:
Here is my Java code for an WhatsTheWeather App(all code from the MainActivity is included):
public class MainActivity extends AppCompatActivity {
EditText cityName;
TextView resultTextview;
public void findTheWeather(View view){
Log.i("cityName", cityName.getText().toString());
InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(cityName.getWindowToken(), 0);
try {
String encodedCityName = URLEncoder.encode(cityName.getText().toString(), "UTF-8");
DownLoadTask task = new DownLoadTask();
task.execute("http://api.openweathermap.org/data/2.5/weather?q=" + cityName.getText().toString() + "&appid=a018fc93d922df2c6ae89882e744e32b");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cityName = (EditText)findViewById(R.id.cityName);
resultTextview = (TextView) findViewById(R.id.resultTextView);
}
public class DownLoadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while(data != -1){
char current = (char) data;
result +=current;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
String message = "";
JSONObject jsonObject = new JSONObject(result);
String weatherInfo = jsonObject.getString("weather");
Log.i("Weather content", weatherInfo);
JSONArray arr = new JSONArray(weatherInfo);
for(int i=0; i<arr.length(); i++){
JSONObject jsonPart = arr.getJSONObject(i);
String main = "";
String description="";
main = jsonPart.getString("main");
description = jsonPart.getString("description");
if(main != "" && description != ""){
message += main + ": "+ description + "\r\n"; //for a line break
}
}
if (message != ""){
resultTextview.setText(message);
} else {
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
}
}
Try this.
public void networkCall(final String urls) {
Observable.fromCallable(new Func0<String>() {
#Override
public String call() {
String result = "";
URL url = null;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
try {
String message = "";
JSONObject jsonObject = new JSONObject(result);
String weatherInfo = jsonObject.getString("weather");
Log.i("Weather content", weatherInfo);
JSONArray arr = new JSONArray(weatherInfo);
for (int i = 0; i < arr.length(); i++) {
JSONObject jsonPart = arr.getJSONObject(i);
String main = "";
String description = "";
main = jsonPart.getString("main");
description = jsonPart.getString("description");
if (main != "" && description != "") {
message += main + ": " + description + "\r\n"; //for a line break
}
}
return message;
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Could not find weather", Toast.LENGTH_LONG).show();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(String message) {
if (message != ""){
resultTextview.setText(message);
} else {
Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
}
}
});
}
But, i would recommend to use Retrofit and RxJava together.
There are couple of things you should know before integrating Retrofit.
Try not to use the older version of Retrofit
Retrofit2 is the one which you are supposed to use at current
Try avoiding code integration of Retrofit with RxJava or RxAndroid
at current(Too much complexity for beginner)
Make sure you are familiar with GSON or Jackson too.
HttpClient is depreciated while OkHttp is comparatively faster than HttpUrlConnection which is generally used by Retrofit2
Finally, here the link for the Retrofit2. It is well detailed and easy to understand. Jack Wharton has tried his best to make it simple to understand as possible.

android get url from edit text and use it in rest api to upload data

Here is my android rest request code but the where i get the url from edit text using its id but "getString" gets flagged(can't be resolved). Please help
class RESTRequest
{
//final String ADD_STROKE_URL = "";
final String ADD_STROKE_URL = new String[]{ getString(R.id.buttonUploadURL)};
public Boolean success = null;
private JSONObject params;
private String strokeId;
private HashSet<Point> localPoints;
private StrokeManagerCallback callback;
public static String encode(Object x) {
try {
return URLEncoder.encode(String.valueOf(x),"UTF-8");
} catch (UnsupportedEncodingException e) {
return(String.valueOf(x));
}
}
public RESTRequest(JSONObject params,String strokeId,Set<Point> points,StrokeManagerCallback callback)
{
this.params = params;
this.strokeId = strokeId;
this.localPoints = new HashSet<Point>();
this.localPoints.addAll(points);
this.callback = callback;
new ExecuteREST().execute();
}
private class ExecuteREST extends AsyncTask<Void, Void, String>
{
protected String doInBackground(Void ...arg0)
{
/* Build URL query */
StringBuffer local = new StringBuffer(ADD_STROKE_URL);
if(params != null)
{
local.append("?");
Iterator<?> k = params.keys();
while(k.hasNext()){
try {
String key = (String) k.next();
Object value = params.get(key);
local.append(encode(key));
local.append("=");
local.append(encode(value));
if(k.hasNext()){
local.append("&");
}
}
catch (JSONException e) {e.printStackTrace();}
}
}
HttpURLConnection urlConn = null;
StringBuffer response = new StringBuffer("error");
try
{
URL url = new URL(local.toString());
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setRequestMethod("GET");
urlConn.setDoInput(true);
urlConn.setUseCaches(false);
urlConn.setRequestProperty("Content-Type", "application/json");
urlConn.connect();
//Get Response
InputStream is = urlConn.getInputStream();
BufferedReader rd = new BufferedReader(newInputStreamReader(is));
String line;
response = new StringBuffer();
try{
while((line = rd.readLine()) != null) {
response.append(line);
}
}
finally{
if(urlConn != null){
urlConn.disconnect();
urlConn = null;
}
if(rd != null){
rd.close();
rd = null;
}
}
if(callback != null){
callback.onSuccess(strokeId, localPoints);
}
} catch (ConnectException e) {
callback.onFailure(strokeId, localPoints);
} catch (UnknownHostException e) {
callback.onFailure(strokeId, localPoints);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (EOFException e) {
response = new StringBuffer("No response from server");
} catch (IOException e) {
e.printStackTrace();
} catch (RuntimeException e) {
e.printStackTrace();
}
finally{
if(urlConn != null){
urlConn.disconnect();
}
}
return response.toString();
}
}
you can get String Resources like this
Resources res = context.getResources();
final String ADD_STROKE_URL = new String[]{ res.getString(R.id.buttonUploadURL)};
and now you can pass that url in AcycncTask class like this
public RESTRequest(JSONObject params,String
strokeId,Set<Point>points,StrokeManagerCallback callback){
this.params = params;
this.strokeId = strokeId;
this.localPoints = new HashSet<Point>();
this.localPoints.addAll(points);
this.callback = callback;
new ExecuteREST(/*Pass url here that you will get in doInBackground method */)
.execute();
}
private class ExecuteREST extends AsyncTask<String, Void, String>{
protected String doInBackground(String ...arg0){
//get your url in arg0 variable
StringBuffer local = new StringBuffer(arg0[0]);
.
.
.
//Rest of yours ...

Using Azure Bing Search API in Android

I am trying to make an app which executes an image search and displays the image results in a grid. Since the Google Image Search API is deprecated and will no longer be available shortly, I am trying to use the Bing Search API.
However, I am getting the following error:
java.io.IOException: No authentication challenges found
at libcore.net.http.HttpURLConnectionImpl.getAuthorizationCredentials(HttpURLConnectionImpl.java:427)
at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:407)
at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:356)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:292)
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
I am following the example in http://learn-it-stuff.blogspot.com/2012/09/using-bing-custom-search-inside-your.html. If anyone has experienced this issue, or can help me out, that would be much appreciated. Thanks!
Here is my code thus far:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AsyncTask <Void, Void, Void> task = new AsyncTask <Void, Void, Void> () {
protected Void doInBackground(Void... args) {
// Uri uri = Uri.parse("https://www.google.com/search?tbm=isch&q=penguin");
// Intent intent = new Intent(Intent.ACTION_VIEW, uri);
// startActivity(intent);
/*-------------------------Bing search-------------------------*/
String searchText = "Hello World";
searchText = searchText.replace(" ", "%20");
String accountKey = "MY_APP_ID";
accountKey = accountKey.replace("+", "%2B");
byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes());
String accountKeyEnc = new String(accountKeyBytes);
URL url;
try {
url = new URL(
"https://api.datamarket.azure.com/Bing/Search/v1/"
+ "Image?Query=%27" + searchText + "%27");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Authorization", "Basic " + accountKeyEnc);
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
StringBuilder sb = new StringBuilder();
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
sb.append(output);
}
conn.disconnect();
System.out.println(sb);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
task.execute();
}
}
The following code worked for me:
public class SearchAsyncTask extends AsyncTask<Void, Void, Void> {
private final String TAG = getClass().getName();
private String mSearchStr;
private int mNumOfResults = 0;
private Callback mCallback;
private BingSearchResults mBingSearchResults;
private Error mError;
public SearchAsyncTask(String searchStr, int numOfResults, Callback callback) {
mSearchStr = searchStr;
mNumOfResults = numOfResults;
mCallback = callback;
}
#Override
protected Void doInBackground(Void... params) {
try {
String searchStr = URLEncoder.encode(mSearchStr);
String numOfResultsStr = mNumOfResults <= 0 ? "" : "&$top=" + mNumOfResults;
String bingUrl = "https://api.datamarket.azure.com/Bing/SearchWeb/v1/Web?Query=%27" + searchStr + "%27" + numOfResultsStr + "&$format=json";
String accountKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes());
String accountKeyEnc = new String(accountKeyBytes);
URL url = null;
url = new URL(bingUrl);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + accountKeyEnc);
InputStream response = urlConnection.getInputStream();
String res = readStream(response);
Gson gson = (new GsonBuilder()).create();
mBingSearchResults = gson.fromJson(res, BingSearchResults.class);
Log.d(TAG, res);
//conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
mError = new Error(e.getMessage(), e);
//Log.e(TAG, e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (mCallback != null) {
mCallback.onComplete(mBingSearchResults, mError);
}
}
private String readStream(InputStream in) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
//System.out.println(line);
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
public interface Callback {
void onComplete(Object o, Error error);
}
}
To parse the result:
public class BingSearchResults {
public ResultsContent d;
public static class ResultsContent {
public Result[] results;
public String __next;
}
public static class Result {
public String ID;
public String Title;
public String Description;
public String DisplayUrl;
public String Url;
public Metadata __metadata;
}
public static class Metadata {
public String uri;
public String type;
}
public Result[] getResults(){
if (d == null)
return null;
return d.results;
}
public String getNextUrl(){
if (d == null)
return null;
return d.__next;
}
public boolean isEmpty(){
return (d == null || d.results == null || d.results.length == 0);
}
public int size(){
if (d == null || d.results == null)
return 0;
return d.results.length;
}
}
You also need to include the external jars commons-codec-1.9.jar and gson-2.2.4.jar
Little bit change occur in this code sometimes compilation bug of encoder generate problem byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes());

Categories

Resources