com.ctrlplusz.dashclock.yr.configuration.AppChooserPreference.java Source code

Java tutorial

Introduction

Here is the source code for com.ctrlplusz.dashclock.yr.configuration.AppChooserPreference.java

Source

/*
 * Copyright 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.ctrlplusz.dashclock.yr.configuration;

import com.ctrlplusz.dashclock.yr.R;
import com.ctrlplusz.dashclock.yr.ui.SimplePagedTabsHelper;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.Preference;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * A preference that allows the user to choose an application or shortcut.
 */
public class AppChooserPreference extends Preference {
    private boolean mAllowUseDefault = false;

    public AppChooserPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs, 0);
    }

    public AppChooserPreference(Context context) {
        super(context);
        initAttrs(null, 0);
    }

    public AppChooserPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initAttrs(attrs, defStyle);
    }

    private void initAttrs(AttributeSet attrs, int defStyle) {
        TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.AppChooserPreference,
                defStyle, defStyle);

        try {
            mAllowUseDefault = a.getBoolean(R.styleable.AppChooserPreference_allowUseDefault, true);
        } finally {
            a.recycle();
        }
    }

    public void setIntentValue(Intent intent) {
        setValue(intent == null ? "" : intent.toUri(Intent.URI_INTENT_SCHEME));
    }

    public void setValue(String value) {
        if (callChangeListener(value)) {
            persistString(value);
            notifyChanged();
        }
    }

    public static Intent getIntentValue(String value, Intent defaultIntent) {
        try {
            if (TextUtils.isEmpty(value)) {
                return defaultIntent;
            }

            return Intent.parseUri(value, Intent.URI_INTENT_SCHEME);
        } catch (URISyntaxException e) {
            return defaultIntent;
        }
    }

    public static CharSequence getDisplayValue(Context context, String value) {
        if (TextUtils.isEmpty(value)) {
            return context.getString(R.string.pref_yr_shortcut_default);
        }

        Intent intent;
        try {
            intent = Intent.parseUri(value, Intent.URI_INTENT_SCHEME);
        } catch (URISyntaxException e) {
            return context.getString(R.string.pref_yr_shortcut_default);
        }

        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
        if (resolveInfos.size() == 0) {
            return null;
        }

        StringBuilder label = new StringBuilder();
        label.append(resolveInfos.get(0).loadLabel(pm));
        if (intent.getData() != null && intent.getData().getScheme() != null
                && intent.getData().getScheme().startsWith("http")) {
            label.append(": ").append(intent.getDataString());
        }
        return label;
    }

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

        AppChooserDialogFragment fragment = AppChooserDialogFragment.newInstance();
        fragment.setPreference(this);

        Activity activity = (Activity) getContext();
        activity.getFragmentManager().beginTransaction().add(fragment, getFragmentTag()).commit();
    }

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

        Activity activity = (Activity) getContext();
        AppChooserDialogFragment fragment = (AppChooserDialogFragment) activity.getFragmentManager()
                .findFragmentByTag(getFragmentTag());
        if (fragment != null) {
            // re-bind preference to fragment
            fragment.setPreference(this);
        }
    }

    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        return a.getString(index);
    }

    @Override
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
        setValue(restoreValue ? getPersistedString("") : (String) defaultValue);
    }

    public String getFragmentTag() {
        return "app_chooser_" + getKey();
    }

    public static class AppChooserDialogFragment extends DialogFragment {
        public static int REQUEST_CREATE_SHORTCUT = 1;

        private AppChooserPreference mPreference;

        public AppChooserDialogFragment() {
        }

        public static AppChooserDialogFragment newInstance() {
            return new AppChooserDialogFragment();
        }

        public void setPreference(AppChooserPreference preference) {
            mPreference = preference;
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Force Holo Light since ?android:actionBarXX would use dark action bar
            Context layoutContext = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light);

            LayoutInflater layoutInflater = LayoutInflater.from(layoutContext);
            View rootView = layoutInflater.inflate(R.layout.dialog_app_chooser, null);
            final ViewGroup tabWidget = (ViewGroup) rootView.findViewById(android.R.id.tabs);
            final ViewPager pager = (ViewPager) rootView.findViewById(R.id.pager);
            pager.setPageMargin((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16,
                    getResources().getDisplayMetrics()));

            SimplePagedTabsHelper helper = new SimplePagedTabsHelper(layoutContext, tabWidget, pager);
            helper.addTab(R.string.title_apps, R.id.apps_list);
            helper.addTab(R.string.title_shortcuts, R.id.shortcuts_list);

            // Set up apps
            final ActivityListAdapter appsAdapter = new ActivityListAdapter(
                    new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER),
                    mPreference.mAllowUseDefault);
            ListView appsList = (ListView) rootView.findViewById(R.id.apps_list);
            appsList.setAdapter(appsAdapter);
            appsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> listView, View view, int position, long itemId) {
                    Intent intent = appsAdapter.getIntent(position);
                    if (intent != null) {
                        intent = Intent.makeMainActivity(intent.getComponent());
                    }
                    mPreference.setIntentValue(intent);
                    dismiss();
                }
            });

            // Set up shortcuts
            final ActivityListAdapter shortcutsAdapter = new ActivityListAdapter(
                    new Intent(Intent.ACTION_CREATE_SHORTCUT).addCategory(Intent.CATEGORY_DEFAULT), false);
            ListView shortcutsList = (ListView) rootView.findViewById(R.id.shortcuts_list);
            shortcutsList.setAdapter(shortcutsAdapter);
            shortcutsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> listView, View view, int position, long itemId) {
                    startActivityForResult(shortcutsAdapter.getIntent(position), REQUEST_CREATE_SHORTCUT);
                }
            });

            return new AlertDialog.Builder(getActivity()).setView(rootView).create();
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == REQUEST_CREATE_SHORTCUT && resultCode == Activity.RESULT_OK) {
                mPreference.setIntentValue((Intent) data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT));
                dismiss();
            }
        }

        static class ActivityInfo {
            CharSequence label;
            Drawable icon;
            ComponentName componentName;
        }

        private class ActivityListAdapter extends BaseAdapter {
            private Intent mQueryIntent;
            private PackageManager mPackageManager;
            private List<ActivityInfo> mInfos;
            private boolean mAllowUseDefault;

            private ActivityListAdapter(Intent queryIntent, boolean allowUseDefault) {
                mQueryIntent = queryIntent;
                mPackageManager = getActivity().getPackageManager();
                mAllowUseDefault = allowUseDefault;

                mInfos = new ArrayList<ActivityInfo>();
                List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(queryIntent, 0);
                for (ResolveInfo ri : resolveInfos) {
                    ActivityInfo ai = new ActivityInfo();
                    ai.icon = ri.loadIcon(mPackageManager);
                    ai.label = ri.loadLabel(mPackageManager);
                    ai.componentName = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
                    mInfos.add(ai);
                }

                Collections.sort(mInfos, new Comparator<ActivityInfo>() {
                    @Override
                    public int compare(ActivityInfo activityInfo, ActivityInfo activityInfo2) {
                        return activityInfo.label.toString().compareTo(activityInfo2.label.toString());
                    }
                });
            }

            @Override
            public int getCount() {
                return mInfos.size() + (mAllowUseDefault ? 1 : 0);
            }

            @Override
            public Object getItem(int position) {
                if (mAllowUseDefault && position == 0) {
                    return null;
                }

                return mInfos.get(position - (mAllowUseDefault ? 1 : 0));
            }

            public Intent getIntent(int position) {
                if (mAllowUseDefault && position == 0) {
                    return null;
                }

                return new Intent(mQueryIntent)
                        .setComponent(mInfos.get(position - (mAllowUseDefault ? 1 : 0)).componentName);
            }

            @Override
            public long getItemId(int position) {
                if (mAllowUseDefault && position == 0) {
                    return -1;
                }

                return mInfos.get(position - (mAllowUseDefault ? 1 : 0)).componentName.hashCode();
            }

            @Override
            public View getView(int position, View convertView, ViewGroup container) {
                if (convertView == null) {
                    convertView = LayoutInflater.from(getActivity()).inflate(R.layout.list_item_intent, container,
                            false);
                }

                if (mAllowUseDefault && position == 0) {
                    ((TextView) convertView.findViewById(android.R.id.text1))
                            .setText(getString(R.string.pref_yr_shortcut_default));
                    ((ImageView) convertView.findViewById(android.R.id.icon)).setImageDrawable(null);
                } else {
                    ActivityInfo ai = mInfos.get(position - (mAllowUseDefault ? 1 : 0));
                    ((TextView) convertView.findViewById(android.R.id.text1)).setText(ai.label);
                    ((ImageView) convertView.findViewById(android.R.id.icon)).setImageDrawable(ai.icon);
                }

                return convertView;
            }
        }
    }
}