com.fordemobile.livepaintings.FragmentPagerSupport.java Source code

Java tutorial

Introduction

Here is the source code for com.fordemobile.livepaintings.FragmentPagerSupport.java

Source

/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.fordemobile.livepaintings;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.fordemobile.billing.BillingRequest.RequestPurchase;
import com.fordemobile.billing.BillingRequest.RestoreTransactions;
import com.fordemobile.billing.BillingRequest.Result;
import com.fordemobile.billing.BillingService;
import com.fordemobile.billing.PurchaseDatabase;
import com.fordemobile.billing.PurchaseObserver;
import com.fordemobile.billing.ResponseHandler;
import com.fordemobile.billing.Security.PurchaseState;

public class FragmentPagerSupport extends FragmentActivity {

    private final static String TAG = "FragmentPagerSupport";
    private final static int DIALOG_PURCHASE_CONFIRMATION = 0;
    private static final int REQUEST_CODE = 0;

    private BillingService mBillingService;
    private PurchaseDatabase mPurchaseDatabase;
    private Handler mHandler;
    private Set<String> mOwnedItems = new HashSet<String>();
    private UserPurchaseObserver mUserPurchaseObserver;
    private static final int DIALOG_BILLING_NOT_SUPPORTED_ID = 0;
    private boolean purchaseEnable;
    private boolean hasBought;

    /**
     * A {@link PurchaseObserver} is used to get callbacks when Android Market
     * sends messages to this application so that we can update the UI.
     */
    private class UserPurchaseObserver extends PurchaseObserver {

        public UserPurchaseObserver(Handler handler) {
            super(FragmentPagerSupport.this, handler);
        }

        @Override
        public void onBillingSupported(boolean supported) {
            updatePurchaseview(supported);
        }

        @Override
        public void onPurchaseStateChange(PurchaseState purchaseState, String itemId, int quantity,
                long purchaseTime, String developerPayload) {
            if (purchaseState == PurchaseState.PURCHASED) {
                FragmentPagerSupport.this.mOwnedItems.add(itemId);
                notifyUser(R.string.purchase_status, R.string.purchase_successful);
            } else if (purchaseState == PurchaseState.REFUNDED) {
                notifyUser(R.string.purchase_status, R.string.purchase_refunded);
            }
            doInitializeOwnedItems();
        }

        @Override
        public void onRequestPurchaseResponse(RequestPurchase request, Result result) {
            if (result == Result.OK) {
                notifyUser(R.string.purchase_status, R.string.purchase_pending);
            } else if (result == Result.USER_CANCELED) {
                notifyUser(R.string.purchase_status, R.string.purchase_canceled);
            } else if (result == Result.ERROR) {
                notifyUser(R.string.purchase_status, R.string.purchase_error);
            } else if (result == Result.DEVELOPER_ERROR) {
                notifyUser(R.string.purchase_status, R.string.purchase_problem);
            } else if (result == Result.SERVICE_UNAVAILABLE) {
                notifyUser(R.string.purchase_status, R.string.purchase_problem);
            } else if (result == Result.ITEM_UNAVAILABLE) {
                notifyUser(R.string.purchase_status, R.string.item_unavailable);
            } else if (result == Result.BILLING_UNAVAILABLE) {
                notifyUser(R.string.purchase_status, R.string.billing_unavailable);
            }
        }

        @Override
        public void onRestoreTransactionsResponse(RestoreTransactions request, Result result) {
        }
    }

    public void updatePurchaseview(boolean purchaseEnable) {
        this.purchaseEnable = purchaseEnable;
    }

    /**
     * Creates a background thread that reads the database and initializes the
     * set of owned items.
     */
    private void initializeOwnedItems() {
        new Thread(new Runnable() {
            public void run() {
                doInitializeOwnedItems();
            }
        }).start();
    }

    /**
     * Reads the set of purchased items from the database in a background thread
     * and then adds those items to the set of owned items in the main UI
     * thread.
     */
    private void doInitializeOwnedItems() {
        Cursor cursor = this.mPurchaseDatabase.queryAllPurchasedItems();
        if (cursor == null) {
            return;
        }

        final Set<String> ownedItems = new HashSet<String>();
        try {
            int productIdCol = cursor.getColumnIndexOrThrow(PurchaseDatabase.PURCHASED_PRODUCT_ID_COL);
            while (cursor.moveToNext()) {
                String productId = cursor.getString(productIdCol);
                ownedItems.add(productId);
            }
        } finally {
            cursor.close();
        }

        // We will add the set of owned items in a new Runnable that runs on
        // the UI thread so that we don't need to synchronize access to
        // mOwnedItems.
        this.mHandler.post(new Runnable() {
            public void run() {
                FragmentPagerSupport.this.mOwnedItems.addAll(ownedItems);
                updateDisplay();
            }
        });
    }

    private void updateDisplay() {

        if (mOwnedItems.contains(Consts.PACK_001)) {
            this.hasBought = true;
            this.pager.getAdapter().notifyDataSetChanged();
        }
    }

    public void notifyUser(int titleId, int messageId) {
        String ns = Context.NOTIFICATION_SERVICE;
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

        int icon = R.drawable.icon;
        long when = System.currentTimeMillis();

        Notification notification = new Notification(icon, getString(titleId), when);

        Context context = getApplicationContext();
        CharSequence contentTitle = getString(titleId);
        CharSequence contentText = getString(messageId);
        Intent notificationIntent = new Intent(this, FragmentPagerSupport.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
        mNotificationManager.notify(0, notification);
    }

    /**
     * Called when this activity is no longer visible.
     */
    @Override
    protected void onStop() {
        super.onStop();
        ResponseHandler.unregister(this.mUserPurchaseObserver);
        //      ((ViewPagerAdapter)this.pager.getAdapter()).recycle();
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case DIALOG_BILLING_NOT_SUPPORTED_ID:
            return createDialog(R.string.billing_not_supported_title, R.string.billing_not_supported_message);
        default:
            return null;
        }
    }

    private Dialog createDialog(int titleId, int messageId) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(titleId).setIcon(android.R.drawable.stat_sys_warning).setMessage(messageId)
                .setCancelable(false).setPositiveButton(android.R.string.ok, null);
        return builder.create();
    }

    public class ViewPagerAdapter extends PagerAdapter implements OnTouchListener, OnClickListener {
        private Context context;
        private List<Painting> paintings;
        private Typeface tf;

        public ViewPagerAdapter(Context context) {
            tf = Typeface.createFromAsset(getAssets(), "fonts/Poly-Regular.ttf");
            this.context = context;
            this.paintings = new ArrayList<Painting>();

            try {
                String lists[] = getResources().getAssets().list("paintings");
                for (String paint : lists) {
                    Painting painting = new Painting("paintings/" + paint + "/", 0, 0);
                    this.paintings.add(painting);
                }
                Collections.sort(this.paintings, new Comparator<Painting>() {
                    public int compare(Painting lhs, Painting rhs) {
                        return lhs.getDate().compareTo(rhs.getDate());
                    };
                });
                Log.i(TAG, "List:" + this.paintings.size());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void destroyItem(View pager, int position, Object view) {
            ((ViewPager) pager).removeView((View) view);
            Painting painting = paintings.get(position);
            painting.recycle();
        }

        public void recycle() {
            int currentItem = pager.getCurrentItem();
            Painting painting = paintings.get(currentItem);
            painting.recycle();
        }

        @Override
        public void finishUpdate(View view) {
        }

        @Override
        public int getCount() {
            return this.paintings.size();
        }

        @Override
        public Object instantiateItem(View pager, int position) {
            LayoutInflater layoutInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            Painting painting = paintings.get(position);
            painting.loadPreview();
            View v = null;
            if (painting.isLandscape()) {
                v = layoutInflater.inflate(R.layout.fragment_pager_list, null);
            } else {
                v = layoutInflater.inflate(R.layout.fragment_pager_list_portrait, null);
            }
            TextView descriptionTextView = (TextView) v.findViewById(R.id.descriptionTextView);
            descriptionTextView.setTypeface(tf);
            ImageView previewImageView = (ImageView) v.findViewById(R.id.previewImageView);
            if (painting.getArtistName().trim().isEmpty()) {
                descriptionTextView.setText(getString(R.string.request_description));
            } else {
                descriptionTextView.setText(Html.fromHtml(painting.getDescription()));
            }
            previewImageView.setImageBitmap(painting.getPreviewImage());
            ((ViewPager) pager).addView(v, 0);

            ImageView buyFullVersionButton = (ImageView) v.findViewById(R.id.buyFullVersionButton);
            buyFullVersionButton.setOnClickListener(this);

            View forsaleImage = v.findViewById(R.id.forSaleView);
            if (FragmentPagerSupport.this.hasBought || (!Consts.DEBUG && painting.isForSale())) {
                if (purchaseEnable) {
                    // display sale views
                    buyFullVersionButton.setVisibility(View.VISIBLE);
                    forsaleImage.setVisibility(View.VISIBLE);
                    ColorMatrix cm = new ColorMatrix();
                    cm.setSaturation(0);
                    ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm);
                    previewImageView.setColorFilter(filter);
                } else {
                    // TODO display purchase impossible
                    buyFullVersionButton.setVisibility(View.GONE);
                }
            } else {
                // remove sale views
                previewImageView.setOnTouchListener(this);
                forsaleImage.setVisibility(View.GONE);
                buyFullVersionButton.setVisibility(View.GONE);
            }

            ImageView setAsWallpaperButton = (ImageView) v.findViewById(R.id.setAsWallpaperButton);
            setAsWallpaperButton.setOnClickListener(this);
            Log.i(TAG, "Inflate");

            return v;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view.equals(object);
        }

        @Override
        public void restoreState(Parcelable p, ClassLoader c) {
        }

        @Override
        public Parcelable saveState() {
            return null;
        }

        @Override
        public void startUpdate(View view) {
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            ImageView previewImageView = (ImageView) v;
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                previewImageView.setColorFilter(new LightingColorFilter(0xFFF1C40E, 0x00000000));
                break;
            case MotionEvent.ACTION_UP:
                int currentItem = pager.getCurrentItem();
                Painting painting = paintings.get(currentItem);
                if (painting.getArtistName().trim().isEmpty()) {
                    final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

                    /* Fill it with Data */
                    emailIntent.setType("plain/text");
                    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
                            new String[] { "livepaintings@fordemobile.com" });
                    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(R.string.request_subject));
                    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, getString(R.string.request_message));

                    /* Send it off to the Activity-Chooser */
                    this.context.startActivity(Intent.createChooser(emailIntent, getString(R.string.request_send)));
                } else {
                    previewImageView.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x00000000));
                    SharedPreferences prefs = getSharedPreferences(Consts.SHARED_PREFS_NAME, 0);
                    SharedPreferences.Editor edit = prefs.edit();
                    edit.putString(Consts.PREF_PAINTING, painting.getDirectoryPath());
                    edit.commit();

                    Toast.makeText(this.context, painting.getName() + " " + getString(R.string.set_as_painting),
                            Toast.LENGTH_SHORT).show();
                }
                break;
            }
            return true;
        }

        @Override
        public void onClick(View v) {

            switch (v.getId()) {
            case R.id.setAsWallpaperButton:
                // install button
                Toast toast = Toast.makeText(this.context, R.string.choose_live_paintings, Toast.LENGTH_LONG);
                toast.show();

                Intent intent = new Intent();
                intent.setAction(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER);
                startActivityForResult(intent, REQUEST_CODE);
                break;
            case R.id.buyFullVersionButton:
                // buy full version
                try {
                    if (!FragmentPagerSupport.this.mBillingService.requestPurchase(Consts.PACK_001,
                            "Full Version")) {
                        showDialog(FragmentPagerSupport.DIALOG_BILLING_NOT_SUPPORTED_ID);
                    }
                } catch (NullPointerException e) {
                    showDialog(FragmentPagerSupport.DIALOG_BILLING_NOT_SUPPORTED_ID);
                }
                break;
            default:
                break;
            }
        }
    }

    private ViewPager pager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_pager);
        HardwareManager.initialize(this);

        this.pager = (ViewPager) findViewById(R.id.pager);
        this.pager.setAdapter(new ViewPagerAdapter(this));

        this.mHandler = new Handler();
        this.mUserPurchaseObserver = new UserPurchaseObserver(this.mHandler);

        this.mBillingService = new BillingService();
        this.mBillingService.setContext(this);

        this.mPurchaseDatabase = new PurchaseDatabase(this);

        // Check if billing is supported.
        ResponseHandler.register(this.mUserPurchaseObserver);
        if (this.mBillingService.checkBillingSupported()) {
            updatePurchaseview(false);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        ResponseHandler.register(this.mUserPurchaseObserver);
        initializeOwnedItems();

        Toast.makeText(this, R.string.choose_painting, Toast.LENGTH_SHORT).show();
    }

    // @Override
    // protected Dialog onCreateDialog(int id) {
    // AlertDialog.Builder builder = new AlertDialog.Builder(this);
    // builder.setTitle(R.string.purchase).setMessage(R.string.purchase_question)
    // .setPositiveButton(R.string., new DialogInterface.OnClickListener() {
    // public void onClick(DialogInterface dialog, int id) {
    // MyActivity.this.finish();
    // }
    // })
    // .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener()
    // {
    // public void onClick(DialogInterface dialog, int id) {
    // dialog.cancel();
    // });
    //
    // return super.onCreateDialog(id);
    // }
}