Spotify Android - Make Authorized Web Requests - android

I'm working on an Android app that implements the Spotify API to allow the users to listen to music. I've configured the Player that Spotify has created for android devices, but it's incredibly limited in terms of its functionality, so I've had to go through Spotify's Web API to do more advanced features.
I've hit a bug when trying to get a list of the user's own playlists. I'm making a request using:
URL url = new URL("https://api.spotify.com/v1/me/playlists");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
But instead of this command going through like it does for the other web API requests I've made, it throws the error:
java.io.FileNotFoundException: https://api.spotify.com/v1/me/playlists
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:242)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:25)
at com.tmacstudios.spotifyvoice.WebWrapper$override.searchUserPlaylist(WebWrapper.java:257)
at com.tmacstudios.spotifyvoice.WebWrapper$override.access$dispatch(WebWrapper.java)
at com.tmacstudios.spotifyvoice.WebWrapper.searchUserPlaylist(WebWrapper.java:0)
at com.tmacstudios.spotifyvoice.MainActivity$6.run(MainActivity.java:382)
at java.lang.Thread.run(Thread.java:818)
I'm not entirely sure why I'm getting this error, but I think it may have to do with not having the necessary authorization to make this request. Can anyone please help me solve this problem?

After studying the documentation some more, I was able to figure out a way to solve my problem. I was in fact getting the error since I wasn't using the proper authorization.
You can get the authorization token in OnActivityResult using this code:
AuthenticationResponse response = AuthenticationClient.getResponse(resultCode, intent);
if (response.getType() == AuthenticationResponse.Type.TOKEN) {
authToken = response.getAccessToken();
Log.e("MainActivity","Auth Token: "+authToken.toString());
...
Then when making the URL request, just pass in the authorization token as a header.
URL url = new URL("https://api.spotify.com/v1/me/playlists");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Authorization", "Bearer " + authToken);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
...
Also note that you must have the permissions you are using enabled as scopes when you are forming the authorization request initially.

Related

Android App HTTP connection to server (Server upgrade to HTTPS)

I has an android app that AndroidManifest set to usesCleartextTraffic="true" because it is using http to connection to server.
But, now i plan to update the server to use HTTPS, and the server will redirect all http to https.
So, i want to know, if server redirect all traffic to HTTPS, will the android app that access the server using HTTP still working?
Example i am using the java code below to access server content. So will app still able to read the content at the app.php, if server update to use HTTPS? (server set to redirect all http to https)
String urls = "http://www.example.com/app.php";
URL url = new URL(urls);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Cache-Control", "no-cache");
content = readStream(conn.getInputStream());
Thanks in advance

Get 403 response with the "new" Firebase Cloud Messaging API

We are successfully using the Legacy HTTP Server Protocol on our server for FCM.
I wanted to update to FCM HTTP v1 API today.
I did it step by step and when the server calls the request, we get this response:
Server returned HTTP response code: 403 for URL: https://fcm.googleapis.com/v1/projects/[projectid]/messages:send
This is the server code:
URL url = new URL("https://fcm.googleapis.com/v1/projects/[projectid]/messages:send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Bearer " + getAccessToken());
conn.setRequestProperty("Content-Type", "application/json");
OutputStream outputStream = conn.getOutputStream();
outputStream.write(req.getBytes("UTF-8"));
// Exception happen here
InputStream inputStream = conn.getInputStream();
The getAccessToken():
private static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream(ClientApiServlet.context.getRealPath("/WEB-INF/[projectid].json"))) .createScoped(Arrays.asList("https://www.googleapis.com/auth/firebase.messaging"));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}
I have downloaded the json file from the adminsdk page of the firebase cloud.
All with the same projectid...
I updated these 2 libs on the server:
google-http-client-jackson2-1.23.0.jar
google-oauth-client-1.23.0.jar
The getAccessToken() methode returned an accesstoken: "ya29.c.Elr0BAa..."
I think, I miss a small step, maybe you could help?
Thanks in advance!
Edit:
It is working now with the hint of arterpa! Thanks again!
After that I got a 400 error, so something in the request data was wrong:
The problem was, we didn't converted all data{...}values to strings. With the legacy protocol it was not an issue, but with FCM HTTP v1 API it has to be strings! ;)
I had this problem, and it seems you need to enable FCM API for your project at Google API console.
I was having this issue of getting a 403 from the FCM HTTP v1 API. I had FCM Messaging API enabled, but my problem was that the service account I was using didn't have the correct role to make requests to the FCM API. You can try creating a new service account with the "project Owner" role to see if that helps.

GCM Client Based Device Group Management

I'm having issues adding GCM registration ID's to a device group client side in my Android app. I've followed all the instructions from https://developers.google.com/cloud-messaging/android/client-device-group but keep getting a 401 HTTP response. I've found the following posts but no one has an answer...
get notification key error 401 gcm https://android.googleapis.com/gcm/googlenotification
Google Cloud Messaging, returning 401 Unauthorized
Google Cloud Messaging, 401 Unauthorized is returned when creating notification key from client
How to successfully "Generate a Notification Key on the Client" with GCM?
I'm successfully getting an auth token from GoogleSignInApi and the method provided in Google's instructions but both give back 401 responses. I've ensured that I'm using the client ID for a Web Application in my Google Developer Console and still no luck. Here is my code snippet...
URL url = new URL("https://android.googleapis.com/gcm/googlenotification");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
// HTTP request header
con.setRequestProperty("project_id", getString(R.string.gcm_defaultSenderId));
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("POST");
con.connect();
String accountName = getAccount();
//Initialize the scope using the client ID you got from the Console.
final String scope = "audience:server:client_id:"
+ "MY_WEB_APP_CLIENT_ID";
String idToken = "";
try {
idToken = GoogleAuthUtil.getToken(this, sharedPref.getString("googleEmail", ""), scope);
} catch (Exception e) {
e.printStackTrace();
}
// HTTP request
JSONObject data = new JSONObject();
data.put("operation", "add");
data.put("notification_key_name", "my_group_name");
data.put("registration_ids", new JSONArray(Arrays.asList(registrationId)));
data.put("id_token", idToken);
OutputStream os = con.getOutputStream();
os.write(data.toString().getBytes("UTF-8"));
os.close();
int responseCode = con.getResponseCode();
I don't think it matters for this HTTP post request but I've also ensured the right project and client ID (android) are stored in my google-services.json. Has anyone had any success managing device groups client side? If so what's different in my code from yours?
I'm not sure that it is possible to do this without the server API key. The 401 error indicates that some sort of HTTP Authorization header should be included if that URL is used for device group setup.
My best suggestion is to keep the server API key well hidden using a client-side keystore mechanism (http://developer.android.com/training/articles/keystore.html).
For details on how do do the whole thing using the SERVER_API key, please see here: Google Cloud Messaging (GCM) with local device groups on Android gives HTTP Error code 401
Hope this helps. :-)

CSE (Custom Search Engine) steps

EDIT
...I'm still wondering why I can't find a solution to this issue.
I verify the API Key and the Custom Search Engine ID.
May be I left some library?
I have (related to the question):
-GWT SDK
-validation-api
I'm still reading posts and documentation....but nothing works....
ORIGINAL
I'm trying to develop an Android app. using CSE (Custom Search Engine). I've read a lot about this issue (here and in everywhere), but right now I'n not sure about anything: it's a mess for me.
I would like to know if I'm in the right way.
I get the API access key and the CSE ID
I want to use my own CSE, so I have to open a connection using "https://www.googleapis.com/customsearch/v1?key=_MY_API_KEY_&cx=_MY_SEARCH_ENGINE_ID&q=_MY_QUERY_
Here is the piece of code:
URL url = new URL("https://www.googleapis.com/customsearch/v1?key=_MY_KEY_&cx=_MY_ID_&q=tomcat");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
InputStreamReader isr = new InputStreamReader(conn.getInputStream());
BufferedReader br = new BufferedReader(isr);
I get an SSL exception at
InputStreamReader isr = new InputStreamReader(conn.getInputStream());
javax.net.ssl.SSLException: Connection closed by peer.
I don't know how I could fix this error, because all the examples I found related to CSE have (more or less) the same code to connect to the custom url search.
This is my first time here, so I not sure if I've expressed myself in the proper way.
Thanks a lot in advance.
Isaac.
I think you are trying to access a secure url (https) while using HttpURLConnection (instead HttpsURLConnection, mind the 's'), therefore the ssl error. Change to secure call and see if it worked.
To check if the engine is working as intended, just paste the url you mentioned ("https://www.googleapis.com/customsearch/v1?key=_MY_API_KEY_&cx=_MY_SEARCH_ENGINE_ID&q=_MY_QUERY_") in the browser - if it works, the engine is alright and the problem is in your code.

FileNotfoundException when trying to checkin Foursquare using Android

I tried looking for answers for this since last few days with no luck, Even some of the stackoverflow answers did not help.
I am trying to checkin a user after receiving his UserToken via Android. I get a FileNotfoundException at getInputStream(), non authenticated APIs like
"https://api.foursquare.com/v2/venues/categories" work well. Am i missing something?
URL url = new URL("https://api.foursquare.com/v2/checkins/add?oauth_token="+token);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.addRequestProperty("venueId","12238");
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setAllowUserInteraction(true);
conn.connect();
InputStream is = conn.getInputStream();
String response = streamToString(is);
return response;
Managed to solve this after lot of effort. See my answer below.
Try adding the oauth_token using the same method you use to add the venueid. Also, your venueid is invalid, so make sure you are checking the user in to a real venue.
The HttpURLConnection class is misleading in that it will throw a FileNotFoundException for any HTTP error code of 400 or above.
So it's not necessarily an incorrect URL (404) it could be 400 (bad request), 403 (forbidden), 500 (internal server error) etc.
Use the getResponseCode method to get a more precise indication of the problem.
first: Yoy have https url, and trying to create HttpURLConnection. You should use HttpsURLConnection.
Second: You can try to add conn.setDoOutput(true), "post" request requires it. And without it server can try give a get request from you despite on conn.setRequestMethod("POST"). Also you can check headers from your browser plugin, and put them into your request.
Okie I finally managed to solve the problem, I don't know what exactly was the problem with my code above but the following worked.
This API requires a POST call but even the venueID must be part of the URL and addRequestProperty does not seem to be sending the venueID properly. Hence I changed the code to
URL url = new URL("https://api.foursquare.com/v2/checkins/add?venueId=12238&oauth_token="+token);
And this solved the problem. Thanks all

Categories

Resources