自定义版本更新ProgressBar下载

本文介绍了一种自定义软件更新提示框的方法,包括布局设计、ListView适配器编写及后台下载逻辑实现等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先给个效果看看啊!



1.先自定义一个布局:updata_layout.xml布局

<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="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:background="@drawable/common_head_bg"
        android:padding="10dp" >

        <TextView
            android:id="@+id/updata_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="发现新版本!"
            android:textColor="#8FC127"
            android:textSize="16sp" />

        <View
            android:id="@+id/view"
            android:layout_width="match_parent"
            android:layout_height="0.7dp"
            android:layout_below="@id/updata_tv"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:background="#999999" />

        <TextView
            android:id="@+id/used_updata"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/view"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:background="@drawable/grey_text"
            android:paddingBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="5dp"
            android:text="当前版本:1.0"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/new_updata"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignTop="@id/used_updata"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/used_updata"
            android:background="@drawable/grey_text"
            android:paddingBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="5dp"
            android:text="新版本:1.1"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/size_updata"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/used_updata"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:background="@drawable/grey_text"
            android:paddingBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="5dp"
            android:text="大小:6.5M"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/day_updata"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignTop="@id/size_updata"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@+id/size_updata"
            android:background="@drawable/grey_text"
            android:paddingBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="5dp"
            android:text="发布时间:2016-11-7"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/updata_tv2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/size_updata"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:text="更新日志" />

        <ListView
            android:id="@+id/update_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/updata_tv2"
            android:layout_marginTop="5dp"
            android:minHeight="100dp"
            android:divider="@android:color/transparent"
            android:dividerHeight="0dp"
            android:layout_marginBottom="10dp"
            android:listSelector="@android:color/transparent"
             />

        <LinearLayout
            android:id="@+id/pblt"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_below="@id/update_list"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:orientation="horizontal" >

            <!--style="?android:attr/progressBarStyleHorizontal"  -->
            <ProgressBar
                android:id="@+id/progress"
                style="@style/ProgressBar_Mini"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1" />

            <TextView
                android:id="@+id/tv_downnum"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="5dp"
                android:text="100%" />
        </LinearLayout>

        <View
            android:id="@+id/view2"
            android:layout_width="match_parent"
            android:layout_height="0.7dp"
            android:layout_below="@id/pblt"
            android:layout_marginTop="5dp"
            android:background="#999999" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_below="@id/view2"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/next_time_tv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="下次在说"
                android:textSize="16sp" />

            <TextView
                android:id="@+id/upgrade_tv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="立刻升级"
                android:textSize="16sp" />
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>
2.编写附带listview中item布局:update_list_item.xml布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/list_item_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp" />

</LinearLayout>

以及附带布局:(1).设置圆角的common_head_bg.xml布局

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <corners android:radius="3dp" /> <!-- 设置圆角的半径 -->
    <!-- 填充 -->
    <solid android:color="@android:color/white" />

</shape>
和grey_text.xml布局

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners android:radius="2.5dp" /><!-- 设置圆角的半径 -->

    <solid android:color="#D0D0D0" />

    <stroke
        android:width="1.2dp"
        android:color="#D0D0D0" />
</shape>
(2).设置进度条的progressbar_mini.xml布局

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />

            <gradient
                android:angle="270"
                android:centerY="0.75"
                android:endColor="#F5F5F5"
                android:startColor="#BEBEBE" />
        </shape>
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="0dip" />

                <gradient
                    android:angle="270"
                    android:centerY="0.75"
                    android:endColor="#165CBC"
                    android:startColor="#85B0E9" />
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />

                <gradient
                    android:angle="270"
                    android:centerY="0.75"
                    android:endColor="#8FC127"
                    android:startColor="#85B0E9" />
            </shape>
        </clip>
    </item>

</layer-list>
最后写好布局之后请不要忘了再styles.xml中添加

 <style name="ProgressBar_Mini" parent="@android:style/Widget.ProgressBar.Horizontal">
        <item name="android:maxHeight">50dip</item>
        <item name="android:minHeight">8dip</item>
        <item name="android:indeterminateOnly">false</item>
        <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
        <item name="android:progressDrawable">@drawable/progressbar_mini</item>
    </style>

3.开始写代码:新建一个UpdateManagers类:

public class UpdateManagers {

    private Context mContext;
    
    //提示语
    private String updateMsg = "有最新的软件包哦,亲快下载吧~";
     
    //返回的安装包url
    private String apkUrl = "http://gdown.baidu.com/data/wisegame/40924c147e592984/shendiaoxialv_28.apk";
     
     
    private Dialog noticeDialog;
     
    private Dialog downloadDialog;
     /* 下载包安装路径 */
    private static final String savePath = "/sdcard/updatedemo/";
     
    private static final String saveFileName = savePath + "UpdateDemoRelease.apk";
 
    /* 进度条与通知ui刷新的handler和msg常量 */
    private ProgressBar mProgress;
    
    private TextView mDownloadTextView = null;
    
    private static final int DOWN_UPDATE = 1;
     
    private static final int DOWN_OVER = 2;
     
    private int progress;
     
    private Thread downLoadThread;
     
    private boolean interceptFlag = false;
    
    public UpdateManagers(Context context) {
        this.mContext = context;
    }
    
    private String CurrentVersion,OldVersion,Size,time =null;
    private ArrayList<String> data  = new ArrayList<String>();
    /**
     * 设置不一样的版本更新
     * @param context 上下文
     * @param url apk下载地址
     * @param CurrentVersion 当前版本号
     * @param OldVersion 旧版本号
     * @param Size 文件大小
     * @param time 发布时间
     * @param data 更新日志数据
     */
    public UpdateManagers(Context context,String CurrentVersion,String OldVersion,String Size,String time,ArrayList<String> data){
    	this.mContext = context;
    	this.CurrentVersion = CurrentVersion;
    	this.OldVersion = OldVersion;
    	this.Size = Size;
    	this.time = time;
    	this.data = data;
    	showNoticeDialog();
    }
    
    
    //外部接口让主Activity调用
    public void checkUpdateInfo(){
        showNoticeDialog();
    }
     
    private Handler mHandler = new Handler(){
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case DOWN_UPDATE:
                mProgress.setProgress(progress);
                String downNum = (progress+"%")+"";
                mDownloadTextView.setText(downNum);
                break;
            case DOWN_OVER:
                 
                installApk();
                break;
            default:
                break;
            }
        };
    };
    
    private void showNoticeDialog(){
    	final AlertDialog builder = new AlertDialog.Builder(mContext).create();
    	builder.setCanceledOnTouchOutside(false);
		builder.show();
		Window window = builder.getWindow();
		window.setBackgroundDrawable(new ColorDrawable(0));
		window.setContentView(R.layout.updata_layout);
		 mProgress = (ProgressBar)window.findViewById(R.id.progress);
		 final LinearLayout pblt = (LinearLayout) window.findViewById(R.id.pblt);
		 pblt.setVisibility(View.GONE);
	     mDownloadTextView =  (TextView) window.findViewById(R.id.tv_downnum);
	     
	     TextView used_updata = (TextView) window.findViewById(R.id.used_updata);
	        used_updata.setText("当前版本:"+CurrentVersion);
	        TextView new_updata = (TextView) window.findViewById(R.id.new_updata);
	        new_updata.setText("新版本:"+OldVersion);
	        TextView size_updata = (TextView) window.findViewById(R.id.size_updata);
	        size_updata.setText("大小:"+Size);
	        TextView day_updata = (TextView) window.findViewById(R.id.day_updata);
	        day_updata.setText("发布时间:"+time);
	        ListView update_list = (ListView) window.findViewById(R.id.update_list);
	        UpdateAdapter adapter = new UpdateAdapter(mContext,data);
	        update_list.setAdapter(adapter);
	     
	     
    	TextView next_time_tv = (TextView) window.findViewById(R.id.next_time_tv);
    	//下次再说
    	next_time_tv.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				builder.dismiss();
				interceptFlag = true;
				pblt.setVisibility(View.GONE);
			}
		});
    	//升级
    	TextView upgrade_tv =(TextView) window.findViewById(R.id.upgrade_tv);
    	upgrade_tv.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				pblt.setVisibility(View.VISIBLE);
                downloadApk();
			}
		});
    	
    }
    
    
    private Runnable mdownApkRunnable = new Runnable() {   
        @Override
        public void run() {
            try {
                URL url = new URL(apkUrl);
             
                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                conn.connect();
                int length = conn.getContentLength();
                InputStream is = conn.getInputStream();
                 
                File file = new File(savePath);
                if(!file.exists()){
                    file.mkdir();
                }
                String apkFile = saveFileName;
                File ApkFile = new File(apkFile);
                FileOutputStream fos = new FileOutputStream(ApkFile);
                 
                int count = 0;
                byte buf[] = new byte[1024];
                 
                do{                
                    int numread = is.read(buf);
                    count += numread;
                    progress =(int)(((float)count / length) * 100);
                    System.out.println("长度:"+length);
                    //更新进度
                    mHandler.sendEmptyMessage(DOWN_UPDATE);
                    if(numread <= 0){   
                        //下载完成通知安装
                        mHandler.sendEmptyMessage(DOWN_OVER);
                        break;
                    }
                    fos.write(buf,0,numread);
                }while(!interceptFlag);//点击取消就停止下载.
                 
                fos.close();
                is.close();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch(IOException e){
                e.printStackTrace();
            }
             
        }
    };
    
    /**
     * 下载apk
     * @param url
     */
     
    private void downloadApk(){
        downLoadThread = new Thread(mdownApkRunnable);
        downLoadThread.start();
    }
    
    /**
     * 安装apk
     * @param url
     */
    private void installApk(){
        File apkfile = new File(saveFileName);
        if (!apkfile.exists()) {
            return;
        }   
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
        mContext.startActivity(i);
     
    }
}
4.listview的适配器代码:新建一个UpdateAdapter类:

public class UpdateAdapter extends BaseAdapter {
	private Context context;
	private ArrayList<String> data = new ArrayList<String>();
	public UpdateAdapter(Context context, ArrayList<String> data) {
		this.context = context;
		this.data = data;
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return data.size();
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return data.get(arg0);
	}

	@Override
	public long getItemId(int arg0) {
		// TODO Auto-generated method stub
		return arg0;
	}

	@Override
	public View getView(int arg0, View convertView, ViewGroup arg2) {
		Holder holder = null;
		String bean = (String) getItem(arg0);
		if (convertView == null) {
			LayoutInflater inflater = LayoutInflater.from(context);
			convertView = inflater.inflate(R.layout.update_list_item, null);
			holder = new Holder(convertView);
			convertView.setTag(holder);
		} else {
			holder = (Holder) convertView.getTag();
		}
		holder.list_item_tv.setText(bean);
		return convertView;
	}

	class Holder {
		TextView list_item_tv; 
		Holder(View v){
			list_item_tv = (TextView) v.findViewById(R.id.list_item_tv);
		}
	}

}

5.不要急我们写好了代码是不是不要忘记权限呀!

  <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
调用方法就不用我说了吧:new UpdateManagers();填写相关内容

源码下载: 点击打开链接下载源码





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值