Tirolel
Tirolel

Reputation: 928

Upload Picture to facebook

Hey there I know a lot of people have asked this question but none of them could help me, this what I want is how to make a button onclick have to start a photo chooser and upload the chosen picture into facebook ?

Iam really stuck and none of the answers could help me. I have a code that it sending text and its working fine. But now I want to upload picture too, so how I can make it? Anyone can help me?

best regards

UPDATE --> This is what I have to post

public class TestPost extends Activity{
private Facebook mFacebook;
private CheckBox mFacebookCb;
private ProgressDialog mProgress;

private Handler mRunOnUi = new Handler();

private static final String APP_ID = "app id here";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.post);

    final EditText reviewEdit = (EditText) findViewById(R.id.revieew);
    mFacebookCb               = (CheckBox) findViewById(R.id.cb_facebook);

    mProgress   = new ProgressDialog(this);

    mFacebook   = new Facebook(APP_ID);

    SessionStore.restore(mFacebook, this);

    if (mFacebook.isSessionValid()) {
        mFacebookCb.setChecked(true);

        String name = SessionStore.getName(this);
        name        = (name.equals("")) ? "Unknown" : name;

        mFacebookCb.setText("  Facebook  (" + name + ")");
    }

    ((Button) findViewById(R.id.button1)).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            String review = reviewEdit.getText().toString();

            if (review.equals("")) return;

            if (mFacebookCb.isChecked()) postToFacebook(review);
        }
    });
  private void postToFacebook(String review) {  
    mProgress.setMessage("Posting ...");
    mProgress.show();

    AsyncFacebookRunner mAsyncFbRunner = new AsyncFacebookRunner(mFacebook);

    Bundle params = new Bundle();

    params.putString("message", review);
    params.putString("name", "Dexter");
    params.putString("caption", "londatiga.net");
    params.putString("link", "http://www.londatiga.net");
    params.putString("description", "Dexter, seven years old dachshund who loves to catch cats, eat carrot and krupuk");
    params.putString("picture", "http://twitpic.com/show/thumb/6hqd44");

    mAsyncFbRunner.request("me/feed", params, "POST", new WallPostListener());
}

private final class WallPostListener extends BaseRequestListener {
    public void onComplete(final String response) {
        mRunOnUi.post(new Runnable() {
            @Override
            public void run() {
                mProgress.cancel();

                Toast.makeText(TestPost.this, "Posted to Facebook", Toast.LENGTH_SHORT).show();
            }
        });
    }

} }

Update 2 --> logcat and the error apper

    04-30 12:45:02.471: W/Bundle(29461): Key method expected byte[] but value was a java.lang.String.  The default value <null> was returned.
    04-30 12:45:02.476: W/Bundle(29461): Attempt to cast generated internal exception:
    04-30 12:45:02.476: W/Bundle(29461): java.lang.ClassCastException: java.lang.String
    04-30 12:45:02.476: W/Bundle(29461):    at android.os.Bundle.getByteArray(Bundle.java:1305)
    04-30 12:45:02.476: W/Bundle(29461):    at com.facebook.android.Util.openUrl(Util.java:155)
    04-30 12:45:02.476: W/Bundle(29461):    at com.facebook.android.Facebook.request(Facebook.java:559)
    04-30 12:45:02.476: W/Bundle(29461):    at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:208)
    04-30 12:45:02.476: W/Bundle(29461): Key format expected byte[] but value was a java.lang.String.  The default value <null> was returned.
    04-30 12:45:02.476: W/Bundle(29461): Attempt to cast generated internal exception:
    04-30 12:45:02.476: W/Bundle(29461): java.lang.ClassCastException: java.lang.String
    04-30 12:45:02.476: W/Bundle(29461):    at android.os.Bundle.getByteArray(Bundle.java:1305)
    04-30 12:45:02.476: W/Bundle(29461):    at com.facebook.android.Util.openUrl(Util.java:155)
    04-30 12:45:02.476: W/Bundle(29461):    at com.facebook.android.Facebook.request(Facebook.java:559)
    04-30 12:45:02.476: W/Bundle(29461):    at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:208)
    04-30 12:45:02.476: W/dalvikvm(29461): threadid=10: thread exiting with uncaught exception (group=0x4001e578)
    04-30 12:45:02.476: E/AndroidRuntime(29461): FATAL EXCEPTION: Thread-11
    04-30 12:45:02.476: E/AndroidRuntime(29461): java.lang.NullPointerException
    04-30 12:45:02.476: E/AndroidRuntime(29461):    at java.net.URLDecoder.decode(URLDecoder.java:104)
    04-30 12:45:02.476: E/AndroidRuntime(29461):    at java.net.URLDecoder.decode(URLDecoder.java:48)
    04-30 12:45:02.476: E/AndroidRuntime(29461):    at com.facebook.android.Util.openUrl(Util.java:167)
    04-30 12:45:02.476: E/AndroidRuntime(29461):    at com.facebook.android.Facebook.request(Facebook.java:559)
    04-30 12:45:02.476: E/AndroidRuntime(29461):    at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:208)

*This is the call *

    ((Button) findViewById(R.id.upload)).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            try{
            selectImage();
                    } 
            catch (Exception e) {
                    Toast toast = Toast.makeText(TestPost.this, "Unable to retrieve the selected image.", Toast.LENGTH_LONG);
                    toast.show();
                } finally {   
                }
            }
    });
    }

Here is // TODO: upload to Facebook albums

private void uploadImageBytes(byte[] bytes) {
    // TODO: upload to Facebook albums

          Bundle params = new Bundle();
          params.putString(Facebook.TOKEN, mFacebook.getAccessToken());
          params.putString("method", "photos.upload");
          params.putByteArray("picture", bytes);

          AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(mFacebook);
          mAsyncRunner.request(null, params, "POST", new WallPostListener());
}

Solution Thx to #vorrtex with the answered question belowed he explained me the issue with his code I got it to work. here is full code for others if they will need it in future

A button calls the method

   ((Button) findViewById(R.id.upload)).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            try{
            selectImage();
                    } 
            catch (Exception e) {
                    Toast toast = Toast.makeText(TestPost.this, "Unable to retrieve the selected image.", Toast.LENGTH_LONG);
                    toast.show();
                } finally {   
                }
            }
    });

And here the method and stream codes. The code is from the answered question

    private void selectImage() {

    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.setType("image/*");
    this.startActivityForResult(i, REQUEST_CODE_GALLERY);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case REQUEST_CODE_GALLERY:

                Uri selectedImage = data.getData();
                String filePath = null;

                String[] columns = { MediaColumns.DATA };
                Cursor cursor = this.getContentResolver().query(selectedImage, columns, null, null, null);
                if (cursor != null) {
                    cursor.moveToFirst();

                    int columnIndex = cursor.getColumnIndex(columns[0]);
                    filePath = cursor.getString(columnIndex);

                    if (!cursor.isClosed()) {
                        cursor.close();
                    }
                } else {
                    filePath = selectedImage.getPath();
                }

                if (filePath != null) {
                    this.uploadImagePath(filePath);
                } else {
                    Toast toast = Toast.makeText(this, "Unable to retrieve the selected image.", Toast.LENGTH_LONG);
                    toast.show();
                }

                break;
        }
    }
}

private void uploadImagePath(String filePath) {
    FileInputStream fileStream = null;
    try {
        fileStream = new FileInputStream(new File(filePath));
        byte[] bytes = convertStreamToBytes(fileStream);
        this.uploadImageBytes(bytes);
        placering = filePath; 
    } catch (Exception e) {
        Toast toast = Toast.makeText(this, "Unable to retrieve the selected image.", Toast.LENGTH_LONG);
        toast.show();
    } finally {
        closeStream(fileStream);
    }
}

private void uploadImageBytes(byte[] bytes) {
    // TODO: upload to Facebook albums

    Bundle params = new Bundle();
    params.putString(Facebook.TOKEN, mFacebook.getAccessToken());
    params.putString("method", "photos.upload");
    params.putByteArray("picture", bytes);

    AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(mFacebook);
    mAsyncRunner.request(null, params, "POST", new WallPostListener());
}


public static byte[] convertStreamToBytes(InputStream stream) throws IOException {
    if (stream == null) {
        return null;
    }

    ByteArrayOutputStream output = new ByteArrayOutputStream();

    copyStream(stream, output);

    return output.toByteArray();
}

public static void copyStream(InputStream from, OutputStream to) throws IOException {
    byte data[] = new byte[8192];
    int count;

    while ((count = from.read(data)) != -1) {
        to.write(data, 0, count);
    }

    from.close();
}

public static void closeStream(Closeable stream) {
    try {
        if (stream != null) {
            stream.close();
        }
    } catch (Exception e) {

    }
}

Upvotes: 0

Views: 1412

Answers (1)

vortexwolf
vortexwolf

Reputation: 14037

Here are answers how to start a photo chooser: How to pick an image from gallery (SD Card) for my app?

Then you should upload the selected image to a Facebook album (/me/photos). You have to do this because me/feed accepts only URL strings, not binary images, so you upload your image so that you have a URL string to it.

Here is an answer how to do this: Android - Upload photo to Facebook with Facebook Android SDK. You should replace '/sdcard/viewitems.png' by the file path chosen from gallery.

Then you can post the link to the uploaded image:

// the onComplete method from the previous link
final String src = json.getString("src");

// ... create params ...
params.putString("picture", src);

mAsyncFbRunner.request("me/feed", params, "POST", new WallPostListener());

Edit: By the way, answers from the first link are not complete and aren't good, so here is the full code how to select an image from gallery and convert it to bytes:

private void selectImage() {
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.setType("image/*");
    this.startActivityForResult(i, Constants.REQUEST_CODE_GALLERY);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case Constants.REQUEST_CODE_GALLERY:

                Uri selectedImage = data.getData();
                String filePath = null;

                String[] columns = { MediaColumns.DATA };
                Cursor cursor = this.getContentResolver().query(selectedImage, columns, null, null, null);
                if (cursor != null) {
                    cursor.moveToFirst();

                    int columnIndex = cursor.getColumnIndex(columns[0]);
                    filePath = cursor.getString(columnIndex);

                    if (!cursor.isClosed()) {
                        cursor.close();
                    }
                } else {
                    filePath = selectedImage.getPath();
                }

                if (filePath != null) {
                    this.uploadImagePath(filePath);
                } else {
                    Toast toast = Toast.makeText(this, "Unable to retrieve the selected image.", Toast.LENGTH_LONG);
                    toast.show();
                }

                break;
        }
    }
}

private void uploadImagePath(String filePath) {
    FileInputStream fileStream = null;
    try {
        fileStream = new FileInputStream(new File(filePath));
        byte[] bytes = convertStreamToBytes(fileStream);
        this.uploadImageBytes(bytes);
    } catch (Exception e) {
        Toast toast = Toast.makeText(this, "Unable to retrieve the selected image.", Toast.LENGTH_LONG);
        toast.show();
    } finally {
        closeStream(fileStream);
    }
}

private void uploadImageBytes(byte[] bytes) {
    // TODO: upload to Facebook albums
}

public static byte[] convertStreamToBytes(InputStream stream) throws IOException {
    if (stream == null) {
        return null;
    }

    ByteArrayOutputStream output = new ByteArrayOutputStream();

    copyStream(stream, output);

    return output.toByteArray();
}

public static void copyStream(InputStream from, OutputStream to) throws IOException {
    byte data[] = new byte[8192];
    int count;

    while ((count = from.read(data)) != -1) {
        to.write(data, 0, count);
    }

    from.close();
}

public static void closeStream(Closeable stream) {
    try {
        if (stream != null) {
            stream.close();
        }
    } catch (Exception e) {
        Log.e(TAG, e);
    }
}

Upvotes: 1

Related Questions