com.soomla.example.ExampleSocialActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.soomla.example.ExampleSocialActivity.java

Source

/*
 * Copyright (C) 2012-2014 Soomla Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.soomla.example;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.soomla.BusProvider;
import com.soomla.SoomlaUtils;
import com.soomla.profile.SoomlaProfile;
import com.soomla.profile.domain.IProvider;
import com.soomla.profile.domain.UserProfile;
import com.soomla.profile.events.auth.LoginCancelledEvent;
import com.soomla.profile.events.auth.LoginFailedEvent;
import com.soomla.profile.events.auth.LoginFinishedEvent;
import com.soomla.profile.events.social.GetContactsFinishedEvent;
import com.soomla.profile.events.social.GetFeedFinishedEvent;
import com.soomla.profile.events.social.SocialActionFailedEvent;
import com.soomla.profile.events.social.SocialActionFinishedEvent;
import com.soomla.profile.exceptions.ProviderNotFoundException;
import com.soomla.profile.exceptions.UserProfileNotFoundException;
import com.soomla.rewards.Reward;
import com.soomla.rewards.VirtualItemReward;
import com.squareup.otto.Subscribe;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.HttpClientParams;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/**
 * This class shows the main activity in which the user can socially interact
 * with different social providers.
 *
 * NOTE: See <code>activity_main_social.xml</code> for activity UI
 */
public class ExampleSocialActivity extends Activity {

    /** Private Members */

    private static final String TAG = "ExampleSocialActivity";

    private static final int SELECT_PHOTO_ACTION = 1;

    private Button mBtnShare;

    private ViewGroup mProfileBar;
    private ImageView mProfileAvatar;
    private TextView mProfileName;

    private ViewGroup mPnlStatusUpdate;
    private Button mBtnUpdateStatus;
    private EditText mEdtStatusText;

    private ViewGroup mPnlStoryUpdate;
    private Button mBtnUpdateStory;
    private EditText mEdtStoryText;

    private ViewGroup mPnlUploadImage;
    private ImageView mBtnChooseImage;
    private Button mBtnUploadImage;
    private EditText mEdtImageText;
    private String mImagePath;
    private ImageView mImagePreview;

    private ProgressDialog mProgressDialog;

    private String mItemId = "cream_cup";
    private String mItemName = "Cup Cup";
    private int mItemAmount = 15;
    private int mItemResId = R.drawable.ic_launcher;

    private IProvider.Provider mProvider = IProvider.Provider.FACEBOOK;

    Reward gameLoginReward = new VirtualItemReward("reward_login", "Login for VG", 15, mItemId);
    Reward gameUpdateStatusReward = new VirtualItemReward("reward_update_status", "Update Status for VG", 25,
            mItemId);
    Reward gameUpdateStoryReward = new VirtualItemReward("reward_update_story", "Update Story for VG", 35, mItemId);
    Reward gameUploadImageReward = new VirtualItemReward("reward_upload_image", "Upload Image for VG", 45, mItemId);
    Reward gameLikePageReward = new VirtualItemReward("reward_like_page", "Like Page for VG", 105, mItemId);

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_social);

        //        SoomlaConfig.logDebug = true;

        mProgressDialog = new ProgressDialog(this);

        final Bundle extras = getIntent().getExtras();
        if (extras != null) {
            final String provider = extras.getString("provider");
            mProvider = IProvider.Provider.getEnum(provider);
            mItemId = extras.getString("id");
            mItemAmount = extras.getInt("amount", 1);
            mItemName = extras.getString("name");
            mItemResId = extras.getInt("iconResId", R.drawable.ic_launcher);

            // set the social provider logo if possible
            final int resourceId = getResources().getIdentifier(provider, "drawable", getPackageName());
            Drawable drawableLogo = getResources().getDrawable(resourceId);
            if (drawableLogo != null) {
                final TextView topBarTextView = (TextView) findViewById(R.id.textview);
                if (topBarTextView != null) {
                    topBarTextView.setCompoundDrawablesWithIntrinsicBounds(drawableLogo, null, null, null);
                }
            }
        }

        final TextView vItemDisplay = (TextView) findViewById(R.id.vItem);
        if (vItemDisplay != null) {
            vItemDisplay.setText(mItemName);
            vItemDisplay.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(mItemResId), null,
                    null);
        }

        mProfileBar = (ViewGroup) findViewById(R.id.profile_bar);
        mProfileAvatar = (ImageView) findViewById(R.id.prof_avatar);
        mProfileName = (TextView) findViewById(R.id.prof_name);

        mPnlStatusUpdate = (ViewGroup) findViewById(R.id.pnlStatusUpdate);
        mEdtStatusText = (EditText) findViewById(R.id.edtStatusText);

        mEdtStatusText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    doUpdateStatus();
                    handled = true;
                }

                return handled;
            }
        });

        mBtnUpdateStatus = (Button) findViewById(R.id.btnStatusUpdate);
        mBtnUpdateStatus.setEnabled(false);
        mBtnUpdateStatus.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                doUpdateStatus();
            }
        });

        mPnlUploadImage = (ViewGroup) findViewById(R.id.pnlUploadImage);
        mImagePreview = (ImageView) findViewById(R.id.imagePreview);
        mEdtImageText = (EditText) findViewById(R.id.edtImageText);

        mEdtImageText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    doUpdateStatus();
                    handled = true;
                }

                return handled;
            }
        });

        mBtnChooseImage = (ImageView) findViewById(R.id.btnChooseImage);
        mBtnChooseImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                chooseImageFile();
            }
        });

        mBtnUploadImage = (Button) findViewById(R.id.btnUploadImage);
        mBtnUploadImage.setEnabled(false);
        mBtnUploadImage.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                doUploadImage();
            }
        });

        mPnlStoryUpdate = (ViewGroup) findViewById(R.id.pnlStoryUpdate);
        mEdtStoryText = (EditText) findViewById(R.id.edtStoryText);

        mEdtStoryText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    doUpdateStory();
                    handled = true;
                }

                return handled;
            }
        });

        mBtnUpdateStory = (Button) findViewById(R.id.btnStoryUpdate);
        mBtnUpdateStory.setEnabled(false);
        mBtnUpdateStory.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                doUpdateStory();
            }
        });

        mBtnShare = (Button) findViewById(R.id.btnShare);

        if (!SoomlaProfile.getInstance().isLoggedIn(this, mProvider)) {
            SoomlaProfile.getInstance().login(this, mProvider, gameLoginReward);

            mProgressDialog.setMessage("logging in...");
            mProgressDialog.show();
        } else {
            applyLoggedInUser(mProvider);
        }
    }

    @Subscribe
    public void onSocialActionFinishedEvent(SocialActionFinishedEvent socialActionFinishedEvent) {
        Log.d(TAG, "SocialActionFinishedEvent:" + socialActionFinishedEvent.SocialActionType.toString());
        Toast.makeText(this, "action " + socialActionFinishedEvent.SocialActionType.toString() + " success",
                Toast.LENGTH_SHORT).show();

        mProgressDialog.dismiss();

        switch (socialActionFinishedEvent.SocialActionType) {
        case UPDATE_STATUS: {
            mEdtStatusText.setText("");
            break;
        }
        case UPLOAD_IMAGE: {
            mEdtImageText.setText("");
        }
        case UPDATE_STORY: {
            mEdtStoryText.setText("");
        }
        default: {
            break;
        }
        }
    }

    @Subscribe
    public void onSocialActionFailedEvent(SocialActionFailedEvent socialActionFailedEvent) {
        Log.d(TAG, "SocialActionFailedEvent:" + socialActionFailedEvent.SocialActionType.toString());

        mProgressDialog.dismiss();

        Toast.makeText(this, "action " + socialActionFailedEvent.SocialActionType.toString() + " failed: "
                + socialActionFailedEvent.ErrorDescription, Toast.LENGTH_SHORT).show();
    }

    /**
     * @{inheritDoc}
     */
    @Override
    protected void onPause() {
        super.onPause();

        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

    @Subscribe
    public void onLoginFinishedEvent(LoginFinishedEvent loginFinishedEvent) {
        // Variable to receive message status
        Log.d(TAG, "Authentication Successful");

        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }

        // Get name of provider after authentication
        final IProvider.Provider provider = loginFinishedEvent.getProvider();

        applyLoggedInUser(provider, loginFinishedEvent.UserProfile);

        if (gameLikePageReward.canGive()) {
            SoomlaProfile.getInstance().like(this, provider, "The.SOOMLA.Project", gameLikePageReward);
        }
    }

    private void applyLoggedInUser(final IProvider.Provider provider) {
        UserProfile loggedInProfile = SoomlaProfile.getInstance().getStoredUserProfile(provider);
        applyLoggedInUser(provider, loggedInProfile);
    }

    private void applyLoggedInUser(final IProvider.Provider provider, UserProfile targetProfile) {

        if (targetProfile == null) {
            SoomlaUtils.LogWarning(TAG, "Logged-in user profile was not found in " + provider + " provider");
            return;
        }

        Log.d(TAG, "Provider Name = " + provider);
        Toast.makeText(this, provider + " connected", Toast.LENGTH_SHORT).show();

        showView(mProfileBar, true);
        new DownloadImageTask(mProfileAvatar).execute(targetProfile.getAvatarLink());
        if (targetProfile.getFirstName() != null) {
            mProfileName.setText(targetProfile.getFullName());
        } else {
            mProfileName.setText(targetProfile.getUsername());
        }

        updateUIOnLogin(provider);

        // TEST
        // todo: it seems that FB no longer simply returns your friends via me/friends
        // todo: need to figure out what's best here
        SoomlaProfile.getInstance().getContacts(provider, null);
        SoomlaProfile.getInstance().getFeed(provider, null);
    }

    @Subscribe
    public void onSocialContactsEvent(GetContactsFinishedEvent contactsFinishedEvent) {
        Log.d(TAG, "GetContactsFinishedEvent");
        final List<UserProfile> contacts = contactsFinishedEvent.Contacts;
        for (UserProfile contact : contacts) {
            Log.d(TAG, "contact:" + contact.toJSONObject().toString());
        }
        if (contactsFinishedEvent.HasMore) {
            SoomlaProfile.getInstance().getContacts(contactsFinishedEvent.Provider, null);
        }
    }

    @Subscribe
    public void onSocialFeedEvent(GetFeedFinishedEvent feedFinishedEvent) {
        Log.d(TAG, "GetFeedFinishedEvent");
        final List<String> posts = feedFinishedEvent.Posts;
        for (String post : posts) {
            Log.d(TAG, "post:" + post);
        }
    }

    @Subscribe
    public void onSocialLoginErrorEvent(LoginFailedEvent loginFailedEvent) {
        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }

        final String errMsg = "login error:" + loginFailedEvent.ErrorDescription;
        Log.e(TAG, errMsg);

        Toast.makeText(getApplicationContext(), errMsg, Toast.LENGTH_SHORT).show();
        finish();
    }

    @Subscribe
    public void onSocialLoginCancelledEvent(LoginCancelledEvent loginCancelledEvent) {
        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }

        Toast.makeText(getApplicationContext(), "login cancelled", Toast.LENGTH_SHORT).show();
        finish();
    }

    private void doUpdateStory() {
        // Please avoid sending duplicate message. Social Media Providers
        // block duplicate messages.

        final String message = mEdtStoryText.getText().toString();
        hideSoftKeyboard();
        // create social action
        // perform social action
        mProgressDialog.setMessage("updating status...");
        mProgressDialog.show();
        SoomlaProfile.getInstance().updateStory(mProvider, message, "The SOOMLA Project", "",
                "SOOMLA is a smart, free and open-source cross-platform framework that empowers indie developers productivity and drives game success.",
                "http://soom.la", "http://about.soom.la/wp-content/uploads/2014/05/330x268-bankerbot.png",
                gameUpdateStoryReward);

        // Or with dialog
        //SoomlaProfile.getInstance().updateStoryDialog(mProvider,
        //        "The SOOMLA Project",
        //        "",
        //        "SOOMLA is a smart, free and open-source cross-platform framework that empowers indie developers productivity and drives game success.",
        //        "http://soom.la",
        //        "http://about.soom.la/wp-content/uploads/2014/05/330x268-bankerbot.png",
        //        gameUpdateStoryReward);
    }

    private void doUpdateStatus() {
        // Please avoid sending duplicate message. Social Media Providers
        // block duplicate messages.

        final String message = mEdtStatusText.getText().toString();
        hideSoftKeyboard();
        mProgressDialog.setMessage("updating status...");
        mProgressDialog.show();
        SoomlaProfile.getInstance().updateStatus(mProvider, message, gameUpdateStatusReward);

        // Or with dialog
        // SoomlaProfile.getInstance().updateStatusDialog(mProvider, "http://www.soom.la", gameUpdateStatusReward);
    }

    private void chooseImageFile() {
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
        photoPickerIntent.setType("image/*");
        startActivityForResult(photoPickerIntent, SELECT_PHOTO_ACTION);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
        super.onActivityResult(requestCode, resultCode, imageReturnedIntent);

        switch (requestCode) {
        case SELECT_PHOTO_ACTION:
            if (resultCode == RESULT_OK) {
                try {
                    final Uri imageUri = imageReturnedIntent.getData();
                    mImagePath = getImagePath(imageUri);
                    final InputStream imageStream = getContentResolver().openInputStream(imageUri);
                    final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
                    mImagePreview.setImageBitmap(selectedImage);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private String getImagePath(Uri uri) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        cursor.moveToFirst();
        String document_id = cursor.getString(0);
        document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
        cursor.close();

        cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,
                MediaStore.Images.Media._ID + " = ? ", new String[] { document_id }, null);
        cursor.moveToFirst();
        String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
        cursor.close();

        return path;
    }

    private void doUploadImage() {
        final String message = mEdtImageText.getText().toString();
        hideSoftKeyboard();

        mProgressDialog.setMessage("uploading image...");
        mProgressDialog.show();
        SoomlaProfile.getInstance().uploadImage(mProvider, message, mImagePath, gameUploadImageReward);
    }

    private void updateUIOnLogin(final IProvider.Provider provider) {
        mBtnShare.setCompoundDrawablesWithIntrinsicBounds(null, null,
                getResources().getDrawable(android.R.drawable.ic_lock_power_off), null);
        mBtnShare.setVisibility(View.VISIBLE);

        mBtnShare.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SoomlaProfile.getInstance().logout(mProvider);
                updateUIOnLogout();
            }
        });

        showView(mPnlStatusUpdate, true);
        showView(mPnlUploadImage, true);
        showView(mPnlStoryUpdate, true);
        mBtnShare.setEnabled(true);

        mBtnUpdateStatus.setEnabled(true);
        mBtnUploadImage.setEnabled(true);
        mBtnUpdateStory.setEnabled(true);
    }

    private void hideSoftKeyboard() {
        if (getCurrentFocus() != null && getCurrentFocus() instanceof EditText) {
            EditText edtCurrentFocusText = (EditText) getCurrentFocus();
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(edtCurrentFocusText.getWindowToken(), 0);
        }
    }

    private void updateUIOnLogout() {

        mBtnUpdateStatus.setEnabled(false);
        mBtnUploadImage.setEnabled(false);
        mBtnUpdateStory.setEnabled(false);

        showView(mProfileBar, false);
        showView(mPnlStatusUpdate, false);
        showView(mPnlUploadImage, false);
        showView(mPnlStoryUpdate, false);

        mProfileAvatar.setImageBitmap(null);
        mProfileName.setText("");

        mBtnShare.setVisibility(View.INVISIBLE);
        mBtnShare.setCompoundDrawablesWithIntrinsicBounds(null, null,
                getResources().getDrawable(android.R.drawable.ic_menu_share), null);
    }

    private void showView(final View view, boolean show) {
        final Animation animation = show ? AnimationUtils.makeInAnimation(view.getContext(), true)
                : AnimationUtils.makeOutAnimation(view.getContext(), true);
        animation.setFillAfter(true);
        animation.setDuration(500);
        view.startAnimation(animation);
    }

    /**
     * @{inheritDoc}
     */
    @Override
    protected void onStart() {
        super.onStart();
        BusProvider.getInstance().register(this);
    }

    /**
     * @{inheritDoc}
     */
    @Override
    protected void onStop() {
        super.onStop();
        BusProvider.getInstance().unregister(this);
    }

    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView imageView;

        public DownloadImageTask(ImageView imageView) {
            this.imageView = imageView;
        }

        protected Bitmap doInBackground(String... urls) {
            String url = urls[0];
            Bitmap bmp = downloadBitmapWithClient(url);

            return bmp;
        }

        // doesn't follow https redirect!
        private Bitmap downloadBitmap(String stringUrl) {
            URL url = null;
            HttpURLConnection connection = null;
            InputStream inputStream = null;

            try {
                url = new URL(stringUrl);
                connection = (HttpURLConnection) url.openConnection();
                connection.setUseCaches(true);
                inputStream = connection.getInputStream();

                return BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
            } catch (Exception e) {
                Log.w(TAG, "Error while retrieving bitmap from " + stringUrl, e);
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }

            return null;
        }

        private Bitmap downloadBitmapWithClient(String url) {
            final AndroidHttpClient httpClient = AndroidHttpClient.newInstance("Android");
            HttpClientParams.setRedirecting(httpClient.getParams(), true);
            final HttpGet request = new HttpGet(url);

            try {
                HttpResponse response = httpClient.execute(request);
                final int statusCode = response.getStatusLine().getStatusCode();

                if (statusCode != HttpStatus.SC_OK) {
                    Header[] headers = response.getHeaders("Location");

                    if (headers != null && headers.length != 0) {
                        String newUrl = headers[headers.length - 1].getValue();
                        // call again with new URL
                        return downloadBitmap(newUrl);
                    } else {
                        return null;
                    }
                }

                final HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream inputStream = null;
                    try {
                        inputStream = entity.getContent();

                        // do your work here
                        return BitmapFactory.decodeStream(inputStream);
                    } finally {
                        if (inputStream != null) {
                            inputStream.close();
                        }
                        entity.consumeContent();
                    }
                }
            } catch (Exception e) {
                request.abort();
            } finally {
                if (httpClient != null) {
                    httpClient.close();
                }
            }

            return null;
        }

        protected void onPostExecute(Bitmap result) {
            imageView.setImageBitmap(result);
        }
    }

    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int byteValue = read();
                    if (byteValue < 0) {
                        break; // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }
}