还是继续复习我的安卓基础吧,毕竟基础才是最重要的
这一篇文章将会用到复杂的listview,和获取系统软件信息,还有给Listview加动画效果.
先看看布局吧,源码在后面提供下载,只是一个包,因为我是拿测试项目在演示。
布局很简单 我直接贴源码吧 因为怕有些手机装的APP过多,所以加入了一个progressbar
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/tv_avail_rom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="内存可用:" android:textColor="#000000" /> <TextView android:id="@+id/tv_avail_sd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="SD卡可用:" android:textColor="#000000" /> </RelativeLayout> <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/ll_loading" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:orientation="vertical" android:visibility="invisible" > <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="正在加载程序信息..." /> </LinearLayout> <ListView android:overScrollMode="never" android:fastScrollEnabled="true" android:id="@+id/lv_app_manager" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView> <TextView android:id="@+id/tv_status" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="用户程序:6个" android:textColor="#ffffff" android:background="#ff888888" /> </FrameLayout> </LinearLayout>
package com.example.Darkbutton.Appmanager; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; /** * @author xiaoxin007 * 2014-12-6下午8:18:58 * TODO 业务方法,提供手机里面安装的所有的应用程序信息 */ public class AppInfoProvider { /** * 获取所有的安装的应用程序信息。 * @param context 上下文 * @return */ public static List<AppInfo> getAppInfos(Context context){ //1.获得一个包管理器 PackageManager pm = context.getPackageManager(); //2.所有的安装在系统上的应用程序包信息。 List<PackageInfo> packInfos = pm.getInstalledPackages(0); //3.建立一个实体类 存储东西 List<AppInfo> appInfos = new ArrayList<AppInfo>(); //4.遍历 for(PackageInfo packInfo : packInfos){ AppInfo appInfo = new AppInfo(); //packInfo 相当于一个应用程序apk包的清单文件 String packname = packInfo.packageName; Drawable icon = packInfo.applicationInfo.loadIcon(pm); String name = packInfo.applicationInfo.loadLabel(pm).toString(); int flags = packInfo.applicationInfo.flags;//应用程序信息的标记 相当于用户提交的答卷 if((flags&ApplicationInfo.FLAG_SYSTEM)==0){ //用户程序 appInfo.setUserApp(true); }else{ //系统程序 appInfo.setUserApp(false); } if((flags&ApplicationInfo.FLAG_EXTERNAL_STORAGE)==0){ //手机的内存 appInfo.setInRom(true); }else{ //手机外存储设备 appInfo.setInRom(false); } appInfo.setPackname(packname); appInfo.setIcon(icon); appInfo.setName(name); appInfos.add(appInfo); } return appInfos; } }
package com.example.Darkbutton.Appmanager; import android.graphics.drawable.Drawable; /** * @author xiaoxin007 * 2014-12-6下午5:37:47 * TODO 应用程序信息的业务bean */ public class AppInfo { private Drawable icon; private String name; private String packname; private boolean inRom; private boolean userApp; public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this.icon = icon; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPackname() { return packname; } public void setPackname(String packname) { this.packname = packname; } public boolean isInRom() { return inRom; } public void setInRom(boolean inRom) { this.inRom = inRom; } public boolean isUserApp() { return userApp; } public void setUserApp(boolean userApp) { this.userApp = userApp; } @Override public String toString() { return "AppInfo [name=" + name + ", packname=" + packname + ", inRom=" + inRom + ", userApp=" + userApp + "]"; } }
/** * 获取某个目录的可用空间 * * @param path * @return */ private long getAvailSpace(String path) { StatFs statf = new StatFs(path); statf.getBlockCount();// 获取分区的个数 long size = statf.getBlockSize();// 获取分区的大小 long count = statf.getAvailableBlocks();// 获取可用的区块的个数 return size * count; }
/** * 初始化组件 */ private void initView() { tv_status = (TextView) findViewById(R.id.tv_status); tv_avail_rom = (TextView) findViewById(R.id.tv_avail_rom); tv_avail_sd = (TextView) findViewById(R.id.tv_avail_sd); lv_app_manager = (ListView) findViewById(R.id.lv_app_manager); ll_loading = (LinearLayout) findViewById(R.id.ll_loading); }
/** * 初始化数据 */ private void initData() { sdsize = getAvailSpace(Environment.getExternalStorageDirectory() .getAbsolutePath()); romsize = getAvailSpace(Environment.getDataDirectory() .getAbsolutePath()); tv_avail_sd .setText("SD卡可用空间:" + Formatter.formatFileSize(this, sdsize)); tv_avail_rom.setText("内存可用空间:" + Formatter.formatFileSize(this, romsize)); }
/** * listview动画 */ private void initAnim() { AnimationSet set = new AnimationSet(false); Animation animation = new TranslateAnimation(1, 13, 10, 50); //ScaleAnimation 控制尺寸伸缩的动画效果 animation.setDuration(300); set.addAnimation(animation); LayoutAnimationController controller = new LayoutAnimationController(set, 1); lv_app_manager.setLayoutAnimation(controller); //ListView 设置动画效果 }
/** * 给Listview填充数据 */ private void fillDataToListView() { //1.用户体验,加入progressbar ll_loading.setVisibility(View.VISIBLE); //2.耗时操作加入线程以免GG new Thread() { public void run() { //3.调用 类,获取到软件信息 appInfos = AppInfoProvider.getAppInfos(AppManagerActivity.this); //4.因为要把系统,用户软件分开,所以单独建立两个数据存储 userAppInfos = new ArrayList<AppInfo>(); systemAppInfos = new ArrayList<AppInfo>(); //5.遍历 填充进数组 for (AppInfo info : appInfos) { if (info.isUserApp()) { userAppInfos.add(info); } else { systemAppInfos.add(info); } } // 加载listview的数据适配器 因为在线程之中,所以使用runOnUiThread 可以在ui更新 runOnUiThread(new Runnable() { @Override public void run() { if (adapter == null) { adapter = new AppManagerAdapter(); lv_app_manager.setAdapter(adapter); } else { adapter.notifyDataSetChanged(); } ll_loading.setVisibility(View.INVISIBLE); } }); }; }.start(); }
private class AppManagerAdapter extends BaseAdapter { // 控制listview有多少个条目 第一个1 代表是显示 用户应用 第二个1代表系统应用 @Override public int getCount() { return userAppInfos.size() + 1 + systemAppInfos.size() + 1; } @Override public View getView(int position, View convertView, ViewGroup parent) { AppInfo appInfo; if (position == 0) {// 显示的是用程序有多少个的小标签 TextView tv = new TextView(getApplicationContext()); tv.setTextColor(Color.WHITE); tv.setBackgroundColor(Color.GRAY); tv.setText("用户程序:" + userAppInfos.size() + "个"); return tv; } else if (position == (userAppInfos.size() + 1)) { TextView tv = new TextView(getApplicationContext()); tv.setTextColor(Color.WHITE); tv.setBackgroundColor(Color.GRAY); tv.setText("系统程序:" + systemAppInfos.size() + "个"); return tv; } else if (position <= userAppInfos.size()) {// 用户程序 int newposition = position - 1;// 因为多了一个textview的文本占用了位置 appInfo = userAppInfos.get(newposition); } else {// 系统程序 int newposition = position - 1 - userAppInfos.size() - 1; appInfo = systemAppInfos.get(newposition); } View view; ViewHolder holder; // if(position<userAppInfos.size()){//这些位置是留个用户程序显示的。 // appInfo = userAppInfos.get(position); // }else{//这些位置是留个系统程序的。 // int newposition = position - userAppInfos.size(); // appInfo = systemAppInfos.get(newposition); // } if (convertView != null && convertView instanceof RelativeLayout) { // 不仅需要检查是否为空,还要判断是否是合适的类型去复用 view = convertView; holder = (ViewHolder) view.getTag(); } else { view = View.inflate(getApplicationContext(), R.layout.list_item_appinfo, null); holder = new ViewHolder(); holder.iv_icon = (ImageView) view .findViewById(R.id.iv_app_icon); holder.tv_location = (TextView) view .findViewById(R.id.tv_app_location); holder.tv_name = (TextView) view.findViewById(R.id.tv_app_name); view.setTag(holder); } holder.iv_icon.setImageDrawable(appInfo.getIcon()); holder.tv_name.setText(appInfo.getName()); if (appInfo.isInRom()) { holder.tv_location.setText("手机内存"); } else { holder.tv_location.setText("外部存储"); } return view; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } }
/** * 设置listview的点击事件 */ lv_app_manager.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //设置点击第一个条目的时候不显示,因为不是软件 if (position == 0) { return; //以此类推 } else if (position == (userAppInfos.size() + 1)) { return; } else if (position <= userAppInfos.size()) {// 用户程序 int newposition = position - 1; appInfo = userAppInfos.get(newposition); } else {// 系统程序 int newposition = position - 1 - userAppInfos.size() - 1; appInfo = systemAppInfos.get(newposition); } // System.out.println(appInfo.getPackname()); dismissPopupWindow(); //填充一个popwindow View contentView = View.inflate(getApplicationContext(), R.layout.popup_app_item, null); ll_start = (LinearLayout) contentView .findViewById(R.id.ll_start); ll_share = (LinearLayout) contentView .findViewById(R.id.ll_share); ll_uninstall = (LinearLayout) contentView .findViewById(R.id.ll_uninstall); //启动的监听 ll_start.setOnClickListener(AppManagerActivity.this); //分享的监听 ll_share.setOnClickListener(AppManagerActivity.this); //卸载的监听 ll_uninstall.setOnClickListener(AppManagerActivity.this); popupWindow = new PopupWindow(contentView, -2, -2); // 动画效果的播放必须要求窗体有背景颜色。 // 透明颜色也是颜色 popupWindow.setBackgroundDrawable(new ColorDrawable( Color.TRANSPARENT)); int[] location = new int[2]; view.getLocationInWindow(location); // 在代码里面设置的宽高值 都是像素。---》dip int dip = 60; int px = DensityUtil.dip2px(getApplicationContext(), dip); System.out.println("px=" + px); popupWindow.showAtLocation(parent, Gravity.LEFT | Gravity.TOP, px, location[1]); ScaleAnimation sa = new ScaleAnimation(0.3f, 1.0f, 0.3f, 1.0f, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f); sa.setDuration(300); AlphaAnimation aa = new AlphaAnimation(0.5f, 1.0f); aa.setDuration(300); AnimationSet set = new AnimationSet(false); set.addAnimation(aa); set.addAnimation(sa); contentView.startAnimation(set); } }); }
/** * 布局对应的点击事件 */ @Override public void onClick(View v) { dismissPopupWindow(); switch (v.getId()) { case R.id.ll_share: shareApplication(); break; case R.id.ll_start: startApplication(); break; case R.id.ll_uninstall: if (appInfo.isUserApp()) { uninstallAppliation(); }else{ Toast.makeText(this, "系统应用只有获取root权限才可以卸载", 0).show(); //Runtime.getRuntime().exec(""); } break; } }
/** * 分享一个应用程序 */ private void shareApplication() { // Intent { act=android.intent.action.SEND typ=text/plain flg=0x3000000 cmp=com.android.mms/.ui.ComposeMessageActivity (has extras) } from pid 256 Intent intent = new Intent(); intent.setAction("android.intent.action.SEND"); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "推荐您使用一款软件,名称叫:"+appInfo.getName()); startActivity(intent); }
/** * 卸载应用 */ private void uninstallAppliation() { // <action android:name="android.intent.action.VIEW" /> // <action android:name="android.intent.action.DELETE" /> // <category android:name="android.intent.category.DEFAULT" /> // <data android:scheme="package" /> Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.setAction("android.intent.action.DELETE"); intent.addCategory("android.intent.category.DEFAULT"); intent.setData(Uri.parse("package:" + appInfo.getPackname())); startActivityForResult(intent, 0); }
/** * 开启一个应用程序 */ private void startApplication() { // 查询这个应用程序的入口activity。 把他开启起来。 PackageManager pm = getPackageManager(); // Intent intent = new Intent(); // intent.setAction("android.intent.action.MAIN"); // intent.addCategory("android.intent.category.LAUNCHER"); // //查询出来了所有的手机上具有启动能力的activity。 // List<ResolveInfo> infos = pm.queryIntentActivities(intent, // PackageManager.GET_INTENT_FILTERS); Intent intent = pm.getLaunchIntentForPackage(appInfo.getPackname()); if (intent != null) { startActivity(intent); } else { Toast.makeText(this, "不能启动当前应用", 0).show(); } }