com.google.cloud.backend.core.CloudBackendFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.google.cloud.backend.core.CloudBackendFragment.java

Source

/*
 * Copyright (c) 2013 Google 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.google.cloud.backend.core;

import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.android.volley.Network;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.BasicNetwork;
import com.android.volley.toolbox.DiskBasedCache;
import com.android.volley.toolbox.HttpStack;
import com.android.volley.toolbox.HurlStack;
import com.android.volley.toolbox.ImageLoader;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.cloud.backend.GCMIntentService;
import com.google.cloud.backend.volleyutil.BitmapLruCache;

import java.io.File;
import java.util.List;

/**
 * An {@link android.app.Fragment} class that allows hosting Activities to access the
 * features and functionalities of the CloudBackend classes, including CRUD of
 * {@link com.google.cloud.backend.core.CloudEntity}, Google account authentication and Google Cloud
 * Messaging.
 */
public class CloudBackendFragment extends Fragment {

    /**
     * onActivityResult code
     */
    private static final int REQUEST_ACCOUNT_PICKER = 2;

    private GoogleAccountCredential mCredential;

    private CloudBackendMessaging mCloudBackend;

    /** Image cache for Volley */
    private ImageLoader.ImageCache mImageCache = new BitmapLruCache();

    /**
     * The listener to use upon completion of certain functions.
     */
    private OnListener callback;

    /**
     * BroadcastReceiver for incoming messages.
     */
    private BroadcastReceiver mMsgReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String token = intent.getStringExtra("token");
            Log.i(Consts.TAG, "A message has been recieved of token: " + token);
            mCloudBackend.handleQueryMessage(token);
        }
    };

    private ImageLoader mImageLoader;

    // Default maximum disk usage in bytes
    private static final int DEFAULT_DISK_USAGE_BYTES = 25 * 1024 * 1024;

    // Default cache folder name
    private static final String DEFAULT_CACHE_DIR = "photos";

    private RequestQueue newRequestQueue(Context context) {
        // define cache folder
        File rootCache = context.getExternalCacheDir();
        if (rootCache == null) {
            rootCache = context.getCacheDir();
        }

        File cacheDir = new File(rootCache, DEFAULT_CACHE_DIR);
        cacheDir.mkdirs();

        HttpStack stack = new HurlStack();
        Network network = new BasicNetwork(stack);
        DiskBasedCache diskBasedCache = new DiskBasedCache(cacheDir, DEFAULT_DISK_USAGE_BYTES);
        RequestQueue queue = new RequestQueue(diskBasedCache, network);
        queue.start();

        return queue;
    }

    /**
     * Returns {@link com.google.cloud.backend.core.CloudBackendMessaging} instance for this activity.
     *
     * @return {@link com.google.cloud.backend.core.CloudBackendMessaging}
     */
    public CloudBackendMessaging getCloudBackend() {
        return mCloudBackend;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            callback = (OnListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnListener");
        }

        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(newRequestQueue(getActivity()), mImageCache);
        }
    }

    /**
     * Subclasses may override this to execute initialization of the activity.
     * If it uses any CloudBackend features, it should be executed inside
     * {@link #onCreateFinished()} that will be called after CloudBackend
     * initializations such as user authentication.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);

        // init backend
        mCloudBackend = new CloudBackendMessaging(getActivity());

        // create credential
        mCredential = GoogleAccountCredential.usingAudience(getActivity(), Consts.AUTH_AUDIENCE);
        mCloudBackend.setCredential(mCredential);

        signInAndSubscribe(false);

        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMsgReceiver,
                new IntentFilter(GCMIntentService.BROADCAST_ON_MESSAGE));
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onDestroy() {
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mMsgReceiver);
        super.onDestroy();
    }

    /**
     * A listener interface for GameActivity to use to process the actions this
     * player makes.
     *
     */
    public interface OnListener {
        public void onCreateFinished();

        public void onBroadcastMessageReceived(List<CloudEntity> message);
    }

    /**
     * Signs in to the application with an account. Subscribes to broadcast messages
     * once the account picking flow has completed, or immediately if there is no
     * authentication required.
     *
     * @param overrideCurrent {@code true} if user can choose an account even if
     *            already signed in, {@code false} if the user can choose an
     *            account only if there is no currently signed in user
     */
    public void signInAndSubscribe(boolean overrideCurrent) {
        if (Consts.IS_AUTH_ENABLED) {
            String accountName = mCloudBackend.getSharedPreferences().getString(Consts.PREF_KEY_ACCOUNT_NAME, null);
            if (accountName == null || overrideCurrent) {
                super.startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
                return;
            } else {
                mCredential.setSelectedAccountName(accountName);
                subscribeToBroadcast();
            }
        } else {
            subscribeToBroadcast();
        }
    }

    private void subscribeToBroadcast() {
        // init subscription to broadcast message
        CloudCallbackHandler<List<CloudEntity>> handler = new CloudCallbackHandler<List<CloudEntity>>() {
            @Override
            public void onComplete(List<CloudEntity> results) {
                callback.onBroadcastMessageReceived(results);
            }
        };
        mCloudBackend.subscribeToCloudMessage(
                com.google.cloud.backend.core.CloudBackendMessaging.TOPIC_ID_BROADCAST, handler);

        callback.onCreateFinished();
    }

    /**
     * Handles callback from Intents like authorization request or account
     * picking. If the hosting Activity also makes use of onActivityResult, make
     * sure the Activity calls super.onActivityResult to handle all
     * requestCodes, including the code here. Forgetting to call the super
     * method is a common mistake and is often cause for confusion.
     */
    @Override
    public final void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        Log.i("result from activity", "resultcode: " + resultCode);
        switch (requestCode) {
        case REQUEST_ACCOUNT_PICKER:
            if (data != null && data.getExtras() != null) {

                // set the picked account name to the credential
                String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                mCredential.setSelectedAccountName(accountName);

                // save account name to shared pref
                SharedPreferences.Editor e = mCloudBackend.getSharedPreferences().edit();
                e.putString(Consts.PREF_KEY_ACCOUNT_NAME, accountName);
                e.commit();
            }

            // post create initialization
            subscribeToBroadcast();
            break;
        }
    }

    /**
     * Returns account name selected by user, or null if any account is
     * selected.
     */
    protected String getAccountName() {
        return mCredential == null ? null : mCredential.getSelectedAccountName();
    }

    /**
     * Returns the reference of the ImageLoader for Volley.
     * @return
     */
    public ImageLoader getImageLoader() {
        return mImageLoader;
    }
}