I am Authorizing an Alexa android application , using the below code .
How can I get profile information from the below code ?
private static final String[] APP_SCOPES= {"alexa:all"};
String PRODUCT_DSN = Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.ANDROID_ID);
Bundle options = new Bundle();
String scope_data = "{\"alexa:all\":{\"productID\":\"" + mProductId +
"\", \"productInstanceAttributes\":{\"deviceSerialNumber\":\"" +
PRODUCT_DSN + "\"}}}";
options.putString(AuthzConstants.BUNDLE_KEY.SCOPE_DATA.val, scope_data);
options.putBoolean(AuthzConstants.BUNDLE_KEY.GET_AUTH_CODE.val, true);
options.putString(AuthzConstants.BUNDLE_KEY.CODE_CHALLENGE.val, getCodeChallenge());
options.putString(AuthzConstants.BUNDLE_KEY.CODE_CHALLENGE_METHOD.val, "S256");
options.putBoolean(AuthzConstants.BUNDLE_KEY.PROFILE.val, true);
mAuthManager.authorize(APP_SCOPES, options, authListener);
Finally i found the answer , Need Fetch the access token, then call the api:
https://api.amazon.com/user/profile
Header: Authorization", Bearer
access_token
Eg :
String url = "https://api.amazon.com/user/profile";
OkHttpClient client = ClientUtil.getTLS12OkHttpClient();
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer " + access_token)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, final IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String s = response.body().string();
}
});
Related
I have the following code working perfectly in Python:
login_data = {'identifier': 'something#email.com', 'password': 'Password'}
url = "https://www.duolingo.com/2017-06-30/login?fields="
p = requests.post(url, data = json.dumps(login_data))
if p.status_code is 200:
print("SUCCESS")
else:
print("ERROR")
I want to convert it to Java using OkHttp to be able to implement it in Android Studio.
I have written the following code but it gives Status Code: 422 which according to Google means Unprocessable Entity:
OkHttpClient client = new OkHttpClient();
String url = "https://www.duolingo.com/2017-06-30/login?fields=";
String login_data = "{\"identifier\": \"something#email.com\", \"password\": \"Password\"";
RequestBody body = RequestBody.create(login_data, MediaType.parse("application/json"));
Request postRequest = new Request.Builder()
.url(url)
.post(body)
.build();
client.newCall(postRequest).enqueue(new Callback()
{
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e)
{
Log.i("TAG", "ERROR - " + e.getMessage());
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException
{
if (response.isSuccessful())
{
Log.i("LOG", "SUCCESS - " + response.body().string());
}
else
{
Log.i("LOG", "FAILED. Status Code: " + String.valueOf(response.code));
}
}
});
All help is appreciated!
You have a missing closing bracket in the request body at java implementation.
"{\"identifier\": \"something#email.com\", \"password\": \"Password\"}"
I use OkHttp for requests to my raspberry. I am thinking about putting the requests in a separate class.
Currently I have one method to send requests. The code is as follows:
private void sendRequest(String url, JSONObject json) {
Log.d(TAG, "sendRequest: Das Json: " + json);
// Authentication for the request to raspberry
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic("username", "password");
return response.request().newBuilder()
.header("Authorization", credential)
.build();
}
});
// Sending out the request to the raspberry
OkHttpClient okHttpClient = client.build();
RequestBody body = RequestBody.create(null, new byte[]{});
if( json != null) {
body = RequestBody.create(MediaType.parse(
"application/json"),
json.toString()
);
}
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d(LOG, "Big Fail");
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
ResponseBody responseBody = response.body();
if( !response.isSuccessful() ) {
Log.d(TAG, "onResponse: We are in !response.successful()");
throw new IOException("Response not successful: " + response );
}
Log.d(LOG, "onResponse: Response is: " + responseBody.string());
} catch (Exception e) {
e.printStackTrace();
Log.d(LOG, "onResponse: failed!" + e);
}
}
});
}
Here is an example how the sendRequest() function is called:
private void makePremixCall(Premix premix) {
JSONArray jsonArray = new JSONArray();
ArrayList<Premixable> usedPremixables = premix.getUsedPremixables();
for(Premixable usedPremixable: usedPremixables) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("Silo", usedPremixable.getmSilo());
jsonObject.put("Gramm", usedPremixable.getmKgPerCow() * mFeeding.getmNumberOfCows());
jsonArray.put(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("Components", jsonArray);
sendRequest("http://192.168.178.49:5000/evaluatePost", jsonObject);
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "makePremixCall: " + e);
}
}
My problem with this: I would like to have a separate class, which offers the function makePremix(Premix premix) and other functions that I need.
The only solution that comes to my mind is implementing the requests synchronously in the separate class and call that separate class in an AsyncTask in the class I am working in.
Do I oversee something? Is there a way to create a separate class and still use the OkHttp enqueue method?
You could extract makePremix(Premix premix) in a separate class and make sendRequest() public (or maybe package-private depending on your use case).
public void sendRequest(String url, JSONObject json)
However since sendRequest is generic and can be used by any other makeAnotherCall() in some other class you would need to get back result of every requests. Hence you can extract the Callback out of sendRequest()
public void sendRequest(String url, JSONObject json, Callback callback)
Now your sendRequest will look like
private void sendRequest(String url, JSONObject json) {
Log.d(TAG, "sendRequest: Das Json: " + json);
// Authentication for the request to raspberry
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic("username", "password");
return response.request().newBuilder()
.header("Authorization", credential)
.build();
}
});
// Sending out the request to the raspberry
OkHttpClient okHttpClient = client.build();
RequestBody body = RequestBody.create(null, new byte[]{});
if( json != null) {
body = RequestBody.create(MediaType.parse(
"application/json"),
json.toString()
);
}
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
okHttpClient.newCall(request).enqueue(callback);
}
Hope it makes sense!
Also as a side note, see that you are creating a new OkHttp Client every time you call sendRequest. You could probably optimise memory here by caching the client and reusing it.
I'm running OkHTTP3 on Android Lollipop and I have the following static method to upload an image in a multipart form request:
public static void uploadImage(Context context, String imageTitle, Uri imageUri, CallbackReceiver callbackReceiver) {
ContentResolver contentResolver = context.getContentResolver();
MimeTypeMap mime = MimeTypeMap.getSingleton();
String type = mime.getExtensionFromMimeType(contentResolver.getType(imageUri));
String filePath = imageUri.toString();
String fileName = imageUri.getLastPathSegment();
File file = new File(filePath);
MediaType mediaType = MediaType.parse(type);
RequestBody rb = RequestBody.create(mediaType, file);
requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", fileName, rb)
.build();
Request request = new Request.Builder()
.url(RequestConstants.POST_IMAGE)
.addHeader(
RequestConstants.HTTP_HEADER_AUTHORIZATION,
RequestConstants.HTTP_AUTHORIZATION_PREFIX +
AccessToken.get())
.addHeader(
RequestConstants.HTTP_HEADER_ACCEPT,
RequestConstants.HTTP_APPLICATION_JSON)
.post(requestBody)
.build();
run(request, callbackReceiver);
The RequestConstants are String values that work in other GET and POST requests.
The run method implementation:
private static OkHttpClient client = new OkHttpClient();
private static void run(Request request, final CallbackReceiver callbackReceiver) {
try {
client.newCall(request).enqueue(new Callback() {
#Override
public void onResponse(Call call, Response response) throws IOException {
callbackReceiver.onSuccess(response);
}
#Override
public void onFailure(Call call, IOException e) {
callbackReceiver.onFailure(e);
}
});
} catch (Exception e) {
Log.e("OkHttpClient", e.getMessage());
}
}
Whenever I run the request, I never receive an answer - neither the onSuccess nor the onFailure callbacks are executed.
In Logcat I can see that there are several 'suspending all threads', which could indicate a performance issue, although I am testing with a very small image (~250kB).
Any idea what could be causing this?
I solved this a while ago. To make sure it's not left unanswered: I increased the timeout on the client. I was unable to find the piece of code that fixed it.
I'm using the GettyImages API: http://developers.gettyimages.com/api/docs/v3/search/images/get/
I'm getting Account Inactive as the response.In the Dashboard my Status is Active
Can't figure out what's wrong
Here's the code:
String mySearch = "football";
HashMap<String, String> header = new HashMap<String, String>();
header.put("API_KEY", API_KEY);
String url = "https://api.gettyimages.com/v3/search/images?phrase=football";
if (isNetworkAvailable()) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.header("API_KEY", API_KEY)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
alertUserAboutError();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
String jsonData = response.body().string();
Log.v("Response: ", jsonData);
}
catch (IOException e)
{
e.printStackTrace();
Log.d("Exception Caught: ",e.toString());
}
}
});
If your API Key is correct,
then you're missing request Authorization header.
See the Getty github project for reference:
https://github.com/gettyimages/gettyimages-api_java
I'm trying to implement the Reddit oAuth2 (every app that utilizes Reddit content has to have this implemented) in Android based 'userless' application and I'm following the guidelines.
I registered an app and get the respective client_id.
I'm following this for API guidelines and this for Retrofit in order to properly write the Android code.
Hence, I've coded two approaches to the issue and it seems that neither works. The call in the appropriate Fragment is the same for the two options and it goes as follows:
public void oAuth(){
String bodyString = "grant_type=" + "https://oauth.reddit.com/grants/installed_client"
+ "&device_id=" + UUID.randomUUID().toString();
TypedInput requestBody = new TypedByteArray("application/x-www-form-urlencoded", bodyString.getBytes(Charset.forName("UTF-8")));
RedditAPI.sRedditAuth().redditAuth(requestBody, new Callback<TokenResponse>() {
#Override
public void success(TokenResponse tokenResponse, Response response) {
Log.d("OATH_TAG", "oAuth() | YAY! :)");
}
#Override
public void failure(RetrofitError error) {
Log.d("OATH_TAG", "oAuth() | NOOOOOoooooo.... :(");
}
});
}
OPTION 1:
the Retrofit interface:
public interface RedditAuthInterface {
#POST(Urlz.REDDIT_OATH2_PATH)
void redditAuth(#Body TypedInput body, Callback<TokenResponse> result);
}
//the adapter
public static RedditAuthInterface sRedditAuth() {
if (sRedditAuthInterface == null) {
RestAdapter restAdapter = new RestAdapter
.Builder()
.setClient(getAuthClient())
.setEndpoint(Urlz.BASE_REDDIT_URL)
.build();
sRedditAuthInterface = restAdapter.create(RedditAuthInterface.class);
}
return sRedditAuthInterface;
}
/* support methods */
private static OkClient getAuthClient() {
final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(Static.READ_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(Static.CONNECT_TIMEOUT, TimeUnit.SECONDS);
/*okHttpClient.setAuthenticator(new Authenticator() {
#Override
public Request authenticate(Proxy proxy, Response response) throws IOException {
String credential = Credentials.basic(BldCnfg.REDDIT_CLIENT_ID, BldCnfg.REDDIT_PASS);
return response.request().newBuilder().header("Authorization", credential).build();
}
#Override
public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
return null;
}
});*/
okHttpClient.networkInterceptors().add(OAUTH_INTERCEPTOR);
return new OkClient(okHttpClient);
}
private static final Interceptor OAUTH_INTERCEPTOR = new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
String credentials = BldCnfg.REDDIT_CLIENT_ID + ":" + BldCnfg.REDDIT_PASS; // REDDIT_PASS = "" as by API guides
String string = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
originalResponse.header("Authorization", string);
originalResponse.header("Accept", "application/json");
return originalResponse;
}
};
result:
RetrofitError: 401 Unauthorized
OPTION 2:
the Retrofit interface:
public interface RedditAuthInterface {
#POST(Urlz.REDDIT_OATH2_PATH)
void redditAuth(#Body TypedInput body, Callback<TokenResponse> result);
}
//the adapter
public static RedditAuthInterface sRedditAuth() {
if (sRedditAuthInterface == null) {
RestAdapter restAdapter = new RestAdapter
.Builder()
.setClient(getConfuguredClient())
.setRequestInterceptor(getRequestInerceptorPass())
.setEndpoint(Urlz.BASE_REDDIT_URL)
.build();
sRedditAuthInterface = restAdapter.create(RedditAuthInterface.class);
}
return sRedditAuthInterface;
}
/* support methods */
public static RequestInterceptor getRequestInerceptorPass() {
RequestInterceptor rqInter = new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
String credentials = BldCnfg.REDDIT_CLIENT_ID + ":" + BldCnfg.REDDIT_PASS; // REDDIT_PASS = "" as by API guides
String string = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
request.addHeader("Authorization", string);
request.addHeader("Accept", "application/json");
}
};
return rqInter;
}
private static OkClient getConfuguredClient() {
final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(Static.READ_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(Static.CONNECT_TIMEOUT, TimeUnit.SECONDS);
return new OkClient(okHttpClient);
}
result:
It seems that I'm getting empty response (I only get "*" for scope). The successful response looks like this:
and header like this:
Do you have any ideas what am I doing wrong?
Has anybody done this?
The official Reddit github wiki lacks Android examples (has in almost every other language, though).
I was going through the same problem before and make this library to handel OAuth2 in Android. and the library is an extension for Retrofit that simplifies the process of authenticating against an OAuth 2 provider.
Based on your image with the "empty" response, showing that you got * back as a scope, I suspect that your definition for the access token response is using camel case instead of snake case, so the JSON is not getting loaded properly into the Java object.