大家晚上好,今晚跟大家分享的是软件管理信息展示列表,今晚这个肯定是大招了,涉及的知识点,以及遇到的难道,是以前的小项目是不可比拟的,单单显示的界面,足以惊吓到你,想要有这效果,大家应该决定很难,其实没那么难,我主要用到的是用到packageManage这个类,取它的api,得到数据,保存在列表,然后在自定义适配器展示数据,就OK了。废话不多说直接开讲。
1.创建实体类,用于保存数据,SoftManageInfo.java
我们要保存的对象有,name应用名,packageName包名,versionName版本号,icon图标,isUser是否为用户,isScard是否为sd卡内存。
再实现get/set方法,无参构造,有参构造方法,toString方法,就完事了,由于建立bean类简单,我就不上代码了。
2.创建业务层,实现封装方法,SoftManage.java
/**
*软件管理工具类
*/
public class SoftManage {
private Context context;
//工具类构造函数,实现被调用
public SoftManage(Context context) {
this.context = context;
}
//得到所有软件信息的方法,保存在集合里
public List<SoftManageInfo> getAllSoftInfo() {
List<SoftManageInfo> data = new ArrayList<SoftManageInfo>();
//创建包管理器
PackageManager packageManager = context.getPackageManager();
//得到所有的安装的包
List<PackageInfo> infos = packageManager.getInstalledPackages(0);
//遍历所有的安装的包
for (PackageInfo info : infos) {
//取得包名称
String packageName = info.packageName;// 包名称
//取得版本号
String versionName = info.versionName;// 版本名
//取得应用名
String name = info.applicationInfo.loadLabel(packageManager)
.toString();// 应用名
//取得图标
Drawable icon = info.applicationInfo.loadIcon(packageManager);// 图标
//设置isUser,isScard的默认值
boolean isUser = true;// 默认值为true
boolean isScard = false;// 默认值为false
//取得应用信息的状态值
int flags = info.applicationInfo.flags;
//判断是否为系统应用,Applicationinfo.FLAG_SYSTEM系统应用的判断值
if ((flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) {
isUser = false;
}
//判断是否为外部存储,applicationinfo.FLAG_EXTERNAL_STORAGE外部存储
if ((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE) {
isScard = true;
}
//创建实体类构造函数,添加数据到bean
SoftManageInfo manageInfo = new SoftManageInfo(name, versionName,
packageName, icon, isUser, isScard);
//把实体类的值添加集合,方便取出
data.add(manageInfo);
}
//返回数据
return data;
}
}
3.主代码,实现调用封装工具类方法,展示数据,SoftManageActivity.java
**
* 软件管理
*
*/
public class SoftManageActivity extends Activity implements OnClickListener {
@ViewInject(R.id.soft_list)
private ListView mSoftList;
@ViewInject(R.id.soft_text)
private TextView mSaftTv;
private MyAdapter adapter;
private List<SoftManageInfo> mData;
private Context context;
private SoftManage manage;
private List<SoftManageInfo> userSoftInfos;//用户程序集合
private List<SoftManageInfo> systemSoftInfos;// 系统程序集合
private PopupWindow mPopupWindow;// 弹窗
private AnimationSet mAnimationSet;//集合动画
private View popView;// 视图view弹窗
private LinearLayout mPwlly;
private SoftManageInfo mInfo;
private Animation translateAnimation;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_soft_manage);
// 注解
ViewUtils.inject(this);
context = this;
manage = new SoftManage(context);
//初始化系统集合,用户程序集合
userSoftInfos = new ArrayList<SoftManageInfo>();
systemSoftInfos = new ArrayList<SoftManageInfo>();
getActionBar().setDisplayHomeAsUpEnabled(true);//返回图标
initPopupWindown();//初始化弹窗
//填充数据,主要加载数据,展示数据
fillData();
//列表的点击事件
mSoftList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//设置显示程序个数列表不能点击
if (position == 0) {
return;
}
if (position == userSoftInfos.size() + 1) {
return;
}
//点击列表获取分层数据,存在mInfo里,分位里面两大块,一块是userSoftInfos数据,一块是systemSoftInfos数据
if (position <= userSoftInfos.size()) {
//position=position-1;
mInfo = userSoftInfos.get(position - 1);
} else {
//position=position-用户程序个数-2
mInfo = systemSoftInfos.get(position - userSoftInfos.size()
- 2);
}
//隐藏弹窗
hidePopupWindown();
//显示位置,在view视图下边显示
mPopupWindow.showAsDropDown(view, 50, -115);
// 设置弹窗背景
mPopupWindow.setBackgroundDrawable(new ColorDrawable(
Color.TRANSPARENT));
//设置焦点,有焦点,可让弹窗消息,在这前提下,要设置弹窗背景,才可以实现其功能
mPopupWindow.setFocusable(true);
//弹窗的动画集合效果
popView.startAnimation(mAnimationSet);
}
});
//列表滑动监听
mSoftList.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
/*
* 参数一:视图,AbsListView是adapterView的子类,同样也是ListView的父类参数二:第一条列表项
* 参数三:可见列表数量参数四:总列表数量
*/
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
/隐藏弹窗
hidePopupWindown();
//我们在布局文件设置framLayout控件,将TxetView显示在listView控件之上,用来显示程序个数信息。滑动达到判断条件改变TextView文本值
//当第一条列表项小于用户程序的个数,就是用户程序的显示值
if (firstVisibleItem <= userSoftInfos.size()) {
mSaftTv.setText("用户程序(" + userSoftInfos.size() + ")个");
//反之,是系统程序的个数显示值,改变点是刚好等于用户程序总个数时
} else {
mSaftTv.setText("系统程序(" + systemSoftInfos.size() + ")个");
}
}
});
}
//初始化弹窗
private void initPopupWindown() {、
//挂载弹窗的布局,自定义布局
popView = LayoutInflater.from(context).inflate(
R.layout.pop_windown_list, null);
//设置弹窗的属性,参数一,弹窗显示的内容,参数二,三是长和宽
mPopupWindow = new PopupWindow(popView,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
mAnimationSet = new AnimationSet(true);
// 缩放动画
ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1,
Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(200);
scaleAnimation.setFillAfter(true);
mAnimationSet.addAnimation(scaleAnimation);
// 透明动画
AlphaAnimation alphaAnimation = new AlphaAnimation(0.3f, 1);
alphaAnimation.setDuration(200);
alphaAnimation.setFillAfter(true);
mAnimationSet.addAnimation(alphaAnimation);
mPwlly = (LinearLayout) popView.findViewById(R.id.pw_lly);
//获取LinearLayout下的子节点总个数,实现注册监听作用
int childCount = mPwlly.getChildCount();
// 遍历子节点
for (int i = 0; i < childCount; i++) {
//得到每一个子节点,设置监听
mPwlly.getChildAt(i).setOnClickListener(this);
}
}
//隐藏弹窗方法
public void hidePopupWindown() {
if (mPopupWindow != null) {
mPopupWindow.dismiss();
}
}
//填充数据方法
private void fillData() {
new AsyncTask<String, Integer, String>() {
// 在子线程之前执行
protected void onPreExecute() {
};
// 子线程执行
protected String doInBackground(String[] params) {
//第二次访问之后就要清除之前的数据
userSoftInfos.clear();
systemSoftInfos.clear();
//得到集合List里实体类softInfo的所有数据
mData = manage.getAllSoftInfo();
//判断是哪个是系统应用数据,用户应用数据
// 迭代
for (SoftManageInfo info : mData) {
// 判断是否为用户程序
//添加到各自的集合里
if (info.isUser()) {
userSoftInfos.add(info);
} else {
systemSoftInfos.add(info);
}
}
return null;
};
// 在子线程之后执行
protected void onPostExecute(String result) {
if (adapter == null) {
adapter = new MyAdapter();
//展示数据
mSoftList.setAdapter(adapter);
}
//更新数据
adapter.notifyDataSetChanged();
};
}.execute();
}
//自定义适配器
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
//因为有两个TextView列表,所有要加2
return mData == null ? 0 : mData.size() + 2;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mData == null ? 0 : mData.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
//判断列表项,当索引号为0时显示用户程序个数信息,当索引号等于用户程序个数+1显示系统程序个数TextView
if (position == 0) {
TextView tv = new TextView(context);
tv.setText("用户程序(" + userSoftInfos.size() + ")" + "个");
tv.setTextSize(20);
tv.setTextColor(Color.YELLOW);
tv.setClickable(false);
tv.setBackgroundColor(Color.BLUE);
// 返回,不能点击
return tv;
}
// 系统程序显示列表项
if (position == userSoftInfos.size() + 1) {
TextView tv = new TextView(context);
tv.setText("系统程序(" + systemSoftInfos.size() + ")" + "个");
tv.setTextSize(20);
tv.setTextColor(Color.YELLOW);
tv.setBackgroundColor(Color.BLUE);
// 返回,不能点击
return tv;
}
// 判断哪个是用户程序,系统程序
SoftManageInfo info = null;
// 用户程序要展示的总列表
if (position < userSoftInfos.size() + 1) {
info = userSoftInfos.get(position - 1);
// 系统程序要展示的总列表
} else {
info = systemSoftInfos.get(position - userSoftInfos.size() - 2);
}
View view = LayoutInflater.from(context).inflate(
R.layout.soft_item_list, parent, false);
mSoftList.setBackgroundResource(R.drawable.dog);
//显示要展示的信息
ImageView icon = (ImageView) view.findViewById(R.id.soft_icon_item);
TextView name = (TextView) view.findViewById(R.id.soft_name_item);
TextView packageName = (TextView) view
.findViewById(R.id.soft_packageName_item);
TextView versionName = (TextView) view
.findViewById(R.id.soft_versionName_item);
TextView isScardTv = (TextView) view
.findViewById(R.id.soft_isScard_item);
// 图片是drawable形式的
icon.setImageDrawable(info.getIcon());
name.setText(info.getName());
packageName.setText(info.getPackageName());
// 得到version版本值
String version = info.getVersionName();
if (!TextUtils.isEmpty(version)) {
// 判断字符串大于4时
if (version.length() <= 3) {
versionName.setText(version);
} else {
version = version.substring(0, 3);
versionName.setText(version);
}
}
// 判断是否为内部存储
if (info.isScard()) {
isScardTv.setText("内部存储");
} else {
isScardTv.setText("外部存储");
}
return view;
}
}
//弹窗的点击事件
public void onClick(View v) {
switch (v.getId()) {
// 卸载
case R.id.uninstall_tv:
uninstallApp();// 卸载app
break;
// 启动
case R.id.run_app_tv:
runApp();//运行App
break;
// 分享
case R.id.shard_tv:
shardInfo();//分享
break;
// 详情
case R.id.detail_tv:
detailShow();//详情
break;
default:
break;
}
}
//分享
private void shardInfo() {
//使用意图,设置意图事件,数据传送的方式,类型,开始执行
Intent intent=new Intent();
//设置跳转到action_send行为,短信发送
intent.setAction(Intent.ACTION_SEND);
//设置数据传送的方式,和显示数据
intent.putExtra(Intent.EXTRA_TEXT,"android开发");
//设置意图的类型
intent.setType("pain/text");
//执行意图
startActivity(intent);
}
//详情信息
private void detailShow() {
//使用意图,设置意图事件,意图的数据,以及跳转需要的uri
Intent intent=new Intent();
//添加详情信息活动
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
//添加数据,参数一:跳转的uri
intent.setData(Uri.parse("package:"+mInfo.getPackageName()));
startActivity(intent);
}
//运行App
private void runApp() {
//创建包管理器,得到启动项,再判断是否为空,系统服务是没有启动项的
PackageManager manager =getPackageManager();
Intent launchIntentForPackage = manager.getLaunchIntentForPackage(mInfo.getPackageName());
if(!(launchIntentForPackage==null)){
startActivity(launchIntentForPackage);
}else{
ToastUtil.show(context, "系统服务不能启动");
}
}
// 卸载app
private void uninstallApp() {
/*
* <intent-filter> <action android:name="android.intent.action.DELETE"
* /> <action android:name="android.intent.action.UNINSTALL_PACKAGE" />
* <category android:name="android.intent.category.DEFAULT" /> <data
* android:scheme="package" /> </intent-filter>
*/
//判断本身应用以及系统应用是不能删除的
if (mInfo.getPackageName().equals(getPackageName())) {
ToastUtil.show(context, "你不能删我==");
return;
} else if (!mInfo.isUser()) {
ToastUtil.show(context, "不能删除系统应用,因为你没有权限");
return;
} else {
//创建意图,设置意图事件,跳转数据以及需要的uri
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DELETE);
intent.setData(Uri.parse("package:" + mInfo.getPackageName()));
//因为卸载后要刷新数据,我们就用到startActivityForResult方法跳转刷新
startActivityForResult(intent, 6);
}
}
//接受请求码进行刷新数据
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 6) {
//刷新数据
fillData();// 刷新数据,之前要清除数据
}
super.onActivityResult(requestCode, resultCode, data);
}
//ActionBarcar菜单栏
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.soft_manage, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//返回图标的点击事件
case android.R.id.home:
finish();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
一个完整的展示软件信息列表就大功告成了,是不是很牛逼,其实我觉得很厉害,做完这个慢慢的自豪感,大家有时间可以试试看,增加满足感。晚安,做个好梦。