Search code examples
androidtwitteroauthscribe

Twitter update_with_media Via Scribe OAuth On Android


I'm currently using Scribe to both authenticate and post non-media messages to Twitter successfully. This was very easy, my first test message posted with no issues. However, I can't seem to post photos at all. I have reviewed Twitter's instructions for posting with media, both here and here.

All of the Scribe/Twitter examples at Github are for non-media posts. It would be great if someone could provide a solid example of how to post photos to Twitter via Scribe!

I'm have two issues in particular:

1) My posts will not pass authorization. I've tried mimicking the examples I posted above, but nothing seems to work.

2) When converting the image from byte[] to a string, I only seem to get 4113 characters before it stops. From my understanding, this is well under the number of characters a String can hold.

Here is how I'm extracting the photo:

// GET PHOTO FILE AND FILE LENGTH
// INSTANTIATE UPLOAD VARIABLE WITH FILE LENGTH

    File file      = new File(photo); // ("photo" is a string path to the photo file)
    int fileLength = (int) file.length();

    uploadFile = new byte[fileLength];

// CREATE BUFFER INPUT STREAM OF FILE

    BufferedInputStream inputStream;

    try {inputStream = new BufferedInputStream(new FileInputStream(file));}
    catch (FileNotFoundException e)
    {
        inputStream = null;
        Toast.makeText(this.getApplicationContext(), "Buffer input stream error!", Toast.LENGTH_LONG).show();
    }

// READ DATA FROM FILE INTO UPLOAD VARIABLE
// CLOSE INPUT STREAM

    try {inputStream.read(uploadFile);}
    catch (IOException e) {Toast.makeText(this.getApplicationContext(), "Read input stream to upload variable error!", Toast.LENGTH_LONG).show();}

    try {inputStream.close();}
    catch (IOException e) {Toast.makeText(this.getApplicationContext(), "Close input stream error!", Toast.LENGTH_LONG).show();}

Solution

  • After a LOT of research and piece milling code from various places I finally figured out what I was doing wrong. Here is an example of how to post photos to Twitter via Scribe OAuth:

    NOTE: This assumes a few things...

    1) You have already saved the photo and have the file path

    2) You have already authenticated the user at some point and have a valid access Token

    3) You MUST add apache-mime4j-0.6.jar & httpmime-4.0.1.jar to you libs folder and include them in your build path!!!

    I really hope this helps someone! It's very easy to implement, but took a few days of troubleshooting to get it working correctly!

    // BUILD OAUTH SERVICE
    
        OAuthService oAuth = new ServiceBuilder()
            .provider(TwitterApi.class)
            .apiKey(YOUR_TWITTER_API_KEY)        // REPLACE WITH YOUR OWN!!!
            .apiSecret(YOUR_TWITTER_API_SECRET)  // REPLACE WITH YOUR OWN!!!
            .callback(YOUR_CALLBACK)             // REPLACE WITH YOUR OWN!!!
            .build();
    
    // BUILD OAUTH REQUEST & SIGN IT RIGHT AWAY (OTHERWISE MULTIPART FORM MAY PREVENT SIGNING)
    
        OAuthRequest request = new OAuthRequest(Verb.POST, "https://upload.twitter.com/1.1/statuses/update_with_media.json");
        oAuth.signRequest(USER_ACCESS_TOKEN, request);  // ENTER USER'S ACCESS TOKEN
    
    // ADD MULTIPART FORM
    
        try
        {
            MultipartEntity entity = new MultipartEntity();
    
            entity.addPart("status", new StringBody(message));       // THIS IS THE TWITTER MESSAGE
            entity.addPart("media", new FileBody(new File(photo)));  // THIS IS THE PHOTO TO UPLOAD
    
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            entity.writeTo(out);
    
            request.addPayload(out.toByteArray());
            request.addHeader(entity.getContentType().getName(), entity.getContentType().getValue());
        }
        catch (UnsupportedEncodingException e) {e.printStackTrace();}
        catch (IOException e) {e.printStackTrace();}
    
    // SEND REQUEST
    
        try {response = new JSONObject (request.send().getBody());}
        catch (JSONException e) {Log.e("YOUR_APP_TAG", "JSONException Thrown: " + e.getMessage());}