《Android基于IIS的APK下载(一)自定义更新控件》中实现了更新控件的自定义,那么我们要如何引用这些控件并呈现到UI中呢?
首先,我们来定义一下主界面,代码如下。
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/activity_main_checkUpdate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/activity_main_checkUpdate" /> <ListView android:id="@+id/activity_main_updateItems" android:layout_width="fill_parent" android:layout_height="fill_parent" ></ListView> </LinearLayout>注:
1、界面分成两部分,第一部分是获取更新列表的按钮,第二部分是呈现更新列表。这两部分我们用LinearLayout垂直布局来实现。
2、在呈现更新列表的部分,我们使用ListView,然后代码中灌入数据。灌入数据,我们使用Adapter的形式来实现。下面是实现的代码。
UpdateItemsAdapter.java
package com.example.apkupdate; import java.io.File; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.content.pm.PackageInfo; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.kitsp.contentsp.IntentSp; import com.kitsp.httpsp.REQUEST_KEYS; import com.kitsp.httpsp.REQUEST_MESSAGES; import com.kitsp.httpsp.RequestSp; import com.kitsp.widgetsp.MessageBoxSp; public class UpdateItemsAdapter extends BaseAdapter { private List<UpdateItem> _updateItems = null; private Context _context = null; public UpdateItemsAdapter(List<UpdateItem> updateItems, Context context) { _updateItems = updateItems; _context = context; } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); } @Override public int getCount() { // TODO Auto-generated method stub if (_updateItems.isEmpty()) { return 0; } return _updateItems.size(); } @Override public Object getItem(int position) { if (_updateItems.isEmpty()) { return null; } return _updateItems.get(position); } @Override public long getItemId(int position) { if (_updateItems.isEmpty()) { return 0; } return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (_context == null) { return null; } UpdateItem updateItem = (UpdateItem) getItem(position); if (updateItem == null) { return null; } View updateItemLayout = View.inflate(_context, R.layout.update_item, null); if (updateItemLayout == null) { return null; } ImageView app_imageView = (ImageView) updateItemLayout .findViewById(R.id.update_item_app_image); TextView appName_textView = (TextView) updateItemLayout .findViewById(R.id.update_item_app_name); TextView appOldVersion_textView = (TextView) updateItemLayout .findViewById(R.id.update_item_app_old_version); TextView appNewVersion_textView = (TextView) updateItemLayout .findViewById(R.id.update_item_new_version); final Button behavior_button = (Button) updateItemLayout .findViewById(R.id.update_item_behavior); String oldVersion=FetchPackageVersion(updateItem.GetFeaturePackage()); if(oldVersion!=null&&oldVersion.length()>0) { updateItem.SetOldVersion(oldVersion); } appName_textView.setText(updateItem.GetName()); appOldVersion_textView.setText(updateItem.GetOldVersion()); appNewVersion_textView.setText(updateItem.GetNewVersion()); boolean isNewVersion = IsNewVersion(updateItem.GetOldVersion(), updateItem.GetNewVersion()); updateItem.SetBehavior(isNewVersion ? UPDATE_BEHAVIORS.UPDATE : UPDATE_BEHAVIORS.NO_UPDATE); behavior_button.setEnabled(isNewVersion); behavior_button.setText(updateItem.GetBehavior()); behavior_button.setTag(updateItem); behavior_button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ExecuteBehavior(behavior_button); } }); return updateItemLayout; } private String FetchPackageVersion(String packageName) { if (packageName == null || packageName.length() <= 0) { return null; } List<PackageInfo> packages = _context.getPackageManager() .getInstalledPackages(0); for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); if (packageInfo.packageName.equals(packageName)) { return packageInfo.versionName; } } return null; } private boolean IsNewVersion(String oldVersion, String newVersion) { if (newVersion == null || newVersion.length() <= 0) { return false; } if (oldVersion == null || oldVersion.length() <= 0 || oldVersion.equals(UPDATE_BEHAVIORS.NOT_INSTALL)) { return true; } String[] olds = oldVersion.split("\\."); String[] news = newVersion.split("\\."); int compareLength = (olds.length > news.length) ? news.length : olds.length; for (int index = 0; index < compareLength; index++) { if (Integer.parseInt(olds[index]) > Integer.parseInt(news[index])) { return false; } else if (Integer.parseInt(olds[index])< Integer .parseInt(news[index])) { return true; } } if (news.length > olds.length) { return true; } return false; } }注:
1、UpdateItemsAdapter继承自BaseAdapter,然后重载相应的方法。关键是getView的重载。
2、在getView中,我们获取了update_item.xml的布局,然后抓取相关的控件,并填入数据。在获取update_item.xml的布局时,需要一个context,所以UpdateItemsAdapter的构造函数中需要传入一个context,以方便使用。
3、UpdateItem是自定义的一个类,具体可以参考后面的代码。
4、在updateItem中有一个GetFeaturePackage()函数,获取相应的特征包的名称,根据该特征包的名称从机器中获取相应的版本信息。该特征包的名称会在服务器中进行配置,以便于更灵活的更新。当然如果要实现各个包的更新,可以增加更详细的明细表来实现。
5、IsNewVersion通过新旧版本的比较,判断安装包是否是最新的,然后在behavior_button中呈现相应的行为。
6、对于ExecuteBehavior(behavior_button)将会在后文中实现,该函数的主要功能就是根据不同的行为执行不同的动作,如更新、下载、安装等。
UpdateItem.java
package com.example.apkupdate; public class UpdateItem { private String _name=""; private String _featurePackage=""; private String _oldVersion=UPDATE_BEHAVIORS.NOT_INSTALL; private String _newVersion=""; private String _url=""; private String _behavior=UPDATE_BEHAVIORS.NOT_INSTALL; private String _savePath=""; public void SetName(String name) { _name=name; } public String GetName() { return _name; } public void SetFeaturePackage(String featurePackage) { _featurePackage=featurePackage; } public String GetFeaturePackage() { return _featurePackage; } public void SetOldVersion(String oldVersion) { _oldVersion=oldVersion; } public String GetOldVersion() { return _oldVersion; } public void SetNewVersion(String newVersion) { _newVersion=newVersion; } public String GetNewVersion() { return _newVersion; } public void SetUrl(String url) { _url=url; } public String GetUrl() { return _url; } public void SetBehavior(String behavior) { _behavior=behavior; } public String GetBehavior() { return _behavior; } public void SetSavePath(String savePath) { _savePath=savePath; } public String GetSavePath() { return _savePath; } }
UPDATE_BEHAVIORS.java
package com.example.apkupdate; public class UPDATE_BEHAVIORS { public final static String NOT_INSTALL="Not Install"; public final static String UPDATE="Update"; public final static String INSTALL="Install"; public final static String NO_UPDATE="No Update"; }
这里我们已经将更新列表给显示出来了,但是更新列表的数据从何而来呢?
请参看后文Android基于IIS的APK下载(三)用JSON传输更新数据