今天看了一天代码,说实话确实有点晕。
功能点:
start界面布局、目标APP显示及切换。
代码分析:
1.该界面最外层以线型布局将界面垂直分为5大部分,再依次嵌套相对布局和线型布局。这里对布局不过多阐述。
Start界面
Start界面中点击QQ音乐部分后的效果
2.图中QQ音乐图标和文字的显示由用户选择按键目标APP决定。
首先APPLIST是一个自定义对话框。
在第二个界面中listview显示只有与音频相关的APP。这是怎么实现的呢?
首先是在一个AsyncTask中完成,然后就要用到一个很关键的类PackageManger。这是Android系统为我们提供的一个管理类,它的主要职责是管理应用程序包。 通过它,我们就可以获取应用程序信息。PackageManger。这是Android系统为我们提供的一个管理类,它的主要职责是管理应用程序包。 通过它,我们就可以获取应用程序信息。
PackageManager pManager = context.getPackageManager();获得PackageManager对象。
List<ResolveInfo> avail = pManager.queryBroadcastReceivers(new Intent(
"android.intent.action.MEDIA_BUTTON"), 0);
通过给定条件查询获得所有ResolveInfo对象队列。其中android.intent.action.MEDIA_BUTTON表示系统控 制远程音乐和其他多媒体的方法。在手机上常见的应用就是耳机上的控 制按钮。一般我们手机或者平板上的音乐、视频播放器都会响应这个广播。
但是这里我就不太懂了。代码如下:
public class ApkLoadTask extends AsyncTask<String, AppBean, List<AppBean>> {
private Context context;
private ApkListAdapter adapter;
private String targetPackageName;
public ApkLoadTask(Context mContext, ApkListAdapter mAdapter) {
context = mContext;
adapter = mAdapter;
}
protected List<AppBean> doInBackground(String... params) {
targetPackageName = BlendUtil.getAppTargetPackageName(context);
PackageManager pManager = context.getPackageManager();
try {
load();
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 取出所有侦听音频程序的app,再根据支持手机型号的音乐app进行判断,最终取得本程序支持的音频程序app列表(交集),然后
* 1、更新target
* 2、publish
*
* 注:但当前的程序,好像取得是并集,而且是有多余的并集
* @throws NameNotFoundException
*/
public void load() throws NameNotFoundException {
PackageManager pManager = context.getPackageManager();
List<ResolveInfo> avail = pManager.queryBroadcastReceivers(new Intent(
"android.intent.action.MEDIA_BUTTON"), 0);
List<PackageInfo> appList = BlendUtil.getMusicPackages_2(context);
ArrayList<AppBean> beans = new ArrayList<AppBean>();
//
ArrayList<AppBean> beans2 = new ArrayList<AppBean>(); //restore all
ArrayList<AppBean> beans3 = new ArrayList<AppBean>(); //resort
// 循环1:把所有支持的音乐app包,放到b1和b2列表中
for (int i = 0; i < appList.size(); i++) {
PackageInfo pinfo = appList.get(i);
Drawable icon = pManager.getApplicationIcon(pinfo.applicationInfo);
String appName = (String) pManager.getApplicationLabel(
pinfo.applicationInfo).toString();
String PackageName = pinfo.packageName.toString();
AppBean item = new AppBean();
item.setAppName(appName.replace(" ", ""));
item.setIcon(icon);
item.setPackgeName(PackageName);
item.setImageRes(R.drawable.support);
beans.add(item);
// publishProgress(item);
beans2.add(item); //store
}
// appBeans.add(item);
//循环2:把不在支持列表中的音频程序,添加到b2中:此时,b2=avList与appList的并集
// sort 音乐播放器,其他
for (ResolveInfo info : avail) {
// Log.e("tag", "Info = " + info.loadLabel(pManager));
AppBean item = new AppBean();
item.setAppName(info.loadLabel(pManager).toString()
.replace(" ", ""));
item.setIcon(info.loadIcon(pManager));
item.setPackgeName(info.activityInfo.packageName);
// item.setActivityName(activitykageName);
// item.setServiceName("");
boolean hasAdd = beans.contains(item);// 如果包含,为真
// Debug.d("time", " has add = " +hasAdd);
if (!info.activityInfo.packageName.equals(context.getPackageName())
&& !hasAdd) {
if(info.priority!=2147483647) {
item.setImageRes(R.drawable.nosupport);
// publishProgress(item);
beans2.add(item);
}
}
// appBeans.add(item);
}
//循环3:把不在支持列表中的音频程序,再次 添加到b2中
//感觉和循环2是完全相同的,是否应该去掉!!!!
//confilict
for (ResolveInfo info : avail) {
// Log.e("tag", "Info = " + info.loadLabel(pManager));
AppBean item = new AppBean();
item.setAppName(info.loadLabel(pManager).toString()
.replace(" ", ""));
item.setIcon(info.loadIcon(pManager));
item.setPackgeName(info.activityInfo.packageName);
// item.setActivityName(activitykageName);
// item.setServiceName("");
boolean hasAdd = beans.contains(item);
// Debug.d("time", " has add = " +hasAdd);
if (!info.activityInfo.packageName.equals(context.getPackageName())
&& !hasAdd) {
if(info.priority==2147483647) {
item.setImageRes(R.drawable.conflict);
// publishProgress(item);
beans2.add(item);
}
}
// appBeans.add(item);
}
//循环4:从0开始(最多到100)取target中的值,如果该target中的值与bean2中的app相同,就把该app添加到b3
//resort base on records
for(int i = 0; i < 100; i++) {
String str = AuthoSharePreference.getTargetApp_index(context, i);
if(str != null && !str.equals("") && str.length()>0) {
for (AppBean item : beans2) {
if(item.getPackgeName().equals(str)) {
beans3.add(item);
}
}
} else {
break;
}
}
//循环5:把不在b3中的b2节点,全部添加到b3:此时,b3与b2只有顺序不相同
//new apps detected this time
for (AppBean item : beans2) {
if(beans3.contains(item)) {
continue;
}
else {
beans3.add(item);
}
}
//循环6:根据 b3更新target
//update records
int j = 0;
for (AppBean item : beans3) {
AuthoSharePreference.putTargetApp_index(context, item.getPackgeName(), j);
j++;
}
//循环7
//show:根据b3进行publish
for(int i = 0; i < beans3.size(); i++) {
AppBean item = beans3.get(i);
publishProgress(item);
}
}
注释是我个人的理解,明天再看看吧。新手看这种代码脑子确实有点乱。明天再看看吧。