/* * Copyright 2015. Appsi Mobile * * 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.appsimobile.appsii.module.apps; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.net.Uri; import android.provider.Settings; import android.util.AttributeSet; import android.view.MenuItem; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.PopupMenu; import android.widget.TextView; import com.appsimobile.appsii.InterceptingTouchDelegate; import com.appsimobile.appsii.R; import java.util.ArrayList; import java.util.List; /** * Represents an app in the list of all apps or a specific folder * Created by nick on 03/06/14. */ public class AppView extends FrameLayout implements View.OnClickListener, PopupMenu.OnMenuItemClickListener, AppTagUtils.AppTagListener { /** * The id of the menu action to show app info */ public static final int ACTION_APP_INFO = 0; /** * The id of the menu action to uninstall the app */ public static final int ACTION_APP_UNINSTALL = 1; /** * The id of the menu action to launch the app in halo */ public static final int ACTION_APP_HALO = 3; /** * The id of the menu action to show the tags where the user * can add or remove the app from tags */ public static final int ACTION_APP_TAGS = 4; /** * The id of the menu action in the tags sub-menu, to add a new * app tag */ public static final int ACTION_NEW_TAG = Integer.MIN_VALUE; /** * The list of TaggedApp entries, these are the currently * applied AppTags to the current AppEntry */ private final List<TaggedApp> mAppliedTags = new ArrayList<>(); InterceptingTouchDelegate mTouchDelegate; boolean mDispatchToDelegate; /** * The app entry this App-View is bound to */ private AppEntry mAppEntry; /** * The image view to display the app's icon */ private ImageView mImage; /** * The text view containing the title of the app */ private TextView mText; /** * The overflow menu button */ private View mOverflow; /** * A async-task used to load the app icon for the current app * entry. When non-null, the task may be in progress and can * be cancelled. */ private AppIconLoaderTask mActiveAppIconLoaderTask; /** * All AppTags that are currently present in the system */ private List<AppTag> mAppTags; /** * A listener that can perform actions on the tag */ private AppActionListener mAppActionListener; public AppView(Context context) { super(context); } public AppView(Context context, AttributeSet attrs) { super(context, attrs); } public AppView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onFinishInflate() { super.onFinishInflate(); mImage = (ImageView) findViewById(R.id.image); mText = (TextView) findViewById(R.id.primary_text); mOverflow = findViewById(R.id.overflow); mOverflow.setOnClickListener(this); mAppTags = AppTagUtils.getInstance(getContext()).registerAppTagListener(this); setWillNotDraw(false); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } /** * Binds the App-View to the given app-entry. A list of TaggedApps, * is also provided. Each taggedApp represents a tag that is * applied to the app-entry. */ public void bind(AppEntry app, List<TaggedApp> tags) { mAppEntry = app; if (app == null) { mImage.setImageBitmap(null); mText.setVisibility(GONE); mOverflow.setVisibility(GONE); return; } // update the list of tags mAppliedTags.clear(); if (tags != null) { mAppliedTags.addAll(tags); } mText.setVisibility(VISIBLE); mOverflow.setVisibility(VISIBLE); mText.setText(app.getLabel()); // when an icon is currently being loaded, // cancel the load. if (mActiveAppIconLoaderTask != null) { mActiveAppIconLoaderTask.cancel(true); } // if an icon is already loaded in the Drawable existing = app.getIconIfReady(); if (existing == null) { mImage.setAlpha(0f); mActiveAppIconLoaderTask = new AppIconLoaderTaskImpl(getContext(), app, getContext().getPackageManager()); mActiveAppIconLoaderTask.execute(); } else { mImage.setAlpha(1f); mImage.setImageDrawable(existing); } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mActiveAppIconLoaderTask != null) { mActiveAppIconLoaderTask.cancel(true); } } @Override public void onClick(View v) { PopupMenu popupMenu = new PopupMenu(v.getContext(), v); popupMenu.getMenu().add(0, ACTION_APP_INFO, 0, R.string.apps_action_app_info); if (mAppActionListener != null) { popupMenu.getMenu().add(0, ACTION_APP_TAGS, 0, R.string.action_tags); } popupMenu.getMenu().add(0, ACTION_APP_HALO, 0, R.string.apps_action_halo); popupMenu.getMenu().add(0, ACTION_APP_UNINSTALL, 0, R.string.apps_action_uninstall); popupMenu.setOnMenuItemClickListener(this); popupMenu.show(); } @Override public boolean onMenuItemClick(MenuItem item) { int id = item.getItemId(); switch (id) { case ACTION_APP_INFO: Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + mAppEntry.getApplicationInfo().packageName)); getContext().startActivity(intent); return true; case ACTION_APP_HALO: Context context = getContext(); PackageManager pm = context.getPackageManager(); Intent appIntent = pm.getLaunchIntentForPackage(mAppEntry.getApplicationInfo().packageName); // 0x2000 is the flag to open in halo appIntent.addFlags(0x2000); context.startActivity(appIntent); return true; case ACTION_APP_UNINSTALL: Intent uninstall = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); uninstall.setData( Uri.parse("package:" + mAppEntry.getApplicationInfo().packageName)); getContext().startActivity(uninstall); return true; case ACTION_APP_TAGS: mAppActionListener.onEditAppliedTags(mAppEntry, mAppTags, mAppliedTags); return true; } return false; } // // private boolean handleTagItemClick(MenuItem item) { // if (item.getItemId() == ACTION_NEW_TAG) { // mAppActionListener.onAddAppToNewTag(mAppEntry); // } else { // AppTag tag = mAppTags.get(item.getItemId()); // if (!item.isChecked()) { // mAppActionListener.onAddAppToTag(tag, mAppEntry); // } else { // TaggedApp taggedApp = getTaggedApp(tag); // mAppActionListener.onRemoveAppFromTag(taggedApp); // // } // } // return true; // } public AppEntry getAppEntry() { return mAppEntry; } @Override public void onTagsChanged(ArrayList<AppTag> appTags) { mAppTags = appTags; } void onIconLoaded(Drawable drawable) { if (drawable == null) { drawable = getContext().getResources().getDrawable( android.R.drawable.sym_def_app_icon); } mImage.setImageDrawable(drawable); mImage.animate().alpha(1); } public void setAppActionListener(AppActionListener appActionListener) { mAppActionListener = appActionListener; } public interface AppActionListener { void onEditAppliedTags(AppEntry entry, List<AppTag> allTags, List<TaggedApp> appliedTags); } public interface TagActionListener { void onEditAppTag(AppTag entry); void onReorderApps(AppTag entry); void onToggleSingleRow(AppTag entry); } class AppIconLoaderTaskImpl extends AppIconLoaderTask { AppIconLoaderTaskImpl(Context context, AppEntry appEntry, PackageManager packageManager) { super(context, appEntry, packageManager); } @Override protected void onPostExecute(Drawable drawable) { onIconLoaded(drawable); } } }