您的位置:首页 > 移动开发 > Android开发

Android项目实战--手机卫士02--与服务器交互

2013-08-29 14:26 387 查看
好啦,我们继续我们昨天的那个项目,昨天我们只完成了一个程序启动时的欢迎界面,但是提到了,启动那个界面时会进行版本的检查,所以今天我们就做那个版本的检查那一块。

既然要做版本检查,那肯定要有服务器啦,所以我们就用到tomcat啦,因为这个项目是Android, 所以我就不写那个服务器端的程序啦,我只用tomcat来进行一个简单的从服务器读取数据,然后更新程序。不会专门写一个服务器端来进行业务的处理。

好,废话不多说,可能有些人还没接触过Web方面的,所以我把tomcat的搭建也简单的说一下,大神可以直接跳到下面去。

首先,我们去tomcat官网上下载一个tomcat
下载地址



在这里选择是32位的还是64位的



下载下来后,安装也很简单,直接解压出来就行啦(前提是你的java环境要正确)

解压好之后,我们就可以去到它的bin目录下面,双击那个startup.bat文件啦





然后我们就会看到一个黑呼呼的界面





然后,我们去浏览器输入 http://localhost:8080/ 然后出现下面的界面,那就说明你的tomcat配置成功了





那么,我们的服务器配置好之后,我们就要用它来为我们的app做一些东西啦

首先,我们在tomcat的webapps目录下载新建一个文件夹叫Security(这个是个人喜欢的,因为我们app叫Security)



update.xml里面的内容

<?xml version="1.0" encoding="utf-8"?>
<update>
	<version>1.0</version>
	<description>这里写一些这个版本的特点</description>
	<apkurl>http://192.168.1.5:8080/Security/new.apk</apkurl>
	<!--这里的ip地址一定要写你服务器所在的电脑的ip地址,我们会在Security这个目录下面放置一下new.apk的,用来更新的-->
</update>


好啦,现在测试一下,在浏览器里面输入http://localhost:8080/Security/update.xml 如果能够看到我们刚刚写的update.xml里面的内容,那么,你的服务器就配置成功啦!

先恭喜你,你又会弄服务器啦!!!!!

ps:因为这个要涉及服务器这些知识,所以我们这个app运行的手机上的ip一定要和你运行tomcat那台电脑上的ip是处于同一个局域网的,当时如果有外部ip那就不同,所以最好就是电脑和手机接同一个wifi这个一般会在同一个局域网啦,当然,用模拟器就一定是在同一个局域网啦



好啦,配置好了服务器后,我们就可以继续我们的项目啦,因为要和服务器交互,那么,我们肯定要把交互的地址存起来的啦,所以我们在我们的项目的values目录下新建一个config.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    <string name="serverUrl">http://192.168.1.5:8080/Security/update.xml</string>
    
</resources>


好啦,现在,我们的任务是从服务器上读取到update.xml里面的内容,然后再解析它,拿到apk的下载地址,和最新的版本与当时的版本比较嘛,看一下要不要下载,所以我们就要有一个model来存放这些更新的信息了嘛

所以我们就新建一个类com.xiaobin.security.domain.UpdateInfo

package com.xiaobin.security.domain;

public class UpdateInfo
{
	private String version;
	private String description;
	private String url;
	
	public String getVersion()
	{
		return version;
	}
	public void setVersion(String version)
	{
		this.version = version;
	}
	public String getDescription()
	{
		return description;
	}
	public void setDescription(String description)
	{
		this.description = description;
	}
	public String getUrl()
	{
		return url;
	}
	public void setUrl(String url)
	{
		this.url = url;
	}
	
}




然后呢,我们要从服务器上读取到一个update.xml嘛,所以我们也要新建一个类,用来与服务器交互啦

所以新建一个类com.xiaobin.security.engine.UpdateInfoService

package com.xiaobin.security.engine;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.content.Context;

import com.xiaobin.security.domain.UpdateInfo;

public class UpdateInfoService
{
	
	private Context context;
	
	public UpdateInfoService(Context context)
	{
		this.context = context;
	}
	
	public UpdateInfo getUpdateInfo(int urlId) throws Exception
	{
		String path = context.getResources().getString(urlId);//拿到config.xml里面存放的地址
		URL url = new URL(path);
		HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();//开启一个http链接
		httpURLConnection.setConnectTimeout(5000);//设置链接的超时时间,现在为5秒
		httpURLConnection.setRequestMethod("GET");//设置请求的方式
		InputStream is = httpURLConnection.getInputStream();//拿到一个输入流。里面包涵了update.xml的信息
		return UpdateInfoParser.getUpdateInfo(is);//解析xml
	}

}




刚刚上面那个类里面有一个解析xml的操作,所以我们现在把解析xml的这个类也写一下

所以新建一个类com.xiaobin.security.engine.UpdateInfoParser

package com.xiaobin.security.engine;

import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;

import android.util.Xml;

import com.xiaobin.security.domain.UpdateInfo;

public class UpdateInfoParser
{
	
	public static UpdateInfo getUpdateInfo(InputStream is) throws Exception
	{
		UpdateInfo info = new UpdateInfo();
		XmlPullParser xmlPullParser = Xml.newPullParser();
		xmlPullParser.setInput(is, "utf-8");
		int type = xmlPullParser.getEventType();
		while(type != XmlPullParser.END_DOCUMENT)
		{
			switch(type)
			{
				case XmlPullParser.START_TAG :
					if(xmlPullParser.getName().equals("version"))
					{
						info.setVersion(xmlPullParser.nextText());
					}
					else if(xmlPullParser.getName().equals("description"))
					{
						info.setDescription(xmlPullParser.nextText());
					}
					else if(xmlPullParser.getName().equals("apkurl"))
					{
						info.setUrl(xmlPullParser.nextText());
					}
					break;
					
				default : 
					break;
			}
			type = xmlPullParser.next();
		}
		return info;
	}

}




好啦,现在我们回去给我们昨天写的那个SplashActivity加上一些逻辑啦

package com.xiaobin.security.ui;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.xiaobin.security.R;
import com.xiaobin.security.domain.UpdateInfo;
import com.xiaobin.security.engine.UpdateInfoService;

public class SplashActivity extends Activity
{
	private TextView tv_version;
	private LinearLayout ll;
	
	private UpdateInfo info;
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.splash);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		
		tv_version = (TextView) findViewById(R.id.tv_splash_version);
		String version = getVersion();
		tv_version.setText("版本号  " + version);
		
		ll = (LinearLayout) findViewById(R.id.ll_splash_main);
		AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
		alphaAnimation.setDuration(2000);
		ll.startAnimation(alphaAnimation);
		
		if(isNeedUpdate(version))
		{
			showUpdateDialog();
		}
	}
	
	private void showUpdateDialog()
	{
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setIcon(android.R.drawable.ic_dialog_info);
		builder.setTitle("升级提醒");
		builder.setMessage(info.getDescription());
		builder.setCancelable(false);
		
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
		{
			
			@Override
			public void onClick(DialogInterface dialog, int which)
			{
				// TODO Auto-generated method stub
				
			}
		});
		builder.setNegativeButton("取消", new DialogInterface.OnClickListener()
		{

			@Override
			public void onClick(DialogInterface dialog, int which)
			{
				// TODO Auto-generated method stub
				
			}
			
		});
		builder.create().show();
	}

	private boolean isNeedUpdate(String version)
	{
		UpdateInfoService updateInfoService = new UpdateInfoService(this);
		try
		{
			info = updateInfoService.getUpdateInfo(R.string.serverUrl);
			String v = info.getVersion();
			if(v.equals(version))
			{
				System.out.println("不用更新");
				return false;
			}
			else
			{
				System.out.println("要更新");
				return true;
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			Toast.makeText(this, "获取更新信息异常,请稍后再试", Toast.LENGTH_SHORT).show();
		}
		return false;
	}

	private String getVersion()
	{
		try
		{
			PackageManager packageManager = getPackageManager();
			PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0);
			
			return packageInfo.versionName;
		}
		catch (NameNotFoundException e)
		{
			e.printStackTrace();
			return "版本号未知";
		}
	}

}



因为我们访问了Internet。所以要在AndroidManifest里面加上权限

<uses-permission android:name="android.permission.INTERNET"/>




好啦,现在可以进行测试一下啦,只要修改update.xml里面的那个version,那样就会提示下载的啦,今天的代码有点多,而且有点乱,所以如果有什么不明白的,或出了什么问题的,都可以留言交流,

最后提示一个,记得要把服务器打开再测试,不然就没效果啦

update:

很多朋友都在这里说不能与服务器交互,其实是这样的,这个一个bug来的,这个bug就是在Android4以上,我们已经不能在主线程里面进行网络操作的啦,如果进行网络操作,就会报错

所以我们就要做一下改动,我们在onCreate方法里面开启一个线程,用来检测更新信息的

new Thread()
		{
			public void run() 
			{
				try
				{
					UpdateInfoService updateInfoService = new UpdateInfoService(SplashActivity.this);
					info = updateInfoService.getUpdateInfo(R.string.serverUrl);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			};
		}.start();


然后呢,就在原来的isNeedUpdate方法里面进行一些修改啦

private boolean isNeedUpdate(String version)
	{
		if(info == null)
		{
			Toast.makeText(this, "获取更新信息异常,请稍后再试", Toast.LENGTH_SHORT).show();
			loadMainUI();
			return false;
		}
		String v = info.getVersion();
		if(v.equals(version))
		{
			Log.i(TAG, "当前版本:" + version);
			Log.i(TAG, "最新版本:" + v);
			loadMainUI();
			return false;
		}
		else
		{
			Log.i(TAG, "需要更新");
			return true;
		}
	}


好啦,到这里,我们的这个bug就修复的啦。在进入今天的内容之前,先谢谢一位网友啦,是他发现这个问题的,非常感谢!

以上这些更新的信息,大家和下一篇文章一起看,就会很清楚的啦,这样子,安装apk也应该可以成功的啦!

今天源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: