import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.StatFs; import android.text.format.Formatter; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.ScaleAnimation; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.PopupWindow; import android.widget.TextView; import com.itcast.mobilesafe01.R; import com.itcast.mobilesafe01.domain.AppInfo; import com.itcast.mobilesafe01.engine.AppInfoProvider; /** * 应用管理页面 * 开发流程: * 1. 布局文件 * 2. 获取可用空间信息 * 3. 获取已安装应用列表(AppInfoProvider) * 4. 加载应用列表,使用listview展示(普通展示) * 5. 将用户应用和系统应用分割成两个集合, 让adapter使用这两个集合来展示 * 6. 增加两个标题(复杂listview展示) * 7. 增加一直显示的浮窗 * 8. 将主线程加载改为异步加载应用列表(可以提前做), 展示加载中的布局 * 9. 增加popupwindow * 10.增加popupwindow动画效果 * 11.响应弹窗点击事件 * 12.在点击事件里,分别卸载,启动,分享 * @author Kevin * */ public class AppManagerActivity extends Activity implements OnClickListener { private ArrayList<AppInfo> mList; private ArrayList<AppInfo> mUserList;// 用户app集合 private ArrayList<AppInfo> mSystemList;// 系统app集合 private ListView lvList; private AppInfoAdapter mAdapter; private TextView tvHeader;// 一直浮在上面的TextView private LinearLayout llLoading; private PopupWindow mPopupWindow; private AppInfo mCurrentInfo;// 当前被点击的对象 private View mPopupView; private AnimationSet mPopupAnimSet; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_app_manager); TextView tvRomAvail = (TextView) findViewById(R.id.tv_rom_avail); TextView tvSdcardAvail = (TextView) findViewById(R.id.tv_sdcard_avail); tvRomAvail.setText("内部存储可用:" + getAvailSpace(Environment.getDataDirectory() .getAbsolutePath()));// /data tvSdcardAvail.setText("sdcard可用:" + getAvailSpace(Environment.getExternalStorageDirectory() .getAbsolutePath())); lvList = (ListView) findViewById(R.id.lv_list); tvHeader = (TextView) findViewById(R.id.tv_header); llLoading = (LinearLayout) findViewById(R.id.ll_loading); lvList.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } // 滑动监听 @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // firstVisibleItem 第一个可见元素位置 // visibleItemCount 可见元素数量 // totalItemCount 元素总数 if (mUserList != null && mSystemList != null) { if (firstVisibleItem >= mUserList.size() + 1) { tvHeader.setText("系统应用(" + mSystemList.size() + ")"); } else { tvHeader.setText("用户应用(" + mUserList.size() + ")"); } } } }); lvList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { AppInfo info = mAdapter.getItem(position);// 获取被点击的对象 if (info != null) {// 非标题栏才可以展示 mCurrentInfo = info; showPopupWindow(view);// 将被点击的view对象传递给popupwindow } } }); initData(); } /** * 展示小弹窗 */ protected void showPopupWindow(View view) { if (mPopupWindow == null) { mPopupView = View.inflate(this, R.layout.popup_appinfo, null); mPopupWindow = new PopupWindow(mPopupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true); mPopupWindow.setBackgroundDrawable(new ColorDrawable());// 设置空白背景,点击空白/返回键可以消失 TextView tvUninstall = (TextView) mPopupView .findViewById(R.id.tv_uninstall); TextView tvLaunch = (TextView) mPopupView .findViewById(R.id.tv_launch); TextView tvShare = (TextView) mPopupView .findViewById(R.id.tv_share); tvUninstall.setOnClickListener(this); tvLaunch.setOnClickListener(this); tvShare.setOnClickListener(this); // 渐变动画 AlphaAnimation animAlpha = new AlphaAnimation(0, 1); animAlpha.setDuration(500); // 缩放动画 ScaleAnimation animScale = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f); animScale.setDuration(500); // 动画集合 mPopupAnimSet = new AnimationSet(true); mPopupAnimSet.addAnimation(animAlpha); mPopupAnimSet.addAnimation(animScale); } // 启动动画 mPopupView.startAnimation(mPopupAnimSet); mPopupWindow.showAsDropDown(view, 60, -view.getHeight());// 展示在被点击view的正下方 } /** * 初始化数据 */ private void initData() { llLoading.setVisibility(View.VISIBLE); new Thread() { @Override public void run() { mList = AppInfoProvider .getInstalledApp(getApplicationContext());// 加载已安装的应用 mUserList = new ArrayList<AppInfo>(); mSystemList = new ArrayList<AppInfo>(); for (AppInfo info : mList) { if (info.isUserApp) { mUserList.add(info); } else { mSystemList.add(info); } } // 在主线程运行的简洁方法 runOnUiThread(new Runnable() { @Override public void run() { mAdapter = new AppInfoAdapter(); lvList.setAdapter(mAdapter); llLoading.setVisibility(View.GONE); } }); } }.start(); } /** * 获取可用空间 */ private String getAvailSpace(String path) { StatFs stat = new StatFs(path); long availableBlocks = stat.getAvailableBlocks();// 获取可用存储块的数量 long blockSize = stat.getBlockSize();// 获取每一个存储块大小 long availSize = availableBlocks * blockSize;// 可用空间大小 // Integer.MAX_VALUE = 1.9G // Long.MAX_VALUE 8838T return Formatter.formatFileSize(this, availSize);// 转成带单位的大小 } class AppInfoAdapter extends BaseAdapter { @Override public int getCount() { return mUserList.size() + mSystemList.size() + 2;// 增加两个标题栏 } @Override public AppInfo getItem(int position) { if (position == 0 || position == mUserList.size() + 1) {// 遇到标题栏,直接返回null return null; } if (position < mUserList.size() + 1) { return mUserList.get(position - 1); } else { return mSystemList.get(position - mUserList.size() - 2);// 需要减掉两个标题栏的占位 } } @Override public long getItemId(int position) { return position; } // 返回布局类型的个数, 就会缓存两种convertView @Override public int getViewTypeCount() { return 2; } // 根据当前位置,返回相应布局类型, 必须从0开始计算 @Override public int getItemViewType(int position) { if (position == 0 || position == mUserList.size() + 1) {// 遇到标题栏 return 0; } else { return 1; } } @Override public View getView(int position, View convertView, ViewGroup parent) { // 首先要判断当前布局类型, 系统会缓存多种convertView, 然后根据当前布局类型,返回对应的convertView int type = getItemViewType(position); // 根据类型,加载不同布局 switch (type) { case 0: HeaderHolder headerHolder; if (convertView == null) { convertView = View.inflate(getApplicationContext(), R.layout.list_item_header, null); headerHolder = new HeaderHolder(); headerHolder.tvHeader = (TextView) convertView .findViewById(R.id.tv_header); convertView.setTag(headerHolder); } else { headerHolder = (HeaderHolder) convertView.getTag(); } if (position == 0) { headerHolder.tvHeader.setText("用户应用(" + mUserList.size() + ")"); } else { headerHolder.tvHeader.setText("系统应用(" + mSystemList.size() + ")"); } break; case 1: // View view = null; ViewHolder holder = null; if (convertView == null) { convertView = View.inflate(getApplicationContext(), R.layout.list_item_appinfo, null); holder = new ViewHolder(); holder.tvName = (TextView) convertView .findViewById(R.id.tv_name); holder.tvLocation = (TextView) convertView .findViewById(R.id.tv_location); holder.ivIcon = (ImageView) convertView .findViewById(R.id.iv_icon); convertView.setTag(holder); } else { // view = convertView; holder = (ViewHolder) convertView.getTag(); } AppInfo info = getItem(position); holder.tvName.setText(info.name); holder.ivIcon.setImageDrawable(info.icon); if (info.isRom) { holder.tvLocation.setText("手机内存"); } else { holder.tvLocation.setText("外置存储器"); } break; default: break; } return convertView; } } static class ViewHolder { public TextView tvName; public TextView tvLocation; public ImageView ivIcon; } static class HeaderHolder { public TextView tvHeader; } @Override public void onClick(View v) { mPopupWindow.dismiss();// 弹窗消失 switch (v.getId()) { case R.id.tv_uninstall: System.out.println("卸载:" + mCurrentInfo.name); uninstall(); break; case R.id.tv_launch: System.out.println("启动:" + mCurrentInfo.name); launchApp(); break; case R.id.tv_share: System.out.println("分享:" + mCurrentInfo.name); share(); break; default: break; } } /** * 分享 调用系统所有可以分享的app, 系统自动生成列表,供用户选择 */ private void share() { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain");// 分享纯文本 intent.putExtra(Intent.EXTRA_TEXT, "发现一个很好的应用,赶紧下载哦! 下载地址:https://play.google.com/store/apps/details?id=" + mCurrentInfo.packageName); startActivity(intent); } /** * 启动app */ private void launchApp() { // 获取启动页面 PackageManager pm = getPackageManager(); Intent intent = pm.getLaunchIntentForPackage(mCurrentInfo.packageName);// 通过包名,获取该app的启动intent startActivity(intent); } /** * 卸载 */ private void uninstall() { Intent intent = new Intent(Intent.ACTION_DELETE); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setData(Uri.parse("package:" + mCurrentInfo.packageName)); startActivityForResult(intent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 重新加载数据 initData(); } }