[安卓]手机管家(二)splash续(附加签名问题)

继续

之前对比了用户和服务器端版本,当可升级的时候,要做进一步处理,而不仅仅是toast一个"有新版本"

case MSG_VERSION_DIFF:
			    //弹出通知
				Builder builder = new Builder(SplashActivity.this);
				builder.setTitle("发现新版本");
				builder.setMessage(description);
				//需要实现一个MyDialogOnclickListener传进来
				builder.setPositiveButton("升级",new MyDialogOnclickListener());
				builder.setNegativeButton("取消",new MyDialogOnclickListener());
				builder.show();
			    break;			    
			 default:
				 break;
			}
		};
	};
	
	class MyDialogOnclickListener implements OnClickListener{
		@Override
		public void onClick(DialogInterface dialog, int which) {
			// TODO Auto-generated method stub
			
		}	
	}


 

继续~对于点击事件,需要判断,确认就直接下载,取消就回去

确认:下载,这里用之前做的app,去info里改下信息,并将apk放到root里

涉及到文件的保存,这里用AsyncHttpClient,需要loopj,拷贝过来后,base里有问题,去掉原有导包重新来

class MyDialogOnclickListener implements OnClickListener{
		@Override
		public void onClick(DialogInterface dialog, int which) {
			// TODO Auto-generated method stub
			if(which == DialogInterface.BUTTON_POSITIVE){
				//用户点击了确认下载。这里开始去下载最新版本
				AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
				//需要一个handler
				asyncHttpClient.get(downloadurl, new MyDownloadHandler());
			}else{
				//用户点击了取消下载。这时候应该跳入到主界面
				
			}		
		}	
	}
	class MyDownloadHandler extends AsyncHttpResponseHandler{

		@Override
		public void onSuccess(int statusCode, Header[] headers,
				byte[] responseBody) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onFailure(int statusCode, Header[] headers,
				byte[] responseBody, Throwable error) {
			// TODO Auto-generated method stub
			
		}		
	}


下载并安装:

@Override
		public void onSuccess(int statusCode, Header[] headers,
				byte[] responseBody) {
			// TODO Auto-generated method stub
			File file = new File("storage/sdcard/mobilesafe.apk");
			try {
				FileOutputStream fos = new FileOutputStream(file);
				fos.write(responseBody);
				fos.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}		
			installapk(file);
		}
		private void installapk(File file) {
			// TODO Auto-generated method stub
			Intent intent = new Intent("android.intent.action.VIEW");
			intent.setDataAndType(Uri.fromFile(file), 	"application/vnd.android.package-archive");
			startActivity(intent);
		}


此时走起一个发现解析错误,需要写权限

OK~能够安装

但是这个还有一个方法需要添加,显示安装进度,需要一个view,在splash的layout里加入 

 <TextView
        android:id="@+id/tv_splash_downloadprogress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:textColor="#000000" />


       

oncreate里初始化

@Override
		public void onProgress(int bytesWritten, int totalSize) {
			// TODO Auto-generated method stub
			super.onProgress(bytesWritten, totalSize);
			tv_splash_downloadprogress.setText(bytesWritten+"/"+totalSize);
		}


 

bin目录下的apk没有签名,不能发布到市场上,小范围安装可以

关于签名,导出整个项目时,

没有签名,系统有一个测试签名,在windows下的preference的build里有一个路径

这个可以填到location里,但是还需要一个password,一般就是android

自己创建的可以和系统的类似,改一下最后的文件名就好,第二次填密码那要注意填有效期,必须能达到2033年

发布不同版本时,首选是包名必须相同,其次是签名一致,所以在升级时要用到之前的签名,当然manifest里的版本号也要改下~

 

继续,当可以升级,用户点击取消则应该跳到homeactivity,要完成这个activity和layout

else{
				//用户点击了取消下载。这时候应该跳入到主界面
				enterHome();
			}		
		}	
	}
	private void enterHome() {
		Intent intent = new Intent(SplashActivity.this, HomeActivity.class);
		startActivity(intent);
	}


homeactivity

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HomeActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		TextView tv = new TextView(this);
		tv.setText("我是主界面");
		setContentView(tv);
		
	}
}

manifest里要声明下

 注意handler里,版本相同时,进入home

当出现意外时,比如服务器挂了,这个时候应该有相应处理,这时不能在异常处理里用enterhome(),因为主线程不能操作UI,所以应该利用handler发消息

注意,由于这里涉及多种消息的发送,其实可以做一些优化,把msg的声明拿出来,添加一个finally,在里面发消息,而各种状况里只需说明是哪种消息即可

 

 

异常里的消息

并且提示错误代码,给出反馈

 

有一个细节,当初设了一个notitle,但是背景成了黑色,现在要调成白色并且依然notitle,那么可以在values里的style加一个notitle条目,再在manifest里改主题

取消后,带参数的跳转

@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);

		if (requestCode==100 && resultCode==RESULT_CANCELED) {
			enterHome();
		}
	}

这里有两个取消,一个是直接不升级,进入home,另一个是点了升级,但是在安装的时候又选择不安张,此时也应该可以跳转到home

在安装里应该是一个带参数的跳转


要实现进入下载或者homeactivity后点back键返回九宫格,则需要销毁这个activity,这样就能回到栈底

注意IP地址改动,服务器端的info文件里的地址也要改动。。

在超时等待的时候,加一个小圆圈转动,提升体验~需要ProgressBar

<ProgressBar
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_below="@id/tv_splash_version"
           android:layout_marginTop="5dp"
           android:layout_centerHorizontal="true"/>
</RelativeLayout>


这一段的完整代码

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.Header;
import org.json.JSONException;
import org.json.JSONObject;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;

import utils.WebUtils;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.widget.TextView;
import android.widget.Toast;

public class SplashActivity extends Activity {
	protected static final int MSG_VERSION_SAME =0;
	protected static final int MSG_VERSION_DIFF =1;
	protected static final int MSG_ERROR_URLMALFORMED = 10;
	protected static final int MSG_ERROR_JSON = 20;
	protected static final int MSG_ERROR_IO = 30;
	private String description;
	private String downloadurl;
	private String version;
	private TextView tv_splash_downloadprogress;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_splash);
		TextView tv_splash_version = (TextView) findViewById(R.id.tv_splash_version);
		//上面的声明要注意是空字符串,而不是null
		tv_splash_version.setText("版本: "+getVersion());
		//解析下载进度
		tv_splash_downloadprogress = (TextView) findViewById(R.id.tv_splash_downloadprogress);
		//获取服务器端版本号
		Update();
	}
	
	Handler myHandler = new Handler(){
		public void handleMessage(android.os.Message msg){
			switch(msg.what){
			case MSG_VERSION_SAME:
				//进入主界面
				enterHome();
				break;
			case MSG_VERSION_DIFF:
			    //弹出通知
				Builder builder = new Builder(SplashActivity.this);
				builder.setTitle("发现新版本");
				builder.setMessage(description);
				//需要实现一个MyDialogOnclickListener传进来
				builder.setPositiveButton("升级",new MyDialogOnclickListener());
				builder.setNegativeButton("取消",new MyDialogOnclickListener());
				builder.show();
			    break;	
			case MSG_ERROR_IO:
				 Toast.makeText(getApplicationContext(), "错误代码"+MSG_ERROR_IO, 1).show();
				 enterHome();
			     break;
			case MSG_ERROR_JSON:
				 Toast.makeText(getApplicationContext(), "错误代码"+MSG_ERROR_JSON, 1).show();
  				 enterHome();
			     break;
			case MSG_ERROR_URLMALFORMED:
				 Toast.makeText(getApplicationContext(), "错误代码"+MSG_ERROR_URLMALFORMED, 1).show();
				 enterHome();
				break;
			 default:
				 break;
			}
		};
	};
	
	class MyDialogOnclickListener implements OnClickListener{
		@Override
		public void onClick(DialogInterface dialog, int which) {
			// TODO Auto-generated method stub
			if(which == DialogInterface.BUTTON_POSITIVE){
				//用户点击了确认下载。这里开始去下载最新版本
				AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
				//需要一个handler
				asyncHttpClient.get(downloadurl, new MyDownloadHandler());
			}else{
				//用户点击了取消下载。这时候应该跳入到主界面
				enterHome();
			}		
		}	
	}
	private void enterHome() {
		Intent intent = new Intent(SplashActivity.this, HomeActivity.class);
		startActivity(intent);
		//要实现点back键返回开始的activity,则需要销毁这个activity,这样就能回到栈底
		finish();
	}
	//进入安装后用户又取消,这时候应该能直接进入home,这是带参数值的跳转
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode==100 && resultCode==RESULT_CANCELED) {
			enterHome();
		}
	}
	class MyDownloadHandler extends AsyncHttpResponseHandler{

		@Override
		public void onSuccess(int statusCode, Header[] headers,
				byte[] responseBody) {
			// TODO Auto-generated method stub
			File file = new File("storage/sdcard/mobilesafe.apk");
			try {
				FileOutputStream fos = new FileOutputStream(file);
				fos.write(responseBody);
				fos.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}		
			installapk(file);
		}
		private void installapk(File file) {
			// TODO Auto-generated method stub
			Intent intent = new Intent("android.intent.action.VIEW");
			intent.setDataAndType(Uri.fromFile(file), 	"application/vnd.android.package-archive");
			startActivityForResult(intent,100);
		}
		@Override
		public void onProgress(int bytesWritten, int totalSize) {
			// TODO Auto-generated method stub
			super.onProgress(bytesWritten, totalSize);
			tv_splash_downloadprogress.setText(bytesWritten+"/"+totalSize);
		}
		@Override
		public void onFailure(int statusCode, Header[] headers,
				byte[] responseBody, Throwable error) {
			// TODO Auto-generated method stub
			
		}		
	}
	private void Update() {
		// TODO Auto-generated method stub
		new Thread(new Runnable(){

			@Override
			public void run() {
				String path = "http://192.168.3.100/version_info.json";
				Message msg = myHandler.obtainMessage();
				try {
					URL url = new URL(path);
					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
					conn.setReadTimeout(5000);
					conn.setConnectTimeout(2000); //实际发布版本的时候,超时实际最好稍微长一些
					conn.setRequestMethod("GET");
					conn.connect();
					if (conn.getResponseCode()==200) {
						InputStream is=	conn.getInputStream();
						String jsontext = WebUtils.gettextFromInputStream(is, null);
	                    JSONObject jsonObject = new JSONObject(jsontext);			
	                    version = jsonObject.getString("version");   
	                    description = jsonObject.getString("description");
	                    downloadurl = jsonObject.getString("downloadurl");
	                    System.out
							.println("SplashActivity.Update().new Runnable() {...}.run()" 
	                        +version
	                        +description
	                        +downloadurl);	                    
	                    if(version.equals(getVersion())){
	                    	//版本一致则进入主页                    	
	                    	msg.what = MSG_VERSION_SAME;
	                    }else{
	                    	//不一致则弹出dialog告诉用户,此时需要handler来处理                    	
	                    	msg.what = MSG_VERSION_DIFF;
	                    }
					}
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					msg.what = MSG_ERROR_URLMALFORMED;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					msg.what = MSG_ERROR_IO;
				}catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					msg.what = MSG_ERROR_JSON;
				}finally{				
					myHandler.sendMessage(msg);
				}
			}
		}).start();
	}

	private String getVersion() {
		//获取版本号
		PackageManager pm = getPackageManager();		
		PackageInfo packageinfo;
		String version="";
		try {
			//第一个参数应该为manifest里的包名而不是工程里的包名,后直接以方法获取~
			packageinfo = pm.getPackageInfo(getPackageName(), 0);
			version = packageinfo.versionName;
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return version;
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值