com.jose.castsocialconnector.main.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.jose.castsocialconnector.main.MainActivity.java

Source

/*
 * Copyright (C) 2014 Google Inc. All Rights Reserved. 
 *
 * 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.jose.castsocialconnector.main;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.MediaRouteActionProvider;
import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter;
import android.support.v7.media.MediaRouter.RouteInfo;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;

import com.google.android.gms.cast.ApplicationMetadata;
import com.google.android.gms.cast.Cast;
import com.google.android.gms.cast.Cast.ApplicationConnectionResult;
import com.google.android.gms.cast.Cast.MessageReceivedCallback;
import com.google.android.gms.cast.CastDevice;
import com.google.android.gms.cast.CastMediaControlIntent;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.jose.castsocialconnector.R;
import com.jose.castsocialconnector.castMessagesCallback.ContactsSendMessageCallBack;
import com.jose.castsocialconnector.castMessagesCallback.PagePhotoReadyMessageCallBack;
import com.jose.castsocialconnector.castMessagesCallback.SendMailMessageCallBack;
import com.jose.castsocialconnector.config.Config;
import com.jose.castsocialconnector.instagram.InstagramApi;
import com.jose.castsocialconnector.message.authentication.OnTokenAcquired;
import com.jose.castsocialconnector.message.receive.GetEmailService;
import com.jose.castsocialconnector.photo.NewPhotosService;
import com.jose.castsocialconnector.xml.XmlContact;
import com.jose.castsocialconnector.xml.XmlParser;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * Main activity to send messages to the receiver.
 */
public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private MediaRouter mMediaRouter;
    private MediaRouteSelector mMediaRouteSelector;
    private MediaRouter.Callback mMediaRouterCallback;
    private CastDevice mSelectedDevice;
    private GoogleApiClient mApiClient;
    private Cast.Listener mCastListener;
    private ConnectionCallbacks mConnectionCallbacks;
    private ConnectionFailedListener mConnectionFailedListener;
    private HelloWorldChannel mHelloWorldChannel;
    private boolean mApplicationStarted;
    private boolean mWaitingForReconnect;
    private String mSessionId;

    // email settings
    public String oauthToken;

    // messages
    private AccountManager accountManager;
    private GetEmailService getEmailService;

    // Contacts
    public static ArrayList<XmlContact> xmlContacts;
    public XmlContact userContact;
    public XmlContact currentContact;

    // Instagram
    public static String instagramToken;
    public static InstagramApi instagramApi;

    // SharedPreferences
    private SharedPreferences settings;

    // new photos
    private NewPhotosService newPhotosService;
    public static ScheduledFuture newPhotosSchedule;

    // font-families
    Typeface typeFaceNormal;
    Typeface typeFaceBold;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        typeFaceNormal = Typeface.createFromAsset(getAssets(), "font/DroidSans.ttf");
        typeFaceBold = Typeface.createFromAsset(getAssets(), "font/DroidSans-Bold.ttf");

        // Configure Cast device discovery
        mMediaRouter = MediaRouter.getInstance(getApplicationContext());
        mMediaRouteSelector = new MediaRouteSelector.Builder().addControlCategory(
                CastMediaControlIntent.categoryForCast(getResources().getString(R.string.app_id))).build();
        mMediaRouterCallback = new MyMediaRouterCallback();

        writeTempFile();

        // set contacts from xml file
        xmlContacts = XmlParser.parseContactsXml();
        userContact = XmlParser.parseOwnerXml();

        // connect to email
        getEmailService = new GetEmailService(this);
        accountManager = AccountManager.get(this);
        Account[] accounts = accountManager.getAccountsByType("com.google");
        onAccountSelected(accounts[0]);

        // instagram
        instagramApi = new InstagramApi(this);

        // get instagram token
        settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        getInstagramInfo();

        //New Photos
        newPhotosService = new NewPhotosService(this);
        startCheckNewDataService();

        // default fragment
        showConnectWarningFragment();
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        setActionBarStyle();
    }

    private void setActionBarStyle() {

        ActionBar actionBar = getSupportActionBar();
        actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00B2A6")));

        this.getSupportActionBar().setDisplayShowCustomEnabled(true);
        this.getSupportActionBar().setDisplayShowTitleEnabled(false);

        LayoutInflater inflator = LayoutInflater.from(this);
        View v = inflator.inflate(R.layout.action_bar, null);

        ((TextView) v.findViewById(R.id.title)).setText(this.getTitle());
        ((TextView) v.findViewById(R.id.title)).setTypeface(typeFaceBold);
        ((TextView) v.findViewById(R.id.title)).setTextColor(Color.parseColor("#FFFFFF"));
        this.getSupportActionBar().setCustomView(v);
    }

    private void showConnectWarningFragment() {
        ConnectWarningFragment menuFragment = new ConnectWarningFragment();
        menuFragment.setmMediaRouteSelector(mMediaRouteSelector);

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.fragment_container, menuFragment).addToBackStack("");
        transaction.commit();
    }

    private void startCheckNewDataService() {
        ScheduledExecutorService scheduleCheckMessagesTaskExecutor;
        scheduleCheckMessagesTaskExecutor = Executors.newScheduledThreadPool(5);
        if (!Config.DEBUG)
            newPhotosSchedule = scheduleCheckMessagesTaskExecutor
                    .scheduleAtFixedRate(newPhotosService.getRunnable(), 0, 1, TimeUnit.MINUTES);
    }

    public void writeTempFile() {
        File myFile = new File(Environment.getExternalStorageDirectory(), "SocialConnContacts.xml");
        try {
            FileOutputStream fOut = new FileOutputStream(myFile);
            OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
            myOutWriter.append(
                    "<?xml version=\"1.0\"?> <owners> <owner> <id>0</id> <nickname>Jose</nickname> <photo></photo> <email>jose.wt@gmail.com</email> <skype>ochoadelorenzi</skype> <instagram></instagram> </owner> </owners> <contacts> <contact> <id>0</id> <nickname>Natalia</nickname> <photo>http://www.expertoanimal.com/es/images/9/7/5/img_nombres_para_perros_originales_y_bonitos_5579_paso_1_600.jpg</photo> <email>jose.wt@gmail.com</email> <skype>ochoadelorenzi</skype> <instagram></instagram> </contact> <contact> <id>1</id> <nickname>Javiera</nickname> <photo>http://www.estudiantes.info/ciencias_naturales/images/leonpadre2.jpg</photo> <email>jose.wt@gmail.com</email> <skype>nat_saintmartins</skype> <instagram></instagram> </contact> <contact> <id>2</id> <nickname>Victor</nickname> <photo>http://cdn.20m.es/img2/recortes/2012/01/10/44326-857-550.jpg</photo> <email>jose.wt@gmail.com</email> <skype>carla.sambrizzi</skype> <instagram></instagram> </contact> <contact> <id>3</id> <nickname>Luis</nickname> <photo>http://4.bp.blogspot.com/-F8VTQuaZvuQ/Vl9gw0xGV2I/AAAAAAAADT8/mNmXSbTuiXw/s1600/New-Mixed-HD-Wallpapers-Pack-50_igoryk06-43.jpg</photo> <email>juan.ochoa@ug.uchile.cl</email> <skype>juanma8a</skype> <instagram></instagram> </contact> </contacts>");
            //            myOutWriter.append("<?xml version=\"1.0\"?> <owners> <owner> <id>0</id> <nickname>Jose</nickname> <photo></photo> <email>jose.wt@gmail.com</email> <skype>ochoadelorenzi</skype> <instagram></instagram> </owner> </owners> <contacts> <contact> <id>1</id> <nickname>Natalia</nickname> <photo> http://a5.mzstatic.com/us/r30/Purple5/v4/5a/2e/e9/5a2ee9b3-8f0e-4f8b-4043-dd3e3ea29766/icon128-2x.png </photo> <email>nacha.sanmartin@gmail.com</email> <skype>nat_saintmartins</skype> <instagram>nat_saintmartins</instagram> </contact> </contacts>");
            //            myOutWriter.append("<?xml version=\"1.0\"?> <owners> <owner> <id>0</id> <nickname>Jose</nickname> <photo></photo> <email>jose.wt@gmail.com</email> <skype>ochoadelorenzi</skype> <instagram></instagram> </owner> </owners> <contacts><contact> <id>0</id> <nickname>Jose</nickname> <photo> http://comicsalliance.com/files/2012/07/asmsdccpanelmain-1342466154.jpg </photo> <email>jose.wt@gmail.com</email> <skype>ochoadelorenzi</skype> <instagram></instagram> </contact>  <contact> <id>1</id> <nickname>Natalia</nickname> <photo> http://a5.mzstatic.com/us/r30/Purple5/v4/5a/2e/e9/5a2ee9b3-8f0e-4f8b-4043-dd3e3ea29766/icon128-2x.png </photo> <email>nacha.sanmartin@gmail.com</email> <skype>nat_saintmartins</skype> <instagram>nat_saintmartins</instagram> </contact> </contacts>");
            myOutWriter.close();
            fOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void onAccountSelected(final Account account) {
        userContact.setEmail(account.name);
        accountManager.getAuthToken(account, "oauth2:https://mail.google.com/", null, this,
                new OnTokenAcquired(this, account), null);
    }

    private void getInstagramInfo() {
        String auth_token_string = settings.getString(getApplicationContext().getString(R.string.instagram_token),
                "");
        instagramToken = auth_token_string;
        instagramApi.searchSelf();
        instagramApi.getFollowingInfo();
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Start media router discovery
        mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
                MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
    }

    @Override
    protected void onStop() {
        // End media router discovery
        mMediaRouter.removeCallback(mMediaRouterCallback);
        super.onStop();
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        teardown(true);
        newPhotosSchedule.cancel(true);
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.main, menu);
        MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
        MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat
                .getActionProvider(mediaRouteMenuItem);
        // Set the MediaRouteActionProvider selector for device discovery.
        mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector);
        return true;
    }

    /**
     * Callback for MediaRouter events
     */
    private class MyMediaRouterCallback extends MediaRouter.Callback {

        @Override
        public void onRouteSelected(MediaRouter router, RouteInfo info) {
            Log.d(TAG, "onRouteSelected");
            // Handle the user route selection.
            mSelectedDevice = CastDevice.getFromBundle(info.getExtras());

            launchReceiver();
        }

        @Override
        public void onRouteUnselected(MediaRouter router, RouteInfo info) {
            Log.d(TAG, "onRouteUnselected: info=" + info);
            teardown(false);
            mSelectedDevice = null;
            showConnectWarningFragment();
        }
    }

    /**
     * Start the receiver app
     */
    private void launchReceiver() {
        try {
            mCastListener = new Cast.Listener() {

                @Override
                public void onApplicationDisconnected(int errorCode) {
                    Log.d(TAG, "application has stopped");
                    teardown(true);
                }

            };
            // Connect to Google Play services
            mConnectionCallbacks = new ConnectionCallbacks();
            mConnectionFailedListener = new ConnectionFailedListener();
            Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions.builder(mSelectedDevice, mCastListener);
            mApiClient = new GoogleApiClient.Builder(this).addApi(Cast.API, apiOptionsBuilder.build())
                    .addConnectionCallbacks(mConnectionCallbacks)
                    .addOnConnectionFailedListener(mConnectionFailedListener).build();

            mApiClient.connect();
        } catch (Exception e) {
            Log.e(TAG, "Failed launchReceiver", e);
        }
    }

    /**
     * Google Play services callbacks
     */
    private class ConnectionCallbacks implements GoogleApiClient.ConnectionCallbacks {

        @Override
        public void onConnected(Bundle connectionHint) {
            Log.d(TAG, "onConnected");

            if (mApiClient == null) {
                // We got disconnected while this runnable was pending
                // execution.
                return;
            }

            try {
                if (mWaitingForReconnect) {
                    mWaitingForReconnect = false;

                    // Check if the receiver app is still running
                    if ((connectionHint != null) && connectionHint.getBoolean(Cast.EXTRA_APP_NO_LONGER_RUNNING)) {
                        Log.d(TAG, "App  is no longer running");
                        teardown(true);
                    } else {
                        // Re-create the custom message channel
                        try {
                            Cast.CastApi.setMessageReceivedCallbacks(mApiClient, mHelloWorldChannel.getNamespace(),
                                    mHelloWorldChannel);
                        } catch (IOException e) {
                            Log.e(TAG, "Exception while creating channel", e);
                        }
                    }
                } else {
                    // Launch the receiver app
                    Cast.CastApi.launchApplication(mApiClient, getString(R.string.app_id), false)
                            .setResultCallback(new ResultCallback<Cast.ApplicationConnectionResult>() {
                                @Override
                                public void onResult(ApplicationConnectionResult result) {
                                    Status status = result.getStatus();
                                    Log.d(TAG, "ApplicationConnectionResultCallback.onResult:"
                                            + status.getStatusCode());
                                    if (status.isSuccess()) {
                                        ApplicationMetadata applicationMetadata = result.getApplicationMetadata();
                                        mSessionId = result.getSessionId();
                                        String applicationStatus = result.getApplicationStatus();
                                        boolean wasLaunched = result.getWasLaunched();
                                        Log.d(TAG,
                                                "application name: " + applicationMetadata.getName() + ", status: "
                                                        + applicationStatus + ", sessionId: " + mSessionId
                                                        + ", wasLaunched: " + wasLaunched);
                                        mApplicationStarted = true;

                                        // Create the custom message
                                        // channel
                                        mHelloWorldChannel = new HelloWorldChannel();
                                        try {
                                            Cast.CastApi.setMessageReceivedCallbacks(mApiClient,
                                                    mHelloWorldChannel.getNamespace(), mHelloWorldChannel);

                                            ContactsSendMessageCallBack contactsSendMessageCallBack = new ContactsSendMessageCallBack(
                                                    MainActivity.this);
                                            PagePhotoReadyMessageCallBack pagePhotoReadyMessageCallBack = new PagePhotoReadyMessageCallBack(
                                                    MainActivity.this);
                                            SendMailMessageCallBack sendMailMessageCallBack = new SendMailMessageCallBack(
                                                    MainActivity.this, userContact.getEmail(), oauthToken);

                                            Cast.CastApi.setMessageReceivedCallbacks(mApiClient,
                                                    contactsSendMessageCallBack.getNamespace(),
                                                    contactsSendMessageCallBack);

                                            Cast.CastApi.setMessageReceivedCallbacks(mApiClient,
                                                    getString(R.string.photo_seen_namespace), newPhotosService);

                                            Cast.CastApi.setMessageReceivedCallbacks(mApiClient,
                                                    pagePhotoReadyMessageCallBack.getNamespace(),
                                                    pagePhotoReadyMessageCallBack);

                                            Cast.CastApi.setMessageReceivedCallbacks(mApiClient,
                                                    sendMailMessageCallBack.getNamespace(),
                                                    sendMailMessageCallBack);

                                            MenuFragment menuFragment = new MenuFragment();
                                            FragmentManager fragmentManager = getFragmentManager();
                                            FragmentTransaction transaction = fragmentManager.beginTransaction();
                                            transaction.replace(R.id.fragment_container, menuFragment)
                                                    .addToBackStack("");
                                            transaction.commit();

                                        } catch (IOException e) {
                                            Log.e(TAG, "Exception while creating channel", e);
                                        }

                                    } else {
                                        Log.e(TAG, "application could not launch");
                                        teardown(true);
                                    }
                                }
                            });
                }
            } catch (Exception e) {
                Log.e(TAG, "Failed to launch application", e);
            }
        }

        @Override
        public void onConnectionSuspended(int cause) {
            Log.d(TAG, "onConnectionSuspended");
            mWaitingForReconnect = true;
            showConnectWarningFragment();
        }
    }

    /**
     * Google Play services callbacks
     */
    private class ConnectionFailedListener implements GoogleApiClient.OnConnectionFailedListener {

        @Override
        public void onConnectionFailed(ConnectionResult result) {
            Log.e(TAG, "onConnectionFailed ");

            teardown(false);
        }
    }

    /**
     * Tear down the connection to the receiver
     */
    private void teardown(boolean selectDefaultRoute) {
        Log.d(TAG, "teardown");
        if (mApiClient != null) {
            if (mApplicationStarted) {
                if (mApiClient.isConnected() || mApiClient.isConnecting()) {
                    try {
                        Cast.CastApi.stopApplication(mApiClient, mSessionId);
                        if (mHelloWorldChannel != null) {
                            Cast.CastApi.removeMessageReceivedCallbacks(mApiClient,
                                    mHelloWorldChannel.getNamespace());
                            Cast.CastApi.removeMessageReceivedCallbacks(mApiClient,
                                    getString(R.string.send_message_select_contact_namespace));
                            Cast.CastApi.removeMessageReceivedCallbacks(mApiClient,
                                    getString(R.string.photo_seen_namespace));
                            Cast.CastApi.removeMessageReceivedCallbacks(mApiClient,
                                    getString(R.string.album_photos_ready));
                            Cast.CastApi.removeMessageReceivedCallbacks(mApiClient, getString(R.string.send_mail));
                            mHelloWorldChannel = null;
                        }
                    } catch (IOException e) {
                        Log.e(TAG, "Exception while removing channel", e);
                    }
                    mApiClient.disconnect();
                }
                mApplicationStarted = false;
            }
            mApiClient = null;
        }
        if (selectDefaultRoute) {
            mMediaRouter.selectRoute(mMediaRouter.getDefaultRoute());
        }
        mSelectedDevice = null;
        mWaitingForReconnect = false;
        mSessionId = null;
    }

    class HelloWorldChannel implements MessageReceivedCallback {

        /**
         * @return custom namespace
         */
        public String getNamespace() {
            return getString(R.string.namespace);
        }

        /*
         * Receive message from the receiver app
         */
        @Override
        public void onMessageReceived(CastDevice castDevice, String namespace, String message) {
            Log.d(TAG, "onMessageReceived: " + namespace + message);
        }

    }

    public GoogleApiClient getmApiClient() {
        return mApiClient;
    }

    public NewPhotosService getNewPhotosService() {
        return newPhotosService;
    }

    public void setOauthToken(String oauthToken) {
        this.oauthToken = oauthToken;
    }

    public String getOauthToken() {
        return oauthToken;
    }

    public XmlContact getUserContact() {
        return userContact;
    }

    public GetEmailService getGetEmailService() {
        return getEmailService;
    }

    @Override
    public void onBackPressed() {
        Fragment f = getFragmentManager().findFragmentById(R.id.fragment_container);
        if (f instanceof BaseFragment)
            ((BaseFragment) f).onBackPressed();
        else
            super.onBackPressed();
    }
}