I have implement insert rating method in my app . I am searching more than 1 days to get the response . In this page i have check that insert like method and json is giving response . Look .
But i don't find any way to get the response in my app . How can i solve this ?
#SuppressLint("StaticFieldLeak")
class Insert extends AsyncTask<Object,Object, Object> {
#Override
protected Object doInBackground(Object... objects) {
if (Email!=null){
mCredential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(YouTubeScopes.YOUTUBE))
.setBackOff(new ExponentialBackOff());
mCredential.setSelectedAccountName(Email);
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
YouTube youtubeService = new YouTube.Builder(
transport, jsonFactory, mCredential)
.setApplicationName(LikeInsertActivity.this.getResources().getString(R.string.app_name))
.build();
// Define and execute the API request
try {
YouTube.Videos.Rate request = youtubeService.videos()
.rate(VID, "like");
request.execute();
runOnUiThread(new Runnable() {
public void run() {
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
As #mavriksc mentions Rate.execute() returns Void. This is due to the fact that all these object are based on the superclass
com.google.api.services.youtube.YouTubeRequest<java.lang.Void>
However instead of the execute method you can use other methods defined by AbstractGoogleClientRequest which is a super class of YouTubeRequest.
For example executeUnparsed returns a com.google.api.client.HttpResponse object.
So obtaining that HttpResponse object and checking the StatusCode vs 204 seems to be the solution you want to have.
Example:
try {
final YouTube.Videos.Rate request = youtubeService.videos().rate(VID, "like");
runOnUiThread(new Runnable() {
public void run() {
HttpResponse response = request.executeUnparsed();
// There should be a matching constant for 204 defined somewhere, I haven't found it yet
if (response.getStatusCode() == 204) {
// request successfull
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
Note:
Android forces developers to do certain (time consuming) things (like NetworkCommunication) in a background task to prevent the UI from blocking.
The return type of Rate.execute() is Void. looking at the HTTP it seems like you get a 204 no content on a good response and an exception otherwise.
https://developers.google.com/youtube/v3/docs/videos/rate
Related
Im trying to refresh an Access token in my application following this solution.
My actual problem is handling the callback and then return the new request in the authenticate method.
I tried using an interface to return a String from my callback method but then I cant assign it to a variable, nor can I return the new request from there since its inside my onResponseListener.
How can I solve this issue?
public Request authenticate(Route route, Response response) throws IOException {
// GetAuthRequest is a void method, and I cant assign a String value on the callback.
getAuthRequest(new AuthResponse() {
#Override
public Request onSuccess(String token) {
return response.request().newBuilder()
.header("Authorization", "Bearer " + token)
.build();
}
});
I was using an Asynchronous call instead of Synchronous. Ended up making a method that returns an String like so:
private String getAuthRequest() {
// Make the request above
try (Response response = httpClient.newCall(request).execute()) {
JSONObject jsonObject = new JSONObject(response.body().string());
return jsonObject.getString("access_token");
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return null;
}
I have been trying to use this cordova plugin, which uses NanoHttpd to handle requests.
By default, Nanohttpd handles some of the HTTP methods, like GET, POST, CONNECT, PROPFIND, PATCH, etc.
I have been trying to figure out how to implement a custom handler so that nanohttpd can handled more HTTP methods like: NOTIFY and SUBSCRIBE
#Override
public Response serve(IHTTPSession session) {
Log.d(this.getClass().getName(), "New request is incoming!");
String requestUUID = UUID.randomUUID().toString();
PluginResult pluginResult = null;
try {
pluginResult = new PluginResult(
PluginResult.Status.OK, this.createJSONRequest(requestUUID, session));
} catch (JSONException e) {
e.printStackTrace();
}
pluginResult.setKeepCallback(true);
this.webserver.onRequestCallbackContext.sendPluginResult(pluginResult);
while (!this.webserver.responses.containsKey(requestUUID)) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
JSONObject responseObject = (JSONObject) this.webserver.responses.get(requestUUID);
Log.d(this.getClass().getName(), "responseObject: " + responseObject.toString());
Response response = null;
try {
response = newFixedLengthResponse(
Response.Status.lookup(responseObject.getInt("status")),
getContentType(responseObject),
responseObject.getString("body")
);
Iterator<?> keys = responseObject.getJSONObject("headers").keys();
while (keys.hasNext()) {
String key = (String) keys.next();
response.addHeader(
key,
responseObject.getJSONObject("headers").getString(key)
);
}
} catch (JSONException e) {
e.printStackTrace();
}
return response;
}
I added a simple notify Response to handle any incoming request, referring from here - https://stackoverflow.com/a/27645191/2096740
public Response notify(IHTTPSession session) {
StringBuilder text = new StringBuilder("<html><body>");
text.append("<h1>Url: ");
text.append(session.getUri());
text.append("</h1><br>");
Map<String, String> queryParams = session.getParms();
if (queryParams.size() > 0) {
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
text.append("<p>Param '");
text.append(key);
text.append("' = ");
text.append(value);
text.append("</p>");
}
} else {
text.append("<p>no params in url</p><br>");
}
return newFixedLengthResponse(text.toString());
}
But this returnsBAD REQUEST: Syntax error. HTTP verb NOTIFY unhandled.
Documentation is not clear and there is not much info circulating on extending Nanohttpd behavior on SO or via web results.
What is the correct way to do this? How can I extend it ?
The check for Method is actually locked in an enum. It is hardcoded and there is no other method to expand.
The getMethod instance itself is a enum type of Method.
Since, I couldn't find any other solution, I therefore conclude it is not possible to do this stuff in Nanohttpd. All its versions in Maven dont support this.
The reason they have
Some built-in support for HEAD, POST and DELETE requests. You can
easily implement/customize any HTTP method, though.
mentioned in their feature list is because the original version had method as a String. It has changed since.
Feature list not been updated to reflect this change.
I've been searching the simplest way to get Html code to String for some time now. I just need to fetch it so i can move forward with my project.
I tried:
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
String html= null;
try {
html = run("http://google.com");
} catch (IOException e) {
e.printStackTrace();
}
text.setText(html);
}
}
I got Error android.os.NetworkOnMainThreadException.
I just started developing in Android studio and I'm not an expert in Java either. I would like if someone would explain what i need to do, with examples preferably. thank you in advance
As #CommonsWare and #christian have already said, you need to make network operations in the background and for this aim Okhttp has a special method enqueue(). This will create a background thread for you and simplify your work.
In your case, change the lines inside run() method to these:
String run(String url) throws IOException {
String result = "";
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// failure case
}
#Override
public void onResponse(Call call, Response response) throws IOException {
// success case
result = response.body().string();
}
});
}
You need to make network operations in background thread otherwise, you will get the exceptions. Android make it mandatory because network call takes a bit time and the UI-Thread will freeze.
Please refer https://github.com/square/okhttp/wiki/Recipes#asynchronous-get
and https://stackoverflow.com/a/6343299/1947419
I am using AsyncInvoker using Jersey 2.0. This works fine for me. However, thread is not ending after completion of the return. Please note that I don't expect any response for the services I call.
public Future<Response> fire(WebTarget webTarget) {
Future<Response> response = null;
try {
response = webTarget.request(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE)
.headers(headers)
.async().get();
}
catch (Exception e) {
e.printStackTrace();
}
return response;
}
As long as you don't do anything with the actual javax.ws.rs.core.Response that is provided to you once the future value resolves, the request response stream is kept open (and the thread associated with it the raw HTTP request as wel I guess). You should either:
Do something with the javax.ws.rs.core.Response object and close it (or it's stream).
Use .get(MyPojo.class) to have the response steam converted into an actual object. This will close the stream for you and resolve a MyPojo instance in the future instead.
You need to close your client object that you created in the calling method. In the calling method you would have something like below -
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(SERVER_URL).path(API_PATH).path(String.valueOf(id));
fire(webTarget);
So you need to close your client after calling this method -
client.close()
However, the recommended way of closing client is after receiving response. Something like below -
public void fire(WebTarget webTarget) {
try {
webTarget.request(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE)
.headers(headers)
.async().get(new InvocationCallback<Response>() {
#Override
public void completed(Response response) {
// Do whatever your wish with response
client.close();
}
#Override
public void failed(Throwable throwable) {
throwable.printStackTrace();
client.close();
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}
I use this to config my retrofit:
RestAdapter restAdapter = new RestAdapter.Builder()
//add headers to requests
.setRequestInterceptor(getAuthenticatedRequestInterceptor())
.setEndpoint(BASE_URL)
.setConverter(new GsonConverter(getGson()))
.build();
and The getAuthenticatedRequestInterceptor() method adds headers to request:
public AccountRequestInterceptor getAuthenticatedRequestInterceptor() {
AccountRequestInterceptor interceptor = new AccountRequestInterceptor();
Map<String, String> headers = new HashMap<>();
String accessToken = null;
try {
accessToken = TokenProvider.getInstance(mContext).getToken();
} catch (InterruptedException e) {
}
headers.put(HeadersContract.HEADER_AUTHONRIZATION, O_AUTH_AUTHENTICATION + accessToken);
interceptor.setHeader(headers);
return interceptor;
}
getToken() method is:
private synchronized string getToken() throws InterruptedException {
if (!isRefreshing()) {
//This is very important to call notify() on the same object that we call wait();
final TokenProvider myInstance = this;
setRefreshing(true);
MyApplication.getRestClient().getAccountService().getRefreshedToken(mLoginData.getRefreshToken())
.subscribe(new Observer<LoginResponse>() {
#Override
public void onCompleted() {
synchronized (myInstance) {
setRefreshing(false);
myInstance.notifyAll();
}
}
#Override
public void onError(Throwable e) {
synchronized (myInstance) {
setRefreshing(false);
myInstance.notifyAll();
}
}
#Override
public void onNext(LoginResponse loginResponse) {
synchronized (myInstance) {
mLoginData = loginResponse;
mAccountProvider.saveLoginData(loginResponse);
myInstance.notifyAll();
}
}
});
}
this.wait();
return mLoginData.getToken();
}
The TokenProvider.getInstance(mContext).getToken() has a wait() on main thread to get the response from an async method and i know that is a bad thing to do but i need this here to wait for the response to take the token from it and then return the token.how can i do this in a separate thread to avoid waiting on the main thread?
Note:
1 - that this is called before any request with retrofit.
2 - I read this and i know i can refresh token after a fail request, but for business reasons i want to avoid having an invalid token.
3 - I call MyApplication.getRestClient().getAccountService().login(loginRequest,callback...) in my Activity and before adding token everything happened in background thread. so I want to use my token and do not block the main thread.
UPDATE: I added the following Interceptor to my new OkHttp:
public class RequestTokenInterceptor implements Interceptor {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Request newRequest;
try {
Log.d("addHeader", "Before");
String token = TokenProvider.getInstance(mContext).getToken();
if (token != null) {
newRequest = request.newBuilder()
.addHeader("Bearer", token)
.build();
} else {
// I want to cancel the request or raise an exception to catch it in onError method
// of retrofit callback.
}
} catch (InterruptedException e) {
Log.d("addHeader", "Error");
e.printStackTrace();
return chain.proceed(request);
}
Log.d("addHeader", "after");
return chain.proceed(newRequest);
}
}
Now how can i cancel the request or raise an exception to catch it in onError method of retrofit callback, if token is null?
It's a little bit strange issue but let me try to help you. :)
As you know you can refresh token after a failed request with retrofit using response interceptor.
Let's try to use interceptor before request.
public class RequestTokenInterceptor implements Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// Here where we'll try to refresh token.
// with an retrofit call
// After we succeed we'll proceed our request
Response response = chain.proceed(request);
return response;
}
}
And when you're creating your api create a new HttpClient:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new RequestTokenInterceptor());
And add your http client to your adapter like below:
.setClient(new OkClient(client))
If this works, before every request you'll try to refresh token first and then will proceed your api request. So in ui there'll be no difference with your normal api calls.
Edit:
I'm editing my answer too. If you want to return an error in else case if token null, in else case you can create your custom response:
private Response(Builder builder) {
this.request = builder.request;
this.protocol = builder.protocol;
this.code = builder.code;
this.message = builder.message;
this.handshake = builder.handshake;
this.headers = builder.headers.build();
this.body = builder.body;
this.networkResponse = builder.networkResponse;
this.cacheResponse = builder.cacheResponse;
this.priorResponse = builder.priorResponse;
}
or simply you can return a null response. if you build your custom response and set your code not to 200 such as 401 or 400+ you'll receive that response in Retrofit's callbacks failure method. Than you can do what ever you want.
If you return null you'll get a RuntimeException i think and still you can catch response in your callback's failure method.
After you create your own response in else you can create your custom callback and catch your null response and transform your custom error how ever you want like below:
public abstract class DefaultRequestCallback<T> implements Callback<T> {
public abstract void failure(YourCustomException ex);
public abstract void success(T responseBean);
#Override
public void success(T baseResponseBean, Response response) {
if (response == null) {
// Here we catch null response and transform it to our custom Exception
failure(new YourCustomException());
}
} else {
success(baseResponseBean);
}
}
#Override
public void failure(RetrofitError error) {
// Here's your failure method.
// Also you can transform default retrofit errors to your customerrors
YourCustomException ex = new YourCustomException();
failure(ex);
}
}
This can help you i think.
Edit 2:
You can build a new Response like below. There's a builder pattern in Retrofit's Response class. You can check it from there.
Response response = new Response.Builder().setCode(401).setMessage("Error Message").build();
You could make all long actions in AsyncTask doInBackground method, while in onPre- and onPostExecute you could show/hide some progress bars when user is waiting
Ok, I think if you are calling your getAuthenticatedRequestInterceptor() on the main thread and which in turns call getInstance(),in which i feel you would be creating an object of Type TokenProvider hence when you create this object in the main thread your object.wait() runs on main thread hence to run this on a background thread probably modify your getAuthenticatedRequestInterceptor() method to execute the following lines in a new thread.
try {
accessToken = TokenProvider.getInstance(mContext).getToken();
} catch (InterruptedException e) {
}
headers.put(HeadersContract.HEADER_AUTHONRIZATION, O_AUTH_AUTHENTICATION + accessToken);
interceptor.setHeader(headers);
return interceptor;
but this will have problems for notifying your RestAdapter as the main thread will proceed executing, hence i would suggest
you call getAuthenticatedRequestInterceptor() method first in a new thread and then notify your main thread to build your RestAdapter.This will free your main thread but with the strategy you are employing you will have to wait until you receive the token to make any calls.