Java tutorial
/** * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. * * You are hereby granted a non-exclusive, worldwide, royalty-free license to use, * copy, modify, and distribute this software in source code or binary form for use * in connection with the web services and APIs provided by Facebook. * * As with any software that integrates with the Facebook platform, your use of * this software is subject to the Facebook Developer Principles and Policies * [http://developers.facebook.com/policy/]. This copyright notice shall be * included in all copies or substantial portions of the software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.proalias.awesomestatus; import android.app.AlertDialog; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.facebook.AccessToken; import com.facebook.CallbackManager; import com.facebook.FacebookAuthorizationException; import com.facebook.FacebookCallback; import com.facebook.FacebookException; import com.facebook.FacebookSdk; import com.facebook.Profile; import com.facebook.ProfileTracker; import com.facebook.appevents.AppEventsLogger; import com.facebook.login.LoginManager; import com.facebook.login.LoginResult; import com.facebook.login.widget.ProfilePictureView; import com.facebook.share.ShareApi; import com.facebook.share.Sharer; import com.facebook.share.model.ShareLinkContent; import com.facebook.share.model.SharePhoto; import com.facebook.share.model.SharePhotoContent; import com.facebook.share.widget.ShareDialog; import java.io.FileDescriptor; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; public class MainActivity extends FragmentActivity { private static final String PERMISSION = "publish_actions"; private static final int SELECT_PICTURE = 1; private final String PENDING_ACTION_BUNDLE_KEY = "com.proalias.awesomestatus:PendingAction"; private Button postStatusUpdateButton; private Button postPhotoButton; private ProfilePictureView profilePictureView; private TextView greeting; private PendingAction pendingAction = PendingAction.NONE; private boolean canPresentShareDialog; private boolean canPresentShareDialogWithPhotos; private CallbackManager callbackManager; private ProfileTracker profileTracker; private ShareDialog shareDialog; private Uri selectedImageUri; private FacebookCallback<Sharer.Result> shareCallback = new FacebookCallback<Sharer.Result>() { @Override public void onCancel() { Log.d("AwesomeStatus", "Canceled"); } @Override public void onError(FacebookException error) { Log.d("AwesomeStatus", String.format("Error: %s", error.toString())); String title = getString(R.string.error); String alertMessage = error.getMessage(); showResult(title, alertMessage); } @Override public void onSuccess(Sharer.Result result) { Log.d("AwesomeStatus", "Success!"); if (result.getPostId() != null) { String title = getString(R.string.success); String id = result.getPostId(); String alertMessage = getString(R.string.successfully_posted_post, id); showResult(title, alertMessage); } } private void showResult(String title, String alertMessage) { new AlertDialog.Builder(MainActivity.this).setTitle(title).setMessage(alertMessage) .setPositiveButton(R.string.ok, null).show(); } }; private enum PendingAction { NONE, POST_PHOTO, POST_STATUS_UPDATE } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FacebookSdk.sdkInitialize(this.getApplicationContext()); callbackManager = CallbackManager.Factory.create(); LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() { @Override public void onSuccess(LoginResult loginResult) { handlePendingAction(); updateUI(); } @Override public void onCancel() { if (pendingAction != PendingAction.NONE) { showAlert(); pendingAction = PendingAction.NONE; } updateUI(); } @Override public void onError(FacebookException exception) { if (pendingAction != PendingAction.NONE && exception instanceof FacebookAuthorizationException) { showAlert(); pendingAction = PendingAction.NONE; } updateUI(); } private void showAlert() { new AlertDialog.Builder(MainActivity.this).setTitle(R.string.cancelled) .setMessage(R.string.permission_not_granted).setPositiveButton(R.string.ok, null).show(); } }); shareDialog = new ShareDialog(this); shareDialog.registerCallback(callbackManager, shareCallback); if (savedInstanceState != null) { String name = savedInstanceState.getString(PENDING_ACTION_BUNDLE_KEY); pendingAction = PendingAction.valueOf(name); } setContentView(R.layout.main); profileTracker = new ProfileTracker() { @Override protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) { updateUI(); // It's possible that we were waiting for Profile to be populated in order to // post a status update. handlePendingAction(); } }; profilePictureView = (ProfilePictureView) findViewById(R.id.profilePicture); greeting = (TextView) findViewById(R.id.greeting); postStatusUpdateButton = (Button) findViewById(R.id.postStatusUpdateButton); postStatusUpdateButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { onClickPostStatusUpdate(); } }); //Get view for photo upload button postPhotoButton = (Button) findViewById(R.id.postPhotoButton); postPhotoButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { onClickPostPhoto(); } }); //Set it to hidden until we're logged in //postPhotoButton.setVisibility(View.GONE); // Can we present the share dialog for regular links? canPresentShareDialog = ShareDialog.canShow(ShareLinkContent.class); // Can we present the share dialog for photos? canPresentShareDialogWithPhotos = ShareDialog.canShow(SharePhotoContent.class); } @Override protected void onResume() { super.onResume(); AccessToken accessToken = AccessToken.getCurrentAccessToken(); Profile profile = Profile.getCurrentProfile(); // Call the 'activateApp' method to log an app event for use in analytics and advertising // reporting. Do so in the onResume methods of the primary Activities that an app may be // launched into. AppEventsLogger.activateApp(this); updateUI(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(PENDING_ACTION_BUNDLE_KEY, pendingAction.name()); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); callbackManager.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == SELECT_PICTURE) { selectedImageUri = data.getData(); performPublish(PendingAction.POST_PHOTO, canPresentShareDialogWithPhotos); } } } @Override public void onPause() { super.onPause(); // Call the 'deactivateApp' method to log an app event for use in analytics and advertising // reporting. Do so in the onPause methods of the primary Activities that an app may be // launched into. AppEventsLogger.deactivateApp(this); } @Override protected void onDestroy() { super.onDestroy(); profileTracker.stopTracking(); } private void updateUI() { boolean enableButtons = AccessToken.getCurrentAccessToken() != null; //We're ready to post our status - make the buttons visible / attach the fragment that contains them: postStatusUpdateButton.setEnabled(enableButtons || canPresentShareDialog); postPhotoButton.setEnabled(enableButtons || canPresentShareDialogWithPhotos); //TODO - split out into fragment Profile profile = Profile.getCurrentProfile(); if (enableButtons && profile != null) { profilePictureView.setProfileId(profile.getId()); greeting.setText(getString(R.string.hello_user, profile.getFirstName())); } else { profilePictureView.setProfileId(null); greeting.setText(null); } } private void handlePendingAction() { PendingAction previouslyPendingAction = pendingAction; // These actions may re-set pendingAction if they are still pending, but we assume they // will succeed. pendingAction = PendingAction.NONE; switch (previouslyPendingAction) { case NONE: break; case POST_PHOTO: postPhoto(); break; case POST_STATUS_UPDATE: postStatusUpdate(); break; } } private void onClickPostStatusUpdate() { performPublish(PendingAction.POST_STATUS_UPDATE, canPresentShareDialog); } private void postStatusUpdate() { Profile profile = Profile.getCurrentProfile(); ShareLinkContent linkContent = new ShareLinkContent.Builder().setContentTitle("Awesome Status!") .setContentDescription("Awesome Status for Android is a simple app to update your facebook status") .setContentUrl( Uri.parse("https://play.google.com/store/apps/details?id=com.proalias.awesomestatus")) .build(); if (canPresentShareDialog) { shareDialog.show(linkContent); } else if (profile != null && hasPublishPermission()) { ShareApi.share(linkContent, shareCallback); } else { pendingAction = PendingAction.POST_STATUS_UPDATE; } } private void onClickPostPhoto() { // Launch the gallery picker to specify a photo Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); } private void postPhoto() { Bitmap image = null; try { image = getBitmapFromUri(selectedImageUri); } catch (IOException e) { Log.e("AwesomeStatus", e.getMessage()); } finally { if (image != null) { SharePhoto sharePhoto = new SharePhoto.Builder().setBitmap(image).build(); ArrayList<SharePhoto> photos = new ArrayList<>(); photos.add(sharePhoto); SharePhotoContent sharePhotoContent = new SharePhotoContent.Builder().setPhotos(photos).build(); if (canPresentShareDialogWithPhotos) { shareDialog.show(sharePhotoContent); } else if (hasPublishPermission()) { ShareApi.share(sharePhotoContent, shareCallback); } else { pendingAction = PendingAction.POST_PHOTO; // We need to get new permissions, then complete the action when we get called back. LoginManager.getInstance().logInWithPublishPermissions(this, Arrays.asList(PERMISSION)); } } } } private Bitmap getBitmapFromUri(Uri uri) throws IOException { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); parcelFileDescriptor.close(); return image; } private boolean hasPublishPermission() { AccessToken accessToken = AccessToken.getCurrentAccessToken(); return accessToken != null && accessToken.getPermissions().contains("publish_actions"); } private void performPublish(PendingAction action, boolean allowNoToken) { AccessToken accessToken = AccessToken.getCurrentAccessToken(); if (accessToken != null || allowNoToken) { pendingAction = action; handlePendingAction(); } } }