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
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments