01.应用程序flags的含义&安装在SDcard
a.应用程序flags的含义:
int类型的数据有32个1.可以通过1去判断状态
0000 0000 0000 0000 0000 0010 0000 0000
就可以根据这里的 第10个1表示某种能力。其他位是0的表示没有对应的能力。
例如:QQ.钻 第10个1表示黄钻
b.在代码当中的API:
public static boolean isInstallSD(PackageInfo info) {
ApplicationInfo applicationInfo = info.applicationInfo;
int flags = applicationInfo.flags;// 应用的标记,能力或是特性
boolean isInsallSD = false;
if ((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE) {
isInsallSD = true;
}
return isInsallSD;
}
c.关于软件,安装位置.看清单文件.根节点
android:installLocation="internalOnly" 手机内部存储空间
android:installLocation="preferExternal"安装在SDcard
02.软件管家_应用程序排序显示
a.系统应用和用户应用也是通过flag判断的
b.详细判断的API:
public static boolean isSystemApp(PackageInfo info) {
ApplicationInfo applicationInfo = info.applicationInfo;
int flags = applicationInfo.flags;// 应用的标记,能力或是特性
boolean isSystemApp = false;
if ((flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) {
isSystemApp = true;
}
return isSystemApp;
}
c.集合排序的操作:
// 排序
Collections.sort(mDatas, new Comparator<AppBean>() {
@Override
public int compare(AppBean lhs, AppBean rhs) {
// 用户程序排在前面
boolean lhsSystem = lhs.isSystem;
boolean rhsSystem = rhs.isSystem;
int lhsInt = lhsSystem ? 1 : 0;
int rhsInt = rhsSystem ? 1 : 0;
return lhsInt - rhsInt;
}
});
03.软件管家_ListView头条目添加
A.开源框架 StickyListHeader_library 带有头和吸附效果的ListView
1.搜索开源项目 www.github.com ->Sticky
2.下载download
3.解压开源项目
4.选择开源项目的library导入eclipse里面.注意要保存到工作空间
5.StickyListHeader_library 不是jar包.是一个活动的library依赖.所以此时.添加依赖.add->library
6.查阅github上面,框架的说明文档
B.StickyListHeader_library的使用方式:
1.修改了原始布局的listview.
<se.emilsjolander.stickylistheaders.StickyListHeadersListView
android:id="@+id/am_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2.关心控件.findViewById() 强制转换发生改变
3.适配器.需要实现接口.重写方法
private class AppAdapter extends BaseAdapter implements StickyListHeadersAdapter
4.重写方法
getHeaderView() ->返回头显示的布局
getHeaderId() ->返回头的个数id.在哪个id显示
5.不要忘记写 holderView
6.关于getHeaderId()的写法
@Override
public long getHeaderId(int position) {
// 返回值代表一种类型的头
AppBean bean = mDatas.get(position);
return bean.isSystem ? 0 : 1;
}
04.软件管家_popupwindow显示方式
a.准备视图View,建议使用打气筒View.inflate()
b.创建PopupWindow的对象
PopupWindow popup = new PopupWindow(view,width,height);
width = ViewGroup.LayoutParams.WRAP_CONTENT
height = ViewGroup.LayoutParams.WRAP_CONTENT
c.显示PopupWindow
//参数1:vv表示显示在哪一个视图的左下角位置.此时此刻指的是被点击的listview条目视图
//参数2:popup左上角x轴偏移度.正数向右,负数向左
//参数3:popup左上角y轴偏移度.正数向下,负数向上
popup.showAsDropDown(vv, 80, -60);
d.优化的操作,只显示一个.设置额外的属性
window.setFocusable(true);// 获得焦点
window.setBackgroundDrawable(new ColorDrawable());//设置背景(设置背景之后,才有动画效果)
window.setTouchable(true);//设置可以触摸
05.PopupWindow布局和动画实现
a.布局的实现: 打气筒View.inflate()
b.动画的实现
01.Java代码写法
popup.setAnimationStyle(R.style.popAnimation);
02.style的写法
<style name="popAnimation">
<item name="android:windowEnterAnimation">@anim/pop_enter</item>
<item name="android:windowExitAnimation">@anim/pop_exit</item>
</style>
03.在anim文件夹,定义进入的动画和出去的动画
res/anim/pop_enter
res/anim/pop_exit
04.还需要在interpolator定义插值器
res/interpolator/overshoot.xml
res/interpolator/anticipate.xml
06.ListView条目上面的卸载操作
a.在popupWindow上面点击事件.卸载.隐式意图
Intent intent = new Intent();
intent.setAction("android.intent.action.DELETE");
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
b.卸载完毕之后.隐藏popupWindow
popup.dismiss();
c.动态的广播接收者,监听卸载信息
注册广播onCreate() registerReceiver(mUninstallReceiver, filter);
//意图过滤器
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);// 包卸载的行为
filter.addDataScheme("package");
反注册onDestroy()方法 unregisterReceiver(mUninstallReceiver);
d.在广播接收者的onReceive()遍历集合.判断卸载的包.移除这一项.通知适配器.更新UI
//为什么不用for循环.并发修改异常
//例如: 集合有 10个 list.size(). 3.删除第3个.长度9个
//如果不信,自己玩一下
if (bean.packageName.equals(packageName)) {
// 有的--》移除
iterator.remove();
break;
}
//更新UI
mAdapter.notifyDataSetChanged();
06.ListView条目上面打开其他应用和查看应用详情
1.打开其他应用
PackageManager pm = getPackageManager();//得到包管理者对象
final Intent intent = pm.getLaunchIntentForPackage(packageName);//通过包名.得到启动项意图
startActivity(intent);//启动
---------------
//判断有没有启动项
if (intent == null) {
// 没有启动项
tvOpen.setVisibility(View.GONE);
}
2.查看应用详情
a.通过查看上层源码--->清单文件--->InstallApp...--->隐式意图
b.使用隐式意图打开详情界面
Intent intent = new Intent();
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
c.隐藏popupWindow
popup.dismiss();
07.三方分享的ShareSDK
SDK: soft Develope kit 软件开发工具集
第三方的SDK:
baiduMap.高德地图.支付宝SDK(三方集成的SDK).微博SDK.聚合数据SDK.科大讯飞SDK.
需要申请帐号:手机号.营业执照.身份证.报销发票.
使用需要Appkey
具体的操作,开发文档.照着文档编写.不懂的就问:公司客服
08.include标签的使用(以后遇到比较长的layout布局文件,可以分成N个XML文件)
a.include标签的作用:抽取布局的XML文件.
b.抽取的操作
<include layout="@layout/include_loading" />
c.定义的XML文件res/layout/include_loading
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/include_ll_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
android:visibility="gone" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/loading_bg" />
<TextView
style="@style/textNormal"
android:text="加载中..." />
</LinearLayout>
09.统计正在运行进程数&统计手机总的进程数
a.统计正在运行进程数 ActivityManager
public static int getRunningProcessCount(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
// 获得正在运行的进程
List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
return list.size();
}
b.手机总的进程数目
得到 application/activity/service/receiver/provider
防止出现重复的,使用的是 set集合 ---> HashSet集合
PackageManager pm = context.getPackageManager();//得到包管理器对象
List<PackageInfo> packages = pm.getInstalledPackages(0);//包信息
//循环遍历.得到数据
// application---不会为空
ApplicationInfo applicationInfo = info.applicationInfo;
String processName = applicationInfo.processName;
set.add(processName);
// activity----可能为空
ActivityInfo[] activities = info.activities;
if (activities != null) {
for (ActivityInfo activityInfo : activities) {
set.add(activityInfo.processName);
}
}
c.设置数据在自定义组合控件进度条上面
mPsvProcess.setMax(总的进程数);
mPsvProcess.setProgress(正在运行的进程数);
10.进程管理_内存数据的获取
a.获得到已经使用的内存数据ActivityManager
public static long getUsedMemory(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
long total = 0;
// 获得正在运行的进程
List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
for (RunningAppProcessInfo info : list) {
// 进程id
int pid = info.pid;
MemoryInfo memoryInfo = am.getProcessMemoryInfo(new int[] { pid })[0];
long memory = memoryInfo.getTotalPss() * 1024;
total += memory;
}
return total;
}
b.获得到全部的内存数据.保存在手机 /proc/meminfo 文件第一行
public static long getTotalMemory() {
File file = new File("/proc/meminfo");
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
// MemTotal: 513492 kB
String readLine = reader.readLine();
readLine = readLine.replace("MemTotal:", "");
readLine = readLine.replace("kB", "");
readLine = readLine.trim();
long result = Long.parseLong(readLine) * 1024;
return result;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
c.设置数据在自定义组合控件进度条上面
mPsvProcess.setMax(总的内存数据);
mPsvProcess.setProgress(已经用过的内存数据);
11.进程管理_Adapter简单实现
采用的是开源库
<se.emilsjolander.stickylistheaders.StickyListHeadersListView
android:id="@+id/am_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
适配器的写法
private class ProcessAdapter extends BaseAdapter implements StickyListHeadersAdapter {...}