Search code examples
androidapiauthenticationhttpurlconnectiontwitter-oauth

How to add parameters to httprequest in order to work with twitter api 1.1


I'm working on a project (use twitter api to search for a specific HashTag) when going into this site https://api.twitter.com/1.1/search/tweets.json?q=liverpool&count=20 to get the response

{"errors":[{"code":215,"message":"Bad Authentication data."}]}

after that I know that I should register my app in order to get Consumer Key,Consumer Secret,Access Token,Access Token Secret but I don't know how to add this tokens into my android code in order to this is my makehttpconnection method and I want to add this tokens to the connection

private static String makeHttpRequest(URL url) throws IOException {
    String jsonResponse = "";

    // If the URL is null, then return early.
    if (url == null) {
        return jsonResponse;
    }

    HttpURLConnection urlConnection = null;
    InputStream inputStream = null;
    try {
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setReadTimeout(10000 /* milliseconds */);
        urlConnection.setConnectTimeout(15000 /* milliseconds */);
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();

        // If the request was successful (response code 200),
        // then read the input stream and parse the response.
        if (urlConnection.getResponseCode() == 200) {
            inputStream = urlConnection.getInputStream();
            jsonResponse = readFromStream(inputStream);
        } else {
            Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
        }
    } catch (IOException e) {
        Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
        if (inputStream != null) {
            inputStream.close();
        }
    }
    return jsonResponse;
}

Note:it's unavailable for me to use Twitter sdk


Solution

  • If you want to do only timeline searches, the Application-only authentication (https://dev.twitter.com/oauth/application-only) should be fine for you. So as a first step, register a new twitter application. https://apps.twitter.com/

    You will need a bearer token:

    public class TwitterAuthorization extends AsyncTask<String, Void, Void> {
    String returnEntry;
    boolean finished;
    
    private static final String CONSUMER_KEY = "yourKey";
    private static final String CONSUMER_SECRET = "yourSecret";
    public static String bearerToken;
    public static String tokenType;
    
    private static final String tokenUrl = "https://api.twitter.com/oauth2/token";
    
    public void sendPostRequestToGetBearerToken () {
        URL loc = null;
        HttpsURLConnection conn = null;
        InputStreamReader is;
        BufferedReader in;
    
        try {
            loc = new URL(tokenUrl);
        }
        catch (MalformedURLException ex) {
            return;
        }
    
        try {
    
            String urlApiKey = URLEncoder.encode(CONSUMER_KEY, "UTF-8");
            String urlApiSecret = URLEncoder.encode(CONSUMER_SECRET, "UTF-8");
            String combined = urlApiKey + ":" + urlApiSecret;
            byte[] data = combined.getBytes();
            String base64 = Base64.encodeToString(data, Base64.NO_WRAP);
    
            conn = (HttpsURLConnection)loc.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
    
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Host", "api.twitter.com");
            conn.setRequestProperty("User-Agent", "1");
            conn.setRequestProperty("Authorization", "Basic " + base64);
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            conn.setRequestProperty("Content-Length", "29");
            conn.setUseCaches(false);
            String urlParameters = "grant_type=client_credentials";
    
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
            wr.writeBytes(urlParameters);
    
            wr.flush();
            wr.close();
    
            is = new InputStreamReader (conn.getInputStream(), "UTF-8");
            in = new BufferedReader (is);
    
            readResponse (in);
    
            setJSONresults();
        }
        catch (IOException ex) {
    
        }
        finally {
            conn.disconnect();
    
        }
    
    }
    
    
    public void readResponse(BufferedReader in) {
        String tmp = "";
        StringBuffer response = new StringBuffer();
    
        do {
            try {
                tmp = in.readLine();
            }
            catch (IOException ex) {
    
            }
            if (tmp != null) {
                response.append(tmp);
            }
        } while (tmp != null);
        returnEntry = response.toString();
    }
    
    public void setJSONresults(){
        try {
            JSONObject obj1 = new JSONObject(returnEntry);
            bearerToken =obj1.getString("access_token");
            myLog += bearerToken;
    
            tokenType = obj1.getString("token_type");
            myLog += tokenType;
        } catch (JSONException ex){
    
        }
    }
    
    @Override
    protected void onPostExecute(Void result) {
        finished = true;
    }
    
    @Override
    protected Void doInBackground(String... params) {
        finished = false;
        if (bearerToken == null) {
            sendPostRequestToGetBearerToken();
        }
        return null;
    }
    

    }

    Then you can run the queries with your token:

    private String fetchTimelineTweet(String endPointUrl) throws IOException, ParseException {
        HttpsURLConnection connection = null;
        BufferedReader bufferedReader = null;
        String testUrl = " https://api.twitter.com/1.1/search/tweets.json?q=&geocode=-22.912214,-43.230182,1km&lang=pt&result_type=recent&count=3";
        try {
    
            URL url = new URL(testUrl);
            connection = (HttpsURLConnection) url.openConnection();
            connection.setRequestMethod("HEAD");
            JSONObject jsonObjectDocument = new JSONObject(twitterAuthorizationData);
            String token = jsonObjectDocument.getString("token_type") + " "
                    + jsonObjectDocument.getString("access_token");
            connection.setRequestProperty("Authorization", token);
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestProperty("Host", "api.twitter.com");
            connection.setRequestProperty("Accept-Encoding", "identity");
            connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            connection.connect();
            bufferedReader = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
    
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                response.append(line);
            }
    
            setJSONObjectResults();
    
        } catch (MalformedURLException e) {
            throw new IOException("Invalid endpoint URL specified.", e);
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        return new String();
    }
    
    public void setJSONObjectResults(){
        try {
            JSONObject obj = new JSONObject(response.toString());
            JSONArray statuses;
            statuses = obj.getJSONArray("statuses");
            for (int i=0; i < statuses.length(); i++){
                String text = statuses.getJSONObject(i).getString("text");
            }
    
        } catch (JSONException e) {
            e.printStackTrace();
            myLog += e.toString();
        }
    
    }
    

    You can also have a look over here, but I found it a bit of outdated. android: how to get trends from twitter?