金绮琳

金绮琳 public 上午

JAVA第十四周

JAVA第十四周

一、修改功能

1.创建FruitUpdateAction.java文件,并添加代码:

  1. package com.demo.action;
  2. import com.demo.dao.FruitDAO;
  3. import com.demo.model.Fruit;
  4. import com.opensymphony.xwork2.ActionSupport;
  5. public class FruitUpdateAction extends ActionSupport {
  6. private Integer id;
  7. private Fruit fruit;
  8. public String execute() throws Exception{
  9. FruitDAO dao = new FruitDAO();
  10. if (null != id && id > 0) {
  11. fruit = dao.findById(id);
  12. }
  13. return SUCCESS;
  14. }

之后在定义:

  1. public Fruit getFruit() {
  2. return fruit;
  3. }
  4. public void setFruit(Fruit fruit) {
  5. this.fruit = fruit;
  6. }
  7. public Integer getId() {
  8. return id;
  9. }
  10. public void setId(Integer id) {
  11. this.id = id;
  12. }
  13. }

3.创建修改界面代码:

  1. <form action="fruit_save.action" method="post" enctype="multipart/form-data" name="form1" id="form1">
  2. <ul>
  3. <li>产品名称:
  4. <input id="title" name="title" size="48" value="$!{fruit.title}" type="text" />
  5. </li>
  6. <li>产品原来图片:
  7. <img src="$!{fruit.img}" width="100" height="100" />
  8. <input name="yldt" type="hidden" id="yldt" value="$!{fruit.img}" />
  9. </li>
  10. <li>产品图片:
  11. <input name="upload" id="img" type="file" style="margin-top:15px;margin-bottom:15px;" />
  12. </li>
  13. <li>产品简介:
  14. <textarea name="content" id="content" cols="20" style="width:363px;" rows="5">$!{fruit.content}</textarea>
  15. </li>
  16. <li>产品名称:
  17. <input id="price" name="price" size="48" value="$!{fruit.price}" type="text" />
  18. </li>
  19. <li>
  20. <input name="id" type="hidden" id="id" value="$!{fruit.id}" />
  21. </li>
  22. <li>
  23. <input type="submit" name="send" id="send" value="保存" style="margin-left:412px;margin-top:20px;"/>
  24. </li>
  25. </ul>
  26. </form>

显示界面如下:

以上需注意的就是id名和form action=”fruit_save.action”需填写正确

4.在FruitSaveAction.java文件进行更改,才能足够去显示之前的数据在修改界面上:

1)定义一个private String yldt;,才能显示图片

2)

  1. if (null != id && id > 0) {
  2. dao.update(img, title, content, price,id);
  3. } else {
  4. dao.save(img, title, content,price);
  5. }
  6. }
  7. return SUCCESS;

↑写一个判断语句才能够不出现报错的页面,就算没有更改成功,也可以不出错

3)定义一下yqdt:

  1. public String getYldt() {
  2. return yldt;
  3. }
  4. public void setYldt(String yldt) {
  5. this.yldt = yldt;
  6. }

5.更改index.html的界面:

  1. <a href="fruit_update.action?id=$!{fruit.id}" style="width:100px;height:25px;background-color:#F5BF53;color:white;margin:5px;line-height:25px;text-align:center;margin-top:5px;font-size:20px;margin-left:2px;";>修改</a>

最后实现功能:

0 条评论
发表评论…
0
张咏达

张咏达 public 上午

第十六周笔记

这周在跟着网上的教程安装Hadoop, 安装前要先设置环境变量JAVA_HOME,加上安装的jdk路径,然后下载安装包 如果安装的是二进制版本的要运行以下命令作为根目录。
mvn package -Pdist,native-win -DskipTests -Dtar

挑选一个目标目录安装,提取(例如tar.gz文件)例如,
C:\deploy>dir
Volume in drive C has no label.
Volume Serial Number is 9D1F-7BAC
Directory of C:\deploy

然后需要编辑配置文件:
第一编辑文件Hadoop-env.cmd将下列行添加到文件的末尾附近。
set HADOOP_PREFIX=c:\deploy
set HADOOP_CONF_DIR=%HADOOP_PREFIX%\etc\hadoop
set YARN_CONF_DIR=%HADOOP_CONF_DIR%
set PATH=%PATH%;%HADOOP_PREFIX%\bin

编辑或创建文件core-site.xml 并确保其具有下列结构:

<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://0.0.0.0:19000</value>
</property>
</configuration>

编辑或创建文件HDFS——site.并添加下列配置项:

<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
创建或编辑 mapred-site.xml在%HADOOP_PREFIX%\etc\hadoop目录下,将%UserName%改成Windows用户名称。
<configuration>
<property>
<name>mapreduce.job.user.name</name>
<value>%USERNAME%</value>
</property>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>yarn.apps.stagingDir</name>
<value>/user/%USERNAME%/staging</value>
</property>
<property>
<name>mapreduce.jobtracker.address</name>
<value>local</value>
</property>
</configuration>

最后,编辑或创建yarn-site.xml:

<configuration>
<property>
<name>yarn.server.resourcemanager.address</name>
<value>0.0.0.0:8020</value>
</property>

<property>
<name>yarn.server.resourcemanager.application.expiry.interval</name>
<value>60000</value>
</property>

<property>
<name>yarn.server.nodemanager.address</name>
<value>0.0.0.0:45454</value>
</property>

<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>

<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>

<property>
<name>yarn.server.nodemanager.remote-app-log-dir</name>
<value>/app-logs</value>
</property>

<property>
<name>yarn.nodemanager.log-dirs</name>
<value>/dep/logs/userlogs</value>
</property>

<property>
<name>yarn.server.mapreduce-appmanager.attempt-listener.bindAddress</name>
<value>0.0.0.0</value>
</property>

<property>
<name>yarn.server.mapreduce-appmanager.client-service.bindAddress</name>
<value>0.0.0.0</value>
</property>

<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>

<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>-1</value>
</property>

<property>
<name>yarn.application.classpath</name>
<value>%HADOOP_CONF_DIR%,%HADOOP_COMMON_HOME%/share/hadoop/common/,%HADOOP_COMMON_HOME%/share/hadoop/common/lib/,%HADOOP_HDFS_HOME%/share/hadoop/hdfs/,%HADOOP_HDFS_HOME%/share/hadoop/hdfs/lib/,%HADOOP_MAPRED_HOME%/share/hadoop/mapreduce/,%HADOOP_MAPRED_HOME%/share/hadoop/mapreduce/lib/,%HADOOP_YARN_HOME%/share/hadoop/yarn/,%HADOOP_YARN_HOME%/share/hadoop/yarn/lib/</value>
</property>
</configuration>
运行c:\deploy\etc\hadoop\hadoop-env.cmd设置环境变量所使用的启动脚本和守护进程
此命令将一个文件系统参数打印次数。看看以下两个字符串,以确保格式命令成功。
14/01/18 08:36:23 INFO namenode.FSImage: Saving image file \tmp\hadoop-username\dfs\name\current\fsimage.ckpt_0000000000000000000 using no compression
14/01/18 08:36:23 INFO namenode.FSImage: Image file \tmp\hadoop-username\dfs\name\current\fsimage.ckpt_0000000000000000000 of size 200 bytes saved in 0 seconds.

运行以下命令以启动名称节点和数据节点上的本地主机。
%HADOOP_PREFIX%\sbin\start-dfs.cmd

为了确认HDFS守护进程是否正在运行,请尝试复制文件到HDFS。
C:\deploy>%HADOOP_PREFIX%\bin\hdfs dfs -put myfile.txt /
C:\deploy>%HADOOP_PREFIX%\bin\hdfs dfs -ls /
Found 1 items
drwxr-xr-x - username supergroup 4640 2014-01-18 08:40 /myfile.txt
C:\deploy>
最后,启动YARN。
%HADOOP_PREFIX%\sbin\start-yarn.cmd

为了验证,我们可以运行一个简单的文本文件WordCount工作我们从刚复制到HDFS。

%HADOOP_PREFIX%\bin\yarn jar %HADOOP_PREFIX%\share\hadoop\mapreduce\hadoop-mapreduce-example
s-2.5.0.jar wordcount /myfile.txt /out

0 条评论
发表评论…
0
李嘉玲

李嘉玲 public 上午

JAVA 第十六周 总结

项目总结

根据前几周的所学到的内容,开始制作项目。两个月以来,在老师的指导下,项目终于完成所有功能,项目工作情况如下:
一、项目基本简介:

Wopop是我制作的短篇说说发布网站,是图片加文字的发布形式。它有点类似微信的朋友圈,可以将每天看到的事物,用手机拍下来,添加上文字,发表到网站上,给人观看。它拥有登录、注册、增删查改的功能。

二、项目内容:
1、数据库
User表

Message表

Contact表

2、首页(用户未登录)

用户没有登录时,修改/删除不了内容,只能查看(用户权限:隐藏修改/删除功能,显示登录、注册功能)

3、注册

新用户须注册才可发布信息,否则只能查看
4、登录

点击验证码图片,刷新验证码
5、首页(用户已登录)

当鼠标经过图片,图片翻转,显示文字内容;
当点击图片,显示图片大图
(用户权限:显示修改/删除功能,显示用户名和退出按钮)

6、添加内容

上传图片和文本信息
(用户权限:如果没有登录,编辑内容隐藏)
7、删除

点击Delete 直接删除内容
8、修改内容

修改上传图片和文本信息
9、联系我们

如果用户有任何疑问,发布问题反馈,发布信息将反馈到数据库

三、存在的不足:
对代码不够熟悉,用户体验功能不够多,项目还有补充的空间。

四、心得体会:
通过这次的项目,我学会了许多相关的知识,有些上课不懂的内容或解决不了的问题,也在老师的指导下,顺利的解决了。对JAVA代码的理解提高了许多。虽然项目做的不够完美,但已经超出我原本的预料,比我以前做的网页要好很多,功能也完善了不少。

0 条评论
发表评论…
0
郑展汉

郑展汉 public 上午

JAVA 第二周总结

本周学习拦截器,并了解拦截器的作用

将配置文件复制到WEB-INF/lib文件夹下,在项目下创建TestInterceptor.java拦截器,代码如下:

  1. package com.test;
  2. import com.opensymphony.xwork2.ActionInvocation;
  3. import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
  4. public class TestInterceptor extends AbstractInterceptor {
  5. @Override
  6. public String intercept(ActionInvocation arg0) throws Exception {
  7. System.out.println("拦截器开始执行");
  8. String str = arg0.invoke();
  9. System.out.println("拦截器结束执行");
  10. return str;
  11. }
  12. }

在struts.xml中,添加连接拦截器的代码,代码如下:

  1. <interceptors>
  2. <interceptor name="testInterception" class="com.text.TestInterceptor"></interceptor>
  3. </interceptors>

在struts.xml下添加代码如下:

  1. <action name="abc" class="com.test.TestAction">
  2. <interceptor-ref name="testInterception"></interceptor-ref>
  3. <interceptor-ref name="defaultStack"></interceptor-ref>
  4. <result type="redirect">/index.action</result>
  5. </action>
  6. <action name="index" class="com.test.IndexAction">
  7. <interceptor-ref name="testInterception"></interceptor-ref>
  8. <interceptor-ref name="defaultStack"></interceptor-ref>
  9. <result type="velocity">/index.html</result>
  10. <result name="error" type="velocity">/error.html</result>
  11. </action>

0 条评论
发表评论…
0
李嘉玲

李嘉玲 public 上午

JAVA 第十五周 总结

继续上周的内容:

验证码

1、在action文件夹,新建CreateImageAction.java,用来创建验证码:

  1. package com.project.action;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics;
  5. import java.awt.image.BufferedImage;
  6. import java.io.ByteArrayInputStream;
  7. import java.io.ByteArrayOutputStream;
  8. import java.util.Random;
  9. import javax.imageio.ImageIO;
  10. import javax.servlet.http.HttpServletResponse;
  11. import javax.servlet.http.HttpSession;
  12. import org.apache.struts2.ServletActionContext;
  13. import com.opensymphony.xwork2.ActionSupport;
  14. public class CreateImageAction extends ActionSupport
  15. {
  16. private ByteArrayInputStream inputStream;
  17. private static int WIDTH = 60;
  18. private static int HEIGHT = 20;
  19. public ByteArrayInputStream getInputStream()
  20. {
  21. return inputStream;
  22. }
  23. public void setInputStream(ByteArrayInputStream inputStream)
  24. {
  25. this.inputStream = inputStream;
  26. }
  27. private static String createRandom()
  28. {
  29. String str = "0123456789qwertyuiopasdfghjklzxcvbnm";
  30. char[] rands = new char[4];
  31. Random random = new Random();
  32. for (int i = 0; i < 4; i++)
  33. {
  34. rands[i] = str.charAt(random.nextInt(36));
  35. }
  36. return new String(rands);
  37. }
  38. private void drawBackground(Graphics g)
  39. {
  40. // 画背景
  41. g.setColor(new Color(0xDCDCDC));
  42. g.fillRect(0, 0, WIDTH, HEIGHT);
  43. // 随机产生 120 个干扰点
  44. for (int i = 0; i < 120; i++)
  45. {
  46. int x = (int) (Math.random() * WIDTH);
  47. int y = (int) (Math.random() * HEIGHT);
  48. int red = (int) (Math.random() * 255);
  49. int green = (int) (Math.random() * 255);
  50. int blue = (int) (Math.random() * 255);
  51. g.setColor(new Color(red, green, blue));
  52. g.drawOval(x, y, 1, 0);
  53. }
  54. }
  55. private void drawRands(Graphics g, String rands)
  56. {
  57. g.setColor(Color.BLACK);
  58. g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18));
  59. // 在不同的高度上输出验证码的每个字符
  60. g.drawString("" + rands.charAt(0), 1, 17);
  61. g.drawString("" + rands.charAt(1), 16, 15);
  62. g.drawString("" + rands.charAt(2), 31, 18);
  63. g.drawString("" + rands.charAt(3), 46, 16);
  64. System.out.println(rands);
  65. }
  66. @Override
  67. public String execute() throws Exception
  68. {
  69. HttpServletResponse response = ServletActionContext.getResponse();
  70. // 设置浏览器不要缓存此图片
  71. response.setHeader("Pragma", "no-cache");
  72. response.setHeader("Cache-Control", "no-cache");
  73. response.setDateHeader("Expires", 0);
  74. String rands = createRandom();
  75. BufferedImage image = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
  76. Graphics g = image.getGraphics();
  77. // 产生图像
  78. drawBackground(g);
  79. drawRands(g, rands);
  80. // 结束图像 的绘制 过程, 完成图像
  81. g.dispose();
  82. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  83. ImageIO.write(image, "jpeg", outputStream);
  84. ByteArrayInputStream input = new ByteArrayInputStream(outputStream.toByteArray());
  85. this.setInputStream(input);
  86. HttpSession session = ServletActionContext.getRequest().getSession();
  87. session.setAttribute("checkCode", rands);
  88. input.close();
  89. outputStream.close();
  90. return SUCCESS;
  91. }
  92. }

2、在struts.xml中引用CreateImageAction,取别名为createImageAction:

  1. <action name="createImageAction" class="com.project.action.CreateImageAction">
  2. <result name="success" type="stream">
  3. <param name="contentType">image/jpeg</param>
  4. <param name="inputName">inputStream</param>
  5. </result>
  6. </action>

3、在login.html和register.html中,添加添加验证码的代码,调用createImageAction;

  1. <input type="text" name="checkCode" id="checkCode" class="txt_input" placeholder="Verification code" style="width:180px; margin-right:20px;" />
  2. <img src="createImageAction.action" />

4、在login.html和register.html中的<img/>中,添加onclick(),用来切换验证码:

  1. <!--若要点击图片刷新,重新得到一个验证码,要在后面加上个随机数,这样保证每次提交过去的都是不一样的path,防止因为缓存而使图片不刷新-->
  2. <img src="createImageAction.action" onclick="this.src='createImageAction.action?'+ Math.random()" title="点击图片刷新验证码"/>

5、login.html显示效果为:

6、register.html显示效果为:

0 条评论
发表评论…
0
蔡炎华

蔡炎华 public 上午

JAVA第十六周总结

完成项目 本次项目我做的是一个留言板的功能,里面记录了一个人日常所需事件,如同便利贴一个个贴在冰箱上一样,主要实现了增删查改登录注册功能,当你没登录时,点击其他的页面会自动进入登录页面进行登录,然后会自行跳到留言板界面,可以进行修改和删除。还有个页面可以进行添加。

0 条评论
发表评论…
0
郑展汉

郑展汉 public 昨天下午

PHP 第四周总结

本周于之前聊天室系统增加登录功能

首先新建一个用户模板类,代码如下

  1. <?php
  2. class User {
  3. private $id;
  4. private $account;
  5. private $passwd;
  6. private $name;
  7. public function getId() {
  8. return $this->id;
  9. }
  10. public function setId($id) {
  11. $this->id = $id;
  12. }
  13. public function getAccount() {
  14. return $this->account;
  15. }
  16. public function setAccount($account) {
  17. $this->account = $account;
  18. }
  19. public function getPasswd() {
  20. return $this->passwd;
  21. }
  22. public function setPasswd($passwd) {
  23. $this->passwd = $passwd;
  24. }
  25. public function getName() {
  26. return $this->name;
  27. }
  28. public function setName($name) {
  29. $this->name = $name;
  30. }
  31. }
  32. ?>

在UserDAO中创建一个类,通过帐号查询,需要用户输入用户名和密码才能查询,如果帐号存在的话就从User.php中将ID、ACCOUNT、NAME,获取出来,代码如下:

  1. <?php
  2. require_once(“BaseDAO.php”);
  3. require_once(“User.php”);
  4. class UserDAO extends BaseDAO {
  5. public function findByAccount($account, $passwd) {
  6. $stmt = $this->pdo->prepare(“select * from user where account=:account and passwd=:passwd”);
  7. $stmt->bindParam(‘:account’, $account);
  8. $stmt->bindParam(‘:passwd’, $passwd);
  9. $stmt->execute();
  10. $result = $stmt->fetch();
  11. if ($result["account"] != "") {
  12. $user = new User();
  13. $user->setId($result["id"]);
  14. $user->setAccount($result["account"]);
  15. $user->setName($result["name"]);
  16. return $user;
  17. } else {
  18. return new User();
  19. }
  20. }
  21. }
  22. ?>

在AuthAction.php这个验证的文件中,将用户输入的帐号和密码通过instanceof查询对象中是否有这个实例并且不为空才可以成功跳转其他页面,代码如下:

  1. <?php
  2. require_once("UserDAO.php");
  3. class AuthAction {
  4. public function AuthAction() {
  5. $userdao = new UserDAO();
  6. $user = $userdao->findByAccount($_POST["account"], $_POST["password"]);
  7. //print_r($user);
  8. if ($user instanceof User && $user->getAccount() != "") {
  9. $_SESSION["account"] = $user->getAccount();
  10. //echo "111111111111111111111111";
  11. header("Location:home.php");
  12. } else {
  13. header("Location:login.php");
  14. }
  15. }
  16. }
  17. ?>

0 条评论
发表评论…
0
郑展汉

郑展汉 public 昨天下午

PHP 第二周总结

本周学习如何制作一个简易的聊天室,主要功能有显示聊天信息,发布保存聊天信息,聊天信息保存在指定txt文件中。

首先建立index.php,用于取出聊天信息并输出,代码如下:

  1. <?php
  2. $count = 0;
  3. $msgs = file_get_contents("msg.txt");
  4. $handle = @fopen("msg.txt", "r");
  5. if ($handle) {
  6. while (($buffer = fgets($handle, 4096)) !== false) {
  7. $count++;
  8. }
  9. fclose($handle);
  10. }
  11. echo $count;
  12. $start = $count -9;
  13. $i=0;
  14. $handle=@fopen("msg.txt"."r");
  15. if($handle){
  16. while(($buffer=fgets($handle,4096))!==false){
  17. $i++;
  18. if($i>$start){
  19. //echo $buffer;
  20. ?>
  21. <li><?php echo $buffer; ?></li>
  22. <?php
  23. }
  24. }
  25. if (!feof($handle)) {
  26. echo "Error: unexpected fgets() fail\n";
  27. }
  28. fclose($handle);
  29. }
  30. ?>

用于发布聊天信息表单,代码如下:

  1. <form id="form" method="post" action="msgsava.php">
  2. <input type="text" name="msg" id="msg" />
  3. <input type="submit" name="button" id="button" value="发送" />
  4. </form>

表单将数据传入msgsava.php文件,该文件将数据保存到txt,代码如下:

  1. <?php
  2. file_put_contents("msg.txt",$_POST['msg']."\t\n",FILE_APPEND);
  3. header('Location:index.php');
  4. ?>

本周让我学习到如何将数据保存到txt文件中,并将其取出输出。

0 条评论
发表评论…
0
李美诗

李美诗 public 昨天下午

Web框架 第六周总结---发送消息和图片上传(2)

接着上一周的内容,我们为了让图片能够显示出来,我们把用json的方式来分解。
一、打开模型,建多一个字段,用来存和内容。

  1. //辅助的方法
  2. private Content msg;
  3. public Content getMsg() {
  4. try{
  5. msg=JSON.parseObject(content, Content.class);
  6. }catch(Exception e){
  7. }
  8. return msg;
  9. }
  10. public void setMsg(Content msg) {
  11. this.msg = msg;
  12. }

二、并新建一个一个模型里面是图片的字段。

  1. package com.demo.www.model;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class Content implements Serializable {
  6. private static final long serialVersionUID = -3584729479301729400L;//系统生成
  7. private String message;
  8. private List<String> images=new ArrayList<String>();
  9. public String getMessage() {
  10. return message;
  11. }
  12. public void setMessage(String message) {
  13. this.message = message;
  14. }
  15. public List<String> getImages() {
  16. return images;
  17. }
  18. public void setImages(List<String> images) {
  19. this.images = images;
  20. }
  21. }

三、在action文件,new一个class,用来调用dao的内容,和存放ip,命名为:MessageSaveAction,

  1. package com.demo.www.action;
  2. import java.io.File;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import org.apache.commons.io.FileUtils;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.apache.struts2.ServletActionContext;
  8. import com.alibaba.fastjson.JSON;
  9. import com.demo.www.dao.MessageDAO;
  10. import com.demo.www.model.Content;
  11. import com.demo.www.model.User;
  12. import com.opensymphony.xwork2.ActionContext;
  13. import com.opensymphony.xwork2.ActionSupport;
  14. public class MessageSaveAction extends ActionSupport {
  15. private String content;
  16. private List<File> upload;
  17. private List<String> uploadFileName;
  18. private List<String> uploadContentType;
  19. public String execute() throws Exception {
  20. MessageDAO messagedao=new MessageDAO();
  21. User user=(User)ActionContext.getContext().getSession().get("user");
  22. if(null!=user &&StringUtils.isNotBlank(user.getAccount())){
  23. String ip=getRemoteHost(ServletActionContext.getRequest());
  24. String savepath=ServletActionContext.getServletContext().getRealPath("/upload");//文件夹的地址 ,savepath路径
  25. System.out.println(savepath);//输出文件地址
  26. Content c=new Content();
  27. if(null!=upload && upload.size()>0){
  28. List<String> images=new ArrayList<String>();
  29. for(int i=0;i<upload.size();i++){
  30. File destfile=new File(new File(savepath),uploadFileName.get(i));//找到路径 文件名 目的地文件
  31. if(!destfile.getParentFile().exists()){//判断文件是否存在
  32. destfile.getParentFile().mkdirs();
  33. }
  34. FileUtils.copyFile(upload.get(i), destfile);//复制文件,文件夹的名字和文件名称
  35. //c.setImage("upload"+"/"+uploadFileName);//upload相对路径,不能用savepath
  36. images.add("upload/"+ uploadFileName.get(i));
  37. }
  38. c.setImages(images);
  39. }
  40. c.setMessage(content);
  41. String json=JSON.toJSONString(c);
  42. messagedao.save(user.getId(), json, ip);
  43. }else{
  44. return "login";
  45. }return SUCCESS;
  46. }
  47. //get set字段,因位置空间问题这里省略,但是要写上

通过网上的资料查询,我们得知了如何查询发送者的ip,如下:

  1. public String getRemoteHost(javax.servlet.http.HttpServletRequest request){
  2. String ip = request.getHeader("x-forwarded-for");
  3. if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
  4. ip = request.getHeader("Proxy-Client-IP");
  5. }
  6. if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
  7. ip = request.getHeader("WL-Proxy-Client-IP");
  8. }
  9. if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
  10. ip = request.getRemoteAddr();
  11. }
  12. return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
  13. }

四、打开strurs.xml文件,我们把保存并实现跳转的代码写上。

  1. <action name="message_save" class="com.demo.www.action.MessageSaveAction">
  2. <result name="success" type="redirect">/index.action</result>
  3. <result name="login" type="redirect">/login.action</result>
  4. </action>

五、为了在网页上,我们能够显示出来,我们要在index.html文件上写一段#foreach语句,这样网页上就能够循环显示了。

  1. <ul>
  2. #foreach($message in $list)<!--list 是从indexAction中取到的 -->
  3. <li>$!{message.msg.message}
  4. #foreach($img in $message.msg.images)<!-- $img是自行命名,in在哪里取到的 -->
  5. <img src="$!{img}" width="50" height="50" />
  6. #end
  7. </li>
  8. #end
  9. </ul>

以上就是消息和图片上传的总结了。

0 条评论
发表评论…
0
李美诗

李美诗 public 昨天下午

Web 框架 第十六周总结---项目总结

通过几周的制作,我终于完成了我的项目,现在由我一步步展示给大家看。
一、首先可以看到我的文件夹的分工是非常明确的。

打开action文件,我们可以看到按照功能的名称来命名的,非常明确,

打开模型和dao文件,也是很明确的分工

二、点击项目右键->run Server,就可以看到首页了 如图:

三、可以看到如果没有登录的话,那么我们的产品是不能修改和删除的。

四、点击登录字体,我们可以直接进入登录的界面,这样的用户体验是不错的。我们的登录界面还有验证码的功能呀。

五、登录成功之后,可以看见上面有用户的用户名。

六、我们要发布一个产品了,先进入发布的界面,把字段填完整。

可以看到我们刚刚填写的内容,成功的发布了。

七、点击修改按钮,可以看到我们通过id的方式得到这一个产品。

修改的内容:

八、点击保存,可以看到我们成功的修改了产品的信息

九、当我们要退出时,只需要点击退出这个按钮,我们就可以退出了,可以看到,产品的修改和删除的按钮消失了。

以上是我的项目总结,在后面的时间里,我会把我的项目再一次的重新整理,并修改。

0 条评论
发表评论…
0
李美诗

李美诗 public 前天下午

Web 框架 第十四周总结---产品的删除和退出

实现了产品的发布和产品的修改,当然要有产品的删除了,本周我完成了产品的删除功能和退出功能。
一、我们前面在网页上index文件已经把删除的超链接做好了,现在回顾一下:

  1. <a href="product_delete.action?id=$!{product.id}">删除</a>

可以看到我是按照产品的id来选择的,

二、打开ProductDAO,做一个删除的语句和查询ID的语句

查询ID

  1. public Product findById(Integer id){
  2. try {
  3. PreparedStatement pstm = null;
  4. pstm = conn.prepareStatement("select * from product where id=?");
  5. pstm.setInt(1, id);
  6. pstm.executeUpdate();
  7. ResultSet rs=pstm.executeQuery();
  8. if(rs.next()){
  9. Product product =new Product();
  10. product.setId(rs.getInt("id"));
  11. product.setName(rs.getString("name"));
  12. product.setContent(rs.getString("content"));
  13. product.setPrice(rs.getFloat("price"));
  14. product.setPic(rs.getString("pic"));
  15. return product;
  16. }
  17. } catch (SQLException e) {
  18. e.printStackTrace();// TODO
  19. }
  20. return null;
  21. }

根据ID,我们把选择的内容全部删除

  1. public void delete(Integer id){
  2. try {
  3. PreparedStatement pstm = null;
  4. pstm = conn.prepareStatement("delete from product where id=?");
  5. pstm.setInt(1, id);
  6. pstm.executeUpdate();
  7. } catch (SQLException e) {
  8. e.printStackTrace();// TODO
  9. }
  10. }

三、打开struts.xml文件,添加跳转语句。

  1. <action name="product_delete" class="com.demo.food.action.ProductDeleteAction">
  2. <result type="redirect" name="success">/index.action</result>
  3. </action>

四、有登录,那么就要有退出啦,我们现在首页上添加一个退出的超链接。

  1. <a href="logout.action"style="float:right; margin-right:10px;">退出</a>

五、在action文件夹,new一个class,命名为LogoutAction,所谓退出,就是从Session里移除它的用户。

  1. package com.demo.food.action;
  2. import com.opensymphony.xwork2.ActionContext;
  3. import com.opensymphony.xwork2.ActionSupport;
  4. public class LogoutAction extends ActionSupport {
  5. private static final long serialVersionUID = 1L;
  6. public String execute() throws Exception {
  7. ActionContext.getContext().getSession().remove("user");
  8. return SUCCESS;
  9. }
  10. }

0 条评论
发表评论…
0
李美诗

李美诗 public 前天下午

Web 框架 第十二周总结--产品的修改功能

上一周,我完成的是关于产品的发布功能,这一周我完成的是产品的修改功能,我要实现的是如果产品的如果图片没有修改,那么就是用原来的图,否则就更新。

一、我们要新建一个跟发布的页面类似,字段是一样的,只不过,我们要放图片的隐藏域和id的隐藏域。

  1. <form action="product_update.action" method="post" enctype="multipart/form-data" name="form1" id="form1">
  2. <p>产品名称:
  3. <input name="name" type="text" id="name" value="$!{product.name}" />
  4. </p>
  5. <p>图片:
  6. <img src="$!{product.pic}" width="100" height="100" />
  7. <input name="yldt" type="hidden" id="yldt" value="$!{product.pic}" />
  8. </p>
  9. <p>图片:
  10. <input type="file" name="upload" id="pic" />
  11. </p>
  12. <p>简介:
  13. <textarea name="content" id="content" cols="45" rows="5">$!{product.content}</textarea>
  14. </p>
  15. <p>价格:
  16. <input name="price" type="text" id="price" value="$!{product.price}" />
  17. </p>
  18. <p>
  19. <input type="submit" name="button" id="button" value="保存" />
  20. <input name="id" type="hidden" value="$!{product.id}" />
  21. </p>
  22. </form>

二、在ProductDAO里添加更新的语句。

  1. public void update(String name,String content,double price,String pic,Integer id){
  2. try {
  3. PreparedStatement pstm = null;//这个是sql语句的,所以不能共享
  4. pstm = conn.prepareStatement("update product set name=?,content=?,price=?,pic=? where id=?");
  5. pstm.setString(1, name);
  6. pstm.setString(2,content);
  7. pstm.setFloat(3, (float) price);
  8. pstm.setString(4,pic);
  9. pstm.setInt(5, id);
  10. pstm.executeUpdate();
  11. } catch (SQLException e) {
  12. e.printStackTrace();// TODO
  13. }
  14. }

三、在action文件夹,new一个class,命名为ProductEditAction,调用DAO的值。

  1. package com.demo.food.action;
  2. import com.demo.food.dao.ProductDAO;
  3. import com.demo.food.model.Product;
  4. import com.opensymphony.xwork2.ActionSupport;
  5. public class ProductEditAction extends ActionSupport {
  6. private Integer id;
  7. private Product product;
  8. public String execute() throws Exception{
  9. if(id>0){
  10. ProductDAO updatedao= new ProductDAO();
  11. product=updatedao.findById(id);
  12. }
  13. return SUCCESS;
  14. }
  15. public Integer getId() {
  16. return id;
  17. }
  18. //get set略
  19. }

四、打开ProductSaveAction文件,把语句做一个判断就可以判断内容是要保存还是更新。

  1. if(StringUtils.isNotBlank(name) && null!=content){
  2. ProductDAO dao= new ProductDAO();
  3. String pic="";//定义一个string pic类型
  4. if(null !=upload && upload.size()>0){
  5. String savepath=ServletActionContext.getServletContext().getRealPath("/upload");//文件夹的地址 ,savepath路径
  6. System.out.println(savepath);//输出文件地址
  7. File destfile=new File(new File(savepath),uploadFileName.get(0));//找到路径 文件名 目的地文件
  8. if(!destfile.getParentFile().exists()){//判断文件是否存在
  9. destfile.getParentFile().mkdirs();
  10. }
  11. FileUtils.copyFile(upload.get(0), destfile);//复制文件,文件夹的名字和文件名称
  12. pic="upload/"+ uploadFileName.get(0);
  13. }else{
  14. pic=yldt;
  15. }
  16. if(null !=id && id>0){//如果id不为空,且大于0,那么就更新
  17. dao.update(name, content, price, pic,id);
  18. }else{
  19. dao.save(name, content, price, pic);
  20. }
  21. }

五、打开struts.xml文件,用来显示修改界面和修改成功之后的跳转。

  1. <action name="product_edit" class="com.demo.food.action.ProductEditAction">
  2. <result type="velocity">/WEB-INF/html/product_edit.html</result><!--显示的界面-->
  3. </action>
  4. <action name="product_update" class="com.demo.food.action.ProductSaveAction">
  5. <result type="redirect" >/index.action</result><!--跳转并保存-->
  6. </action>

如图,我的页面就是这样的啦!

0 条评论
发表评论…
0
李美诗

李美诗 public 前天下午

Web 框架 第十周总结---实现登录功能

上一周,建好了项目,并找好了相关模版,这一周我开始做了登录的界面及相关的功能。
一、我们把找到的模版网页放进在src->main->webapp下,新建一个html文件夹,存放html文件,为了在运行中能够完整的显示出来,我们可以把css,images,js文件内容的文件夹放在html文件的外面。

二、新建几个文件夹,存放模型和存放action,数据库语句。

resources的struts.xml文件可以从前面的文件复制出来。

三、我们把找到的登录页面取名为login.html,并把该文件放在html文件下。

四、根据登录界面的需求,我们可以先建一个数据库,数据库的名字为food,表名为user

五、根据数据库,我们可以建立一个模型,里面存放这几个字段。在model模型文件夹内,新建一个User的类

  1. package com.demo.food.model;
  2. import java.io.Serializable;
  3. public class User implements Serializable {
  4. private static final long serialVersionUID = -8674879782766903776L;
  5. private Integer id;
  6. private String account;
  7. private String passwd;
  8. private String name;

然后在空白区域,右键一下,Source->Generate Getters and Setters,就可以选择需要的字段的get,set,就能自动生成。

六、在dao的文件中建一个AbstractBaseDAO文件,里面存放访问数据库的代码,这样我们在后面需要调用数据库就不用再 一次写数据库,只需调用即可。

  1. package com.demo.food.dao;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.SQLException;
  5. import org.apache.commons.lang3.StringUtils;
  6. //这是一个父类的代码
  7. //父类通常是抽象的,通常是不完整的
  8. //没有子类,父类无意义
  9. public abstract class AbstractBaseDAO {
  10. protected Connection conn=null;//现在任意一个方法都可以使用,conn这个类被共享
  11. //protected 这个是受保护的代码,其他的都是可以调用的
  12. public AbstractBaseDAO() {
  13. try {
  14. Class.forName("org.mariadb.jdbc.Driver");
  15. } catch(ClassNotFoundException e) {
  16. System.out.println("找不到驱动");
  17. }
  18. String url = "jdbc:mariadb://127.0.0.1:3306/food";
  19. String dbuser = "root";
  20. String dbpass = "123456";
  21. try {
  22. conn = DriverManager.getConnection(url, dbuser, dbpass);
  23. }catch (SQLException e) {
  24. e.printStackTrace();// TODO
  25. }
  26. }
  27. public void checkif(String account){
  28. if(!StringUtils.isNotBlank(account)){
  29. throw new RuntimeException("account is not null");
  30. }
  31. }
  32. }

七、在com.demo.food.action文件夹内新建一个class文件,命名为:AbstractBaseAction文件,

  1. package com.demo.food.action;
  2. import com.opensymphony.xwork2.ActionSupport;
  3. public class AbstractBaseAction extends ActionSupport {
  4. private static final long serialVersionUID = 1L;
  5. public String execute() throws Exception{
  6. return SUCCESS;
  7. }
  8. }

八、在action文件夹内,新建一个class,命名为LoginAction
,用来显示网页的代码

  1. package com.demo.food.action;
  2. import com.opensymphony.xwork2.ActionSupport;
  3. public class LoginAction extends ActionSupport {
  4. public String execute() throws Exception {
  5. return SUCCESS;
  6. }
  7. }

九、在dao文件夹内,新建一个UserDAO文件,存放SQL语句,用来查询用户的。

  1. package com.demo.food.dao;
  2. import java.sql.PreparedStatement;
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import org.apache.commons.lang3.StringUtils;
  6. import com.demo.food.model.User;
  7. public class UserDAO extends AbstractBaseDAO{//引用AbstractBaseDAO文件
  8. public User findByAccount(String account,String passwd){
  9. try {
  10. PreparedStatement pstm = null;
  11. pstm = conn.prepareStatement("select * from user where account=? and passwd=?");
  12. pstm.setString(1, account);
  13. pstm.setString(2, passwd);
  14. ResultSet rs=pstm.executeQuery();
  15. if(rs.next()){//指到下一行
  16. User user=new User();
  17. user.setId(rs.getInt("id"));
  18. user.setAccount(rs.getString("account"));
  19. user.setName(rs.getString("name"));
  20. return user;
  21. }
  22. } catch (SQLException e) {
  23. e.printStackTrace();// TODO
  24. }
  25. return null;
  26. }

十、在struts.xml文件内写上下面的代码。显示网页并实现跳转。

  1. <action name="login" class="com.demo.food.action.LoginAction">
  2. <result type="velocity">/WEB-INF/html/login.html</result><!-- 显示登录页面 -->
  3. </action>
  4. <action name="auth" class="com.demo.food.action.AuthAction">
  5. <result type="redirect">/index.action</result><!--跳转到首页-->
  6. </action>

并在登录页面login.html中的表单,加一个跳转的路径。

  1. <form id="form1" action="auth.action" method="post">

十一、在action文件建一个AuthAction文件,用于显示用户的姓名。

  1. package com.demo.food.action;
  2. import org.apache.commons.lang3.StringUtils;
  3. import com.demo.food.dao.UserDAO;
  4. import com.demo.food.model.User;
  5. import com.opensymphony.xwork2.ActionContext;
  6. import com.opensymphony.xwork2.ActionSupport;
  7. public class AuthAction extends ActionSupport {
  8. private String account;
  9. private String passwd;
  10. public String execute() throws Exception {
  11. UserDAO userdao=new UserDAO();
  12. User user=userdao.findByAccount(account, passwd);
  13. if(null!=user && StringUtils.isNotBlank(user.getAccount())){
  14. ActionContext.getContext().getSession().put("user", user);
  15. }
  16. return SUCCESS;
  17. }
  18. public String getAccount() {
  19. return account;
  20. }
  21. public void setAccount(String account) {
  22. this.account = account;
  23. }
  24. public String getPasswd() {
  25. return passwd;
  26. }
  27. public void setPasswd(String passwd) {
  28. this.passwd = passwd;
  29. }
  30. }

以上就是关于登录的总结。

0 条评论
发表评论…
0
周文彪

周文彪 public 2016-06-24

第十二周学习总结

树莓派夜视监控器

项目材料

  1. Raspberry Pi 3 4核 1G内存 学习套件

  2. 红外夜视摄像头可调焦RPi

  3. 夜视摄像头专用感光红外灯

  4. 摄像头 支架

树莓派烧录

  1. 一开始,树莓派烧录raspbian镜像包失败,一直停留在彩色屏幕画面上。

  2. 解决的方法是我们下载的镜像包太旧,下载了最新raspbian镜像包,完美烧录进去

本地开启摄像头

  1. 开启树莓排摄像头设置

  2. Sudo raspi-config

  3. 设置完成后,自动重启

  4. 在命令台输入raspivid –o video.h264 –t 10000

  5. 即可显示画面

局域网连接

我们用的摄像头为CSI摄像头,
网上大多数监控的教程都是针对USB摄像头,就连motion这些软件也不支持树莓派的摄像头。我们参阅无数教程后,使用MJPG-Streamer方法,成功配置出丝滑般流畅的监控 。

步骤为:
1.安装辅助工具
在树莓派上执行:
sudo apt-get install libjpeg8-dev
sudo apt-get install cmake

2.解压master,zip
在树莓派上执行:
unzip master.zip

3.编辑源文件
在树莓派上执行:
cd mjpg-streamer-master/mjpg-streamer-experimental/plugins/input_raspicam
修改FPS为30帧,width为320,heigh为240,保存即可。

4.编译mjpg软件
在树莓派上执行:
cd ../
cd ../
make clean all

5.制作mjpg的启动脚本
在树莓派上执行:
cd nano jk.sh
将下面两条命令复制进去
cd mjpg-streamer-master/mjpg-streamer-experimental
./mjpg_streamer -i “./input_raspicam.so” -o “./output_http.so -w ./www”

6.保存后,在树莓派上执行:
chmod 744 jk.sh
.执行mjpg的启动脚本(启动mjpg)
在树莓派上执行:
sh jk.sh

7.最后,在浏览器上打开: http://树莓派的ip:8080:

通过WIFI连接,手机端也可连接摄像头

最终要实现效果
一个有实际使用价值的树莓派监控系统。使用MJPG-Streamer抓图软件控制摄像头每隔1-2分钟拍摄一张照片,通过花生壳网站获得一个固定IP,再将图片上传至yeelink平台或者使用motion软件将图片拼接成视频,由于配有两个感光红外led灯,在弱光情况下仍能工作。网络状况良好的情况下能实现7*24小时的实时监控并存储监控画面。

0 条评论
发表评论…
0
何康勇

何康勇 public 2016-06-24

每周笔记

这星期我没有怎么学习前端的知识,但是我现在是在对ps的的学习,所以我这个星期我就做了一个ps的效果图,这个模版是我在网上找到的

0 条评论
发表评论…
0
杨子威

杨子威 public 2016-06-24

第十六周笔记

这周第十六周了,这周做了一个仿国外风格的,摄影网页,整体上不难,但在一些细节上一点困难,特别是那个小倒三角,定位比较困难,醉倒最后也没有把它准确的居中。居中标签不能把它居中,因为时间原因也就没多去调整了。

0 条评论
发表评论…
0
何镔

何镔 public 2016-06-24

第十五周学习笔记

有次因为要做物流网站,原本的水果网站只好作罢,但是现在有空了,所以我就把水果网站给补了回来,这周先设计出设计图,下周再开始做网站。

0 条评论
发表评论…
0
黄俊锋

黄俊锋 public 2016-06-24

Android:静默安装实现方案,仿360手机助手秒装

所谓的秒装其实就是需要ROOT权限的静默安装,其实静默安装的原理很简单,就是调用Android系统的pm install命令就可以了,但关键的问题就在于,pm命令系统是不授予我们权限调用的,因此只能在拥有ROOT权限的手机上去申请权限才行。
下面我们开始动手,新建一个InstallTest项目,然后创建一个SilentInstall类作为静默安装功能的实现类,代码如下所示:

  1. /**
  2. * 静默安装的实现类,调用install()方法执行具体的静默安装逻辑。
  3. * 原文地址:http://blog.csdn.net/guolin_blog/article/details/47803149
  4. * @author guolin
  5. * @since 2015/12/7
  6. */
  7. public class SilentInstall {
  8. /**
  9. * 执行具体的静默安装逻辑,需要手机ROOT。
  10. * @param apkPath
  11. * 要安装的apk文件的路径
  12. * @return 安装成功返回true,安装失败返回false。
  13. */
  14. public boolean install(String apkPath) {
  15. boolean result = false;
  16. DataOutputStream dataOutputStream = null;
  17. BufferedReader errorStream = null;
  18. try {
  19. // 申请su权限
  20. Process process = Runtime.getRuntime().exec("su");
  21. dataOutputStream = new DataOutputStream(process.getOutputStream());
  22. // 执行pm install命令
  23. String command = "pm install -r " + apkPath + "\n";
  24. dataOutputStream.write(command.getBytes(Charset.forName("utf-8")));
  25. dataOutputStream.flush();
  26. dataOutputStream.writeBytes("exit\n");
  27. dataOutputStream.flush();
  28. process.waitFor();
  29. errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
  30. String msg = "";
  31. String line;
  32. // 读取命令的执行结果
  33. while ((line = errorStream.readLine()) != null) {
  34. msg += line;
  35. }
  36. Log.d("TAG", "install msg is " + msg);
  37. // 如果执行结果中包含Failure字样就认为是安装失败,否则就认为安装成功
  38. if (!msg.contains("Failure")) {
  39. result = true;
  40. }
  41. } catch (Exception e) {
  42. Log.e("TAG", e.getMessage(), e);
  43. } finally {
  44. try {
  45. if (dataOutputStream != null) {
  46. dataOutputStream.close();
  47. }
  48. if (errorStream != null) {
  49. errorStream.close();
  50. }
  51. } catch (IOException e) {
  52. Log.e("TAG", e.getMessage(), e);
  53. }
  54. }
  55. return result;
  56. }
  57. }

可以看到,SilentInstall类中只有一个install()方法,所有静默安装的逻辑都在这个方法中了,那么我们具体来看一下这个方法。首先在第21行调用了Runtime.getRuntime().exec(“su”)方法,在这里先申请ROOT权限,不然的话后面的操作都将失败。然后在第24行开始组装静默安装命令,命令的格式就是pm install -r <apk路径>,-r参数表示如果要安装的apk已经存在了就覆盖安装的意思,apk路径是作为方法参数传入的。接下来的几行就是执行上述命令的过程,注意安装这个过程是同步的,因此我们在下面调用了process.waitFor()方法,即安装要多久,我们就要在这里等多久。等待结束之后说明安装过程结束了,接下来我们要去读取安装的结果并进行解析,解析的逻辑也很简单,如果安装结果中包含Failure字样就说明安装失败,反之则说明安装成功。
整个方法还是非常简单易懂的,下面我们就来搭建调用这个方法的环境。修改activity_main.xml中的代码,如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. android:paddingBottom="@dimen/activity_vertical_margin"
  8. android:paddingLeft="@dimen/activity_horizontal_margin"
  9. android:paddingRight="@dimen/activity_horizontal_margin"
  10. android:paddingTop="@dimen/activity_vertical_margin"
  11. tools:context="com.example.installtest.MainActivity">
  12. <LinearLayout
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content">
  15. <Button
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:onClick="onChooseApkFile"
  19. android:text="选择安装包" />
  20. <TextView
  21. android:id="@+id/apkPathText"
  22. android:layout_width="0dp"
  23. android:layout_height="wrap_content"
  24. android:layout_weight="1"
  25. android:layout_gravity="center_vertical"
  26. />
  27. </LinearLayout>
  28. <View
  29. android:layout_width="match_parent"
  30. android:layout_height="1dp"
  31. android:background="@android:color/darker_gray" />
  32. <Button
  33. android:layout_width="wrap_content"
  34. android:layout_height="wrap_content"
  35. android:onClick="onSilentInstall"
  36. android:text="秒装" />
  37. <View
  38. android:layout_width="match_parent"
  39. android:layout_height="1dp"
  40. android:background="@android:color/darker_gray" />
  41. <Button
  42. android:layout_width="wrap_content"
  43. android:layout_height="wrap_content"
  44. android:onClick="onForwardToAccessibility"
  45. android:text="开启智能安装服务" />
  46. <Button
  47. android:layout_width="wrap_content"
  48. android:layout_height="wrap_content"
  49. android:onClick="onSmartInstall"
  50. android:text="智能安装" />
  51. </LinearLayout>

这里我们先将程序的主界面确定好,主界面上拥有四个按钮,第一个按钮用于选择apk文件的,第二个按钮用于开始秒装,第三个按钮用于开启智能安装服务,第四个按钮用于开始智能安装,这里我们暂时只能用到前两个按钮。那么调用SilentInstall的install()方法需要传入apk路径,因此我们需要先把文件选择器的功能实现好,新建activity_file_explorer.xml和list_item.xml作为文件选择器的布局文件,代码分别如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent">
  6. <ListView
  7. android:id="@+id/list_view"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. />
  11. </LinearLayout>
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content"
  6. android:padding="4dp"
  7. android:orientation="horizontal">
  8. <ImageView android:id="@+id/img"
  9. android:layout_width="32dp"
  10. android:layout_margin="4dp"
  11. android:layout_gravity="center_vertical"
  12. android:layout_height="32dp"/>
  13. <TextView android:id="@+id/name"
  14. android:textSize="18sp"
  15. android:textStyle="bold"
  16. android:layout_width="match_parent"
  17. android:gravity="center_vertical"
  18. android:layout_height="50dp"/>
  19. </LinearLayout>

然后新建FileExplorerActivity作为文件选择器的Activity,代码如下:

  1. public class FileExplorerActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
  2. ListView listView;
  3. SimpleAdapter adapter;
  4. String rootPath = Environment.getExternalStorageDirectory().getPath();
  5. String currentPath = rootPath;
  6. List<Map<String, Object>> list = new ArrayList<>();
  7. @Override
  8. public void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_file_explorer);
  11. listView = (ListView) findViewById(R.id.list_view);
  12. adapter = new SimpleAdapter(this, list, R.layout.list_item,
  13. new String[]{"name", "img"}, new int[]{R.id.name, R.id.img});
  14. listView.setAdapter(adapter);
  15. listView.setOnItemClickListener(this);
  16. refreshListItems(currentPath);
  17. }
  18. private void refreshListItems(String path) {
  19. setTitle(path);
  20. File[] files = new File(path).listFiles();
  21. list.clear();
  22. if (files != null) {
  23. for (File file : files) {
  24. Map<String, Object> map = new HashMap<>();
  25. if (file.isDirectory()) {
  26. map.put("img", R.drawable.directory);
  27. } else {
  28. map.put("img", R.drawable.file_doc);
  29. }
  30. map.put("name", file.getName());
  31. map.put("currentPath", file.getPath());
  32. list.add(map);
  33. }
  34. }
  35. adapter.notifyDataSetChanged();
  36. }
  37. @Override
  38. public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
  39. currentPath = (String) list.get(position).get("currentPath");
  40. File file = new File(currentPath);
  41. if (file.isDirectory())
  42. refreshListItems(currentPath);
  43. else {
  44. Intent intent = new Intent();
  45. intent.putExtra("apk_path", file.getPath());
  46. setResult(RESULT_OK, intent);
  47. finish();
  48. }
  49. }
  50. @Override
  51. public void onBackPressed() {
  52. if (rootPath.equals(currentPath)) {
  53. super.onBackPressed();
  54. } else {
  55. File file = new File(currentPath);
  56. currentPath = file.getParentFile().getPath();
  57. refreshListItems(currentPath);
  58. }
  59. }
  60. }

这部分代码由于和我们本篇文件的主旨没什么关系,主要是为了方便demo展示的,因此我就不进行讲解了。
接下来修改MainActivity中的代码,如下所示:

  1. /**
  2. * 仿360手机助手秒装和智能安装功能的主Activity。
  3. * 原文地址:http://blog.csdn.net/guolin_blog/article/details/47803149
  4. * @author guolin
  5. * @since 2015/12/7
  6. */
  7. public class MainActivity extends AppCompatActivity {
  8. TextView apkPathText;
  9. String apkPath;
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_main);
  14. apkPathText = (TextView) findViewById(R.id.apkPathText);
  15. }
  16. @Override
  17. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  18. if (requestCode == 0 && resultCode == RESULT_OK) {
  19. apkPath = data.getStringExtra("apk_path");
  20. apkPathText.setText(apkPath);
  21. }
  22. }
  23. public void onChooseApkFile(View view) {
  24. Intent intent = new Intent(this, FileExplorerActivity.class);
  25. startActivityForResult(intent, 0);
  26. }
  27. public void onSilentInstall(View view) {
  28. if (!isRoot()) {
  29. Toast.makeText(this, "没有ROOT权限,不能使用秒装", Toast.LENGTH_SHORT).show();
  30. return;
  31. }
  32. if (TextUtils.isEmpty(apkPath)) {
  33. Toast.makeText(this, "请选择安装包!", Toast.LENGTH_SHORT).show();
  34. return;
  35. }
  36. final Button button = (Button) view;
  37. button.setText("安装中");
  38. new Thread(new Runnable() {
  39. @Override
  40. public void run() {
  41. SilentInstall installHelper = new SilentInstall();
  42. final boolean result = installHelper.install(apkPath);
  43. runOnUiThread(new Runnable() {
  44. @Override
  45. public void run() {
  46. if (result) {
  47. Toast.makeText(MainActivity.this, "安装成功!", Toast.LENGTH_SHORT).show();
  48. } else {
  49. Toast.makeText(MainActivity.this, "安装失败!", Toast.LENGTH_SHORT).show();
  50. }
  51. button.setText("秒装");
  52. }
  53. });
  54. }
  55. }).start();
  56. }
  57. public void onForwardToAccessibility(View view) {
  58. }
  59. public void onSmartInstall(View view) {
  60. }
  61. /**
  62. * 判断手机是否拥有Root权限。
  63. * @return 有root权限返回true,否则返回false。
  64. */
  65. public boolean isRoot() {
  66. boolean bool = false;
  67. try {
  68. bool = new File("/system/bin/su").exists() || new File("/system/xbin/su").exists();
  69. } catch (Exception e) {
  70. e.printStackTrace();
  71. }
  72. return bool;
  73. }
  74. }

可以看到,在MainActivity中,我们对四个按钮点击事件的回调方法都进行了定义,当点击选择安装包按钮时就会调用onChooseApkFile()方法,当点击秒装按钮时就会调用onSilentInstall()方法。在onChooseApkFile()方法方法中,我们通过Intent打开了FileExplorerActivity,然后在onActivityResult()方法当中读取选择的apk文件路径。在onSilentInstall()方法当中,先判断设备是否ROOT,如果没有ROOT就直接return,然后判断安装包是否已选择,如果没有也直接return。接下来我们开启了一个线程来调用SilentInstall.install()方法,因为安装过程会比较耗时,如果不开线程的话主线程就会被卡住,不管安装成功还是失败,最后都会使用Toast来进行提示。
代码就这么多,最后我们来配置一下AndroidManifest.xml文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.installtest">
  4. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  5. <application
  6. android:allowBackup="true"
  7. android:icon="@mipmap/ic_launcher"
  8. android:label="@string/app_name"
  9. android:supportsRtl="true"
  10. android:theme="@style/AppTheme">
  11. <activity android:name=".MainActivity">
  12. <intent-filter>
  13. <action android:name="android.intent.action.MAIN" />
  14. <category android:name="android.intent.category.LAUNCHER" />
  15. </intent-filter>
  16. </activity>
  17. <activity android:name=".FileExplorerActivity"/>
  18. </application>
  19. </manifest>

并没有什么特殊的地方,由于选择apk文件需要读取SD卡,因此在AndroidManifest.xml文件中要记得声明读SD卡权限。
另外还有一点需要注意,在Android 6.0系统中,读写SD卡权限被列为了危险权限,因此如果将程序的targetSdkVersion指定成了23则需要做专门的6.0适配,这里简单起见,我把targetSdkVersion指定成了22,因为6.0的适配工作也不在文章的讲解范围之内。
现在运行程序,就可以来试一试秒装功能了,切记手机一定要ROOT,效果如下图所示:

可以看到,这里我们选择的网易新闻安装包已成功安装到手机上了,并且没有弹出系统的安装界面,由此证明秒装功能已经成功实现了。

0 条评论
发表评论…
0
赵少锋

赵少锋 public 2016-06-24

创客作品: 障碍规避机器人

制作流程

1、制作机器人的身体

选择舵机零件包中提供的螺丝,然后按照凹口进行组装。需要注意的是要确保舵机的朝向正确,不然当机器人走动时可能会松动脱落。

2、制作机器人的脚

铁丝有点硬,要用钳子将铁丝折弯,前后脚都折成V字形,中间的脚折成U形。注意的是V形的腿中间部分要折一下,防止舵机运动时腿被卡住。

3、给脚装上胶帽

这样就可以保证腿不会打滑,也不会刮花家居。

4、安装眼睛

眼睛是一个传感器,用扎带固定就好了

5、固定主控器

控制器用双面胶粘到机器人的身体上

6、电路连接

插槽上面标有编号:
红外传感器 - A1
右光敏传感器 - A0
左光敏传感器 - A2
前腿 - D9 中腿 - D11 后退 - D10
电池盒红色线接正极 黑色线接负极

7、调试机器人的脚

装完电池后启动开关,会发现机器人的脚拐的很严重,电源开启后停1秒半,机器人的脚会初始化,那个时候马达是对准了的,就可以把脚重新装一下。

0 条评论
发表评论…
0
赵少锋

赵少锋 public 2016-06-24

让360浏览器优先使用极速模式渲染网站

我开发过一些网站,大量采用了html5和css3,希望用户都以webkit内核打开页面,但是测试却发现360的以ie内核打开为推荐模式,不知原因为何。其实360给网站开发者设计了一种选择的方法,只要加入一段Meta标签代码就可以解决。

以下信息摘自360官方网站:http://se.360.cn/v6/help/meta.html

浏览模式

极速模式、兼容模式及IE9高速模式是360浏览器显示网页时使用的三种模式:

极速模式表示极速模式

兼容模式表示兼容模式

IE9IE10模式表示IE9/IE10模式(仅在安装了IE9或IE10后可用)

360极速浏览器会自动为您选择使用适合每个网站的浏览模式。所以,通常您不用了解几种内核的区别。

几种模式各有什么特点

极速模式下,网站打开速度快,但某些网站在极速模式下可能出现兼容性问题,显示不正常。
兼容模式下,网站打开速度比极速模式略低,但网页兼容性问题较少。
IE9/IE10模式下,网站会使用IE9/IE10的渲染方式渲染,支持硬件加速及IE9/IE10全新的脚本渲染引擎。

切换浏览模式时,360极速浏览器将会自动同步双核间的数据,让您在双核间能无缝切换。

用户体验计划

在您加入用户体验计划的情况下,我们会将切换的网址发送到360网站,以便我们完善兼容列表库,改进产品。

上传的数据不包含具有您个体特征的信息,且不会泄漏给第三方个人或机构。

若不希望上传切换的网址,您只需在“高级选项”里去掉勾选
“ 将使用情况统计信息和崩溃报告自动发送给360极速浏览器网站,帮助我们完善360极速浏览器”即可。

背景介绍

由于众所周知的情况,国内的主流浏览器都是双核浏览器:基于Webkit内核用于常用网站的高速浏览。基于IE的内核用于兼容网银、旧版网站。以360的几款浏览器为例,我们优先通过Webkit内核渲染主流的网站,只有小量的网站通过IE内核渲染,以保证页面兼容。在过去很长一段时间里,我们主要的控制手段是一个几百k大小网址库,一个通过长期人工运营收集的网址库。

尽管我们努力通过用户反馈、代码标签智能判断技术提高浏览器的自动切核准确率。但是在很多情况下,我们仍然无法达到百份百正确。因此,我们新增加了一个控制手段:内核控制Meta标签。只要你在自己的网站里增加一个Meta标签,告诉360浏览器这个网址应该用哪个内核渲染,哪么360浏览器就会在读取到这个标签后,立即切换对应的内核。并将这个行为应用于这个二级域名下所有网址。
目前该功能已经在所有的360安全浏览器实现。我们也建议其它浏览器厂商一起支持这个实现。让这个控制标签成为行业标准。

代码示例

在head标签中添加一行代码:

<html>

<head>

<meta name="renderer" content="webkit|ie-comp|ie-stand">
</head>

<body>
</body>
</html>
content的取值为webkit,ie-comp,ie-stand之一,区分大小写,分别代表用webkit内核,IE兼容内核,IE标准内核。
若页面需默认用极速核,增加标签:<meta name="renderer" content="webkit">
若页面需默认用ie兼容内核,增加标签:<meta name="renderer" content="ie-comp">
若页面需默认用ie标准内核,增加标签:<meta name="renderer" content="ie-stand">

注意:引号要英文状态下的,直接复制代码后看一下格式对不对,请自行更正。
各渲染内核的技术细节

内核 Webkit IE兼容 IE标准
文档模式 Chrome 21 IE6/7 IE9/IE10/IE11(取决于用户的IE)
HTML5支持 YES NO YES
ActiveX控件支持 NO YES YES

备注

这个功能其实和IE9的X-UA-Compatible很类似,关于IE几个内核的实现介绍,请看:
http://blogs.msdn.com/b/ie/archive/2010/06/16/ie-s-compatibility-features-for-site-developers.aspx

了解极速模式和兼容模式使用的技术:
极速模式使用的是Webkit内核,Webkit内核是全球最快速的浏览器内核,同时支持了诸多的网页新标准,
但由于Webkit内核较新,国内一些网站尚未较好地支持此内核。
兼容模式使用的是IE浏览器所使用的 Trident 内核,是国内网页制作时主要兼容的浏览器内核,兼容性问题较少。
IE9/IE10模式使用的是IE9/IE10浏览器所使用的新内核,加入了硬件加速、全新的脚本渲染引擎,更标准的HMTL5及CSS3支持。

综合多篇文章在页面里加入如下代码切换为极速模式:

<meta charset="utf-8" />

<meta name="renderer" content="webkit">

<meta http-equiv="X-UA-Compatible" content="IE=8,9,10">

0 条评论
发表评论…
0
刘才源

刘才源 public 上午

PHP项目总结

一、项目名称 留言功能开发 二、开发工具 Dreamweaver,数据库 三、开发语言 php、html、sql 四、项目的基本情况 这个项目是从网站上下载一个html的模版,然后我找到这个模版的留言,打算做一个留言的功能,这个项目的功能有 增删查改,还有一个登录的界面。 用户在访问这个网站的时候,首先他如果想要留言,就必须登录,(做了一个拦截器)用户登录成功后,就可以进行操作,如果他对你这个游戏有兴趣,他就会留言,他发表之后就会在留言的页面显示,如果他想删除,也可以直接的删除,修改的话,也是直接在留言的页面上直接修改。 五、不足之处 现在做的这个项目存在了很多的小问题,例如做的这些功能太低级了,都是一些上课内容,没有一点自己的东西,当然自己本身也存在问题,对这个项目的不够重视,没有花太多时间去做这个项目,对php这方面的知识缺少,导致在做项目的时候就会懵逼,也缺少对框架的认识。 六、心得体会 老师让我们做这个项目,是让我们知道,以前的那种旧的php思想要抛弃掉,要用新的php框架开发,让这种开发形式更加的安全,程序员自己也更加的清楚。 当初老师一开始让我做这个项目的时候,我是拒绝的,因为平时上课的时候老师讲的时候就有点听不懂,现在要自己做,不知道如何下手,老师说按照上课的那个模版来做就可以了,很多东西都可以参照到,然后自己就开始一点一点的去做这个项目,不会的就去问同学,同学不会就去问老师,到现在项目已经完成,虽然完成的不太好,自己也有颇多的收获,希望以后对php更深入的了解

0 条评论
发表评论…
0
金绮琳

金绮琳 public 上午

JAVA第十三周

JAVA第十三周

一、删除功能

1.创建FruitDeleteAction.java文件,并添加代码:

  1. package com.demo.action;
  2. import com.opensymphony.xwork2.ActionSupport;
  3. import com.demo.dao.FruitDAO;
  4. import com.demo.model.Fruit;
  5. import com.demo.model.User;
  6. public class FruitDeleteAction extends ActionSupport {
  7. private Integer id;
  8. public String execute() throws Exception {
  9. if (id> 0) {
  10. FruitDAO fruitdao = new FruitDAO();
  11. fruitdao.delete(id);
  12. }
  13. return SUCCESS;
  14. }
  15. public Integer getId() {
  16. return id;
  17. }
  18. public void setId(Integer id) {
  19. this.id = id;
  20. }
  21. }

↑在其中是根据id来进行删除的

2.在FruitDAO.java文件中添加删除的代码:

  1. public void delete(Integer id) {
  2. try {
  3. PreparedStatement pstm = null;
  4. pstm = conn.prepareStatement("delete from fruit where id=?");
  5. pstm.setInt(1, id);
  6. pstm.executeUpdate();
  7. } catch (SQLException e) {
  8. e.printStackTrace();// TODO 锟斤拷志
  9. }
  10. }
  11. }

↑也是根据id进行删除

3.返回首页上去添加一个删除的按钮:

  1. <a href="fruit_delete.action?id=$!{fruit.id}" style="width:100px;height:25px;background-color:#F55353;color:white;margin:5px;line-height:25px;margin-left:2px;text-align:center;margin-top:5px;font-size:20px;";>删除</a>

界面显示为:

0 条评论
发表评论…
0
许桂华

许桂华 public 上午

java第十二周课上笔记

操作流程

一、调试

二、配置文件

  1. <action name="configs" class="com.demo.www.action.ConfigsAction">
  2. <result type="velocity">/WEB-INF/html/configs.html</result>
  3. </action>
  4. <action name="configs_save" class="com.demo.www.action.ConfigsSaveAction">
  5. <result type="redirect">/configs.action</result>
  6. </action>

三、创建文件
1、创建ConfigsAction

  1. package com.demo.www.action;
  2. import java.util.List;
  3. import com.demo.www.dao.ConfigDAO;
  4. import com.demo.www.model.Config;
  5. import com.demo.www.model.User;
  6. import com.demo.www.util.ConfigDef;
  7. import com.demo.www.util.ConfigUtil;
  8. import com.opensymphony.xwork2.ActionContext;
  9. import com.opensymphony.xwork2.ActionSupport;
  10. public class ConfigsAction extends ActionSupport {
  11. private ConfigUtil configutil = new ConfigUtil();
  12. public String execute() throws Exception {
  13. User user = (User)ActionContext.getContext().getSession().get("user");
  14. ConfigDAO configdao = new ConfigDAO();
  15. List<Config> list = configdao.findByUser(user.getId());
  16. configutil.setList(list);
  17. List<Config> deflist = ConfigDef.list;
  18. deflist.removeAll(list); //删除再添加
  19. deflist.addAll(list); //删除再添加
  20. return SUCCESS;
  21. }
  22. public ConfigUtil getConfigutil() {
  23. return configutil;
  24. }
  25. public void setConfigutil(ConfigUtil configutil) {
  26. this.configutil = configutil;
  27. }

2、创建ConfigsSaveAction

  1. package com.demo.config.action;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import com.demo.config.model.Config;
  5. import com.opensymphony.xwork2.ActionSupport;
  6. public class ConfigsSaveAction extends ActionSupport {
  7. private List<Config> properties = new ArrayList<Config>();
  8. public String execute() throws Exception{
  9. System.out.println(1);
  10. return SUCCESS;
  11. }
  12. public List<Config> getProperties() {
  13. return properties;
  14. }
  15. public void setProperties(List<Config> properties) {
  16. this.properties = properties;
  17. }
  18. }

3、创建数据库

4、创建Config


Ctrl+Shift+O快速引入包,选第一个。

5、数组下标


四、怎样把多个值通过对象表单传过来?

  1. package com.demo.www.dao;
  2. import java.sql.PreparedStatement;
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import com.demo.www.model.Config;
  8. public class ConfigDAO extends AbstractBaseDAO {
  9. public void save(String property, String value, Integer user) {
  10. try {
  11. PreparedStatement pstm = null;
  12. pstm = conn.prepareStatement("insert into config(property,value,user) values(?,?,?)");
  13. pstm.setString(1, property);
  14. pstm.setString(2, value);
  15. pstm.setInt(3, user);
  16. pstm.executeUpdate();
  17. } catch (SQLException e) {
  18. e.printStackTrace();// TODO 日志
  19. }
  20. }
  21. public void update(String property, String value, Integer user) {
  22. try {
  23. PreparedStatement pstm = null;
  24. pstm = conn.prepareStatement("update config set value=? where property=? and user=?");
  25. pstm.setString(1, value);
  26. pstm.setString(2, property);
  27. pstm.setInt(3, user);
  28. pstm.executeUpdate();
  29. } catch (SQLException e) {
  30. e.printStackTrace();// TODO 日志
  31. }
  32. }
  33. public List<Config> findByUser( Integer user) {
  34. List<Config> configs = new ArrayList<Config>();
  35. try {
  36. PreparedStatement pstm = null;
  37. pstm = conn.prepareStatement("select * from config where user=?");
  38. pstm.setInt(1, user);
  39. ResultSet rs = pstm.executeQuery();
  40. while (rs.next()) {
  41. Config config = new Config();
  42. config.setId(rs.getInt("id"));
  43. config.setProperty(rs.getString("property"));
  44. config.setValue(rs.getString("value"));
  45. config.setUser(rs.getInt("user"));
  46. configs.add(config);
  47. }
  48. } catch (SQLException e) {
  49. e.printStackTrace();// TODO 日志
  50. }
  51. return null;
  52. }
  53. }

0 条评论
发表评论…
0
蔡炎华

蔡炎华 public 上午

JAVA总结

本次项目我做的是一个留言板的功能,里面记录了一个人日常所需事件,当用户打开电脑时,桌面会显示留言板的内容。主要实现了增删查改登录注册功能,当你没登录时,点击其他的页面会自动进入登录页面进行登录,然后会自行跳到留言板界面,可以进行修改和删除。还有添加页面可以进行添加留言。

0 条评论
发表评论…
0
郑展汉

郑展汉 public 上午

JAVA 第一周总结

本周学习如何用elicpse创建一个项目,并正常运行

创建一个项目,将八个jar包导入到webcontent—web-info—lib里面,修改web.xml文件,进入到网页,从网页上复制代码到web.xml里面,代码如下:

  1. struts2
  2. org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  3. struts2
  4. /*

在WEB-INF里新建一个tools.xml文件

  1. tiles
  2. request
  3. org.apache.velocity.tools.struts.TilesTool

建立action类 建立一个包 package

建立前台JSP页面,

添加struts.Xml文件并且对其进行配置

0 条评论
发表评论…
0
蔡炎华

蔡炎华 public 上午

JAVA第十五周

继续完善项目
本周实现删除用户信息的功能
1、 继续使用index.html模板,加入一个修改的按钮并传递一个Id```java

<div class="follower">
#foreach( $get in $list2)
<div class="f1">
<input type="hidden" name="id" value="$!{get.id}">
<img style="width:50px;height:50px;" src="$!{get.cimg}" alt="" />
<h4>$!{get.cname}</h4>
<span style="background-color:#ccc;"><a href="staff_edit.action?id=$!{get.id}" >修改</a></span>
<a href="staff_del.action?id=$!{get.id}" style="color:#000;">删除</a>
</div>
#end
<div class="clear"></div>
</div>

  1. 2 CustomerDAO.java中添加删除的方法
  2. ```java
  3. public void Delete(Integer id){
  4. if(null!=id&& id>0){
  5. try {
  6. PreparedStatement pstmt = conn.prepareStatement(
  7. "delete from customer where id=?");
  8. pstmt.setInt(1,id);
  9. pstmt.executeUpdate();
  10. } catch (SQLException e) {
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. }
  14. }

3、 创建StaffDeAction.java用于实现删除功能
package com.demo.www.action;
import com.demo.www.dao.CustomerDAO;
import com.opensymphony.xwork2.ActionSupport;
public class StaffDeAction extends ActionSupport {
private Integer id;
public String execute() throws Exception {
CustomerDAO c=new CustomerDAO();
c.Delete(id);
System.out.println(id);
return SUCCESS;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

4、 修改struts.xml配置文件

  1. <action name="staff_del" class="com.demo.www.action.StaffDeAction">
  2. <result name="success" type="redirect">/index.action</result>
  3. </action>

5、 运行项目

0 条评论
发表评论…
0
郑展汉

郑展汉 public 昨天下午

PHP 第三周总结

本周学习制作一个验证码程序

通过调用已有的系统函数imagecreatetruecolor(),mt_rand()等函数,绘制出斜线色块对系统产生的随机数进行一定遮蔽,最后将其作为PNG输出,完成验证码,代码如下:

  1. <?php
  2. header('Content-Type:image/png');
  3. $im=imagecreatetruecolor(200,200);//绘画一个有色图片长宽都为200
  4. $color=imagecolorallocate($im, 250, 255, 221);//设置背景颜色
  5. imagefill($im,0,0,$color);//区域填充
  6. for($i=0;$i<5;$i++){
  7. $linkcolor=imagecolorallocate($im, mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));//画线
  8. imageline($im,mt_rand(0,10),mt_rand(0,180),mt_rand(0,380),mt_rand(0,180),$linkcolor);//(pic,x1,y1,x2,y2,color)
  9. }
  10. $texts=array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9");
  11. $p = 30;//定义倾斜角度为30度
  12. for($i=0;$i<4;$i++){
  13. $textcolor = imagecolorallocate($im, mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));//自定义字的颜色
  14. imagettftext($im,40,mt_rand(-30,50),$p,100,$textcolor,mt_rand(1,21).".TTF",$texts[mt_rand(0,35)]);
  15. //出现随机数,,(字体大小,倾斜角度,x轴,y轴)
  16. $p+=30;
  17. }

0 条评论
发表评论…
0
郑展汉

郑展汉 public 昨天下午

PHP 第一周总结

在第一周开始PHP新课程

1.首先了解PHP的环境配置:PHP,Apche服务器以及Apche的配置文件conf目录的httpd.conf文件。
2.为熟悉回忆遗忘的PHP知识,编写一个输出九九乘法表的PHP程序,代码如下

  1. <?php
  2. for($i=1;$i<9;$i++){
  3. for($j=1;$j<9;$j++){
  4. echo "$i*$j='.$i*$j.'"; echo "<br ></9>";
  5. }
  6. }
  7. ?>

0 条评论
发表评论…
0
李美诗

李美诗 public 昨天下午

Web框架 第五周总结---发送消息和图片上传(1)

一、新建一个html文件,命名为index.html

  1. <form action="message_save.action" method="post" enctype="multipart/form-data" name="form1">
  2. <ul>
  3. <li>
  4. <input type="text" name="content" id="content"/>
  5. <input type="submit" name="button" id="button" value="发送"/>
  6. </li>
  7. <li><input type="file" name="upload[]" id="upload"> </li>
  8. <li> <input type="file" name="upload[]" id="upload"></li>
  9. <li><input type="file" name="upload[]" id="upload"></li>
  10. </ul>
  11. </form>

二、建立数据库为www,表名为message.

三、在model文件夹里做一个关于message的模型

  1. package com.demo.www.model;
  2. import java.sql.Timestamp;
  3. import com.alibaba.fastjson.JSON;
  4. public class Message {
  5. private Integer id;
  6. private Integer user;
  7. private String ip;
  8. private String content;
  9. private Timestamp pubtime;
  10. //get set略

四、在dao的文件夹,new一个class为MessageDAO。

  1. package com.demo.www.dao;
  2. import java.sql.PreparedStatement;
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import com.demo.www.model.Message;
  8. public class MessageDAO extends AbstractBaseDAO{//调用AbstractBaseDAO的内容
  9. //1、同一个类中出现的重复的代码,应该是将重复的代码移到独立的方法中(并不一定会用到的代码),或者构造方法中(一定会用到的代码)
  10. //2、在不同的类中出现重复的代码,应该将重复的代码移到父类中。移到独立的方法中(并不一定会用到的代码),或者构造方法中(一定会用到的代码)
  11. //3、不能共享的对象,不能作为类的属性
  12. //4、同一个类中需要共享的对象,可以作为类的属性,不同类中需要共享的对象,可以作为父类的属性
  13. //5、Ctrl+shift+o可以整理你不需要的代码
  14. public void save(Integer user,String content,String ip){//保存消息的工作
  15. try {
  16. PreparedStatement pstm = null;//这个是sql语句的,所以不能共享
  17. pstm = conn.prepareStatement("insert into message(user,content,ip) values(?,?,?,NOW())");
  18. pstm.setInt(1, user);
  19. pstm.setString(2, content);
  20. pstm.setString(3,ip);
  21. pstm.executeUpdate();
  22. } catch (SQLException e) {
  23. e.printStackTrace();// TODO
  24. }
  25. }
  26. }

查询所有消息

  1. public List<Message> findAll(){
  2. List<Message> list=new ArrayList<Message>();
  3. try {
  4. PreparedStatement pstm = null;
  5. pstm = conn.prepareStatement("select *from message");
  6. //pstm.setInt(1, user);
  7. //pstm.setString(2, content);
  8. //pstm.setString(3,ip);
  9. ResultSet rs=pstm.executeQuery();
  10. while(rs.next()){
  11. Message message =new Message();
  12. message.setId(rs.getInt("id"));
  13. message.setUser(rs.getInt("user"));
  14. message.setContent(rs.getString("content"));
  15. message.setIp(rs.getString("ip"));
  16. message.setPubtime(rs.getTimestamp("pubtime"));
  17. list.add(message);
  18. }
  19. } catch (SQLException e) {
  20. e.printStackTrace();// TODO
  21. }
  22. return list;
  23. }

五、打开struts.xml文件,把首页的内容显示出来

  1. <action name="index" class="com.demo.www.action.IndexAction">
  2. <result type="velocity">/WEB-INF/html/index.html</result>
  3. </action>

下一周,继续这个发送消息和图片的功能。

0 条评论
发表评论…
0
李美诗

李美诗 public 前天下午

Web 框架 第十五周总结--验证码

在前面几周,我完成了产品的发布,删除,修改,和授权等功能,我觉得在登录界面还少了点什么?没错,就是验证码啦,
一、由于在java方面,还是比较差的,所以我在网上找了相关的内容,并整合在了一起,实现了验证码的功能。
二、在网页上,先把放验证码的地方,写成一个图片的形式显示。

  1. <img src="validimg.action" onclick="this.src='validimg.action?'+Math.random()"/> </div>

三、在action文件夹,new一个类,命名为:CreateImageAction

  1. package com.demo.food.action;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics;
  5. import java.awt.image.BufferedImage;
  6. import java.io.ByteArrayInputStream;
  7. import java.io.ByteArrayOutputStream;
  8. import java.util.Random;
  9. import javax.imageio.ImageIO;
  10. import javax.servlet.http.HttpServletResponse;
  11. import javax.servlet.http.HttpSession;
  12. import org.apache.struts2.ServletActionContext;
  13. import com.opensymphony.xwork2.ActionSupport;
  14. public class CreateImageAction extends ActionSupport
  15. {
  16. private ByteArrayInputStream inputStream;
  17. private static int WIDTH = 60;
  18. private static int HEIGHT = 20;
  19. public ByteArrayInputStream getInputStream()
  20. {
  21. return inputStream;
  22. }
  23. public void setInputStream(ByteArrayInputStream inputStream)
  24. {
  25. this.inputStream = inputStream;
  26. }
  27. private static String createRandom()
  28. {
  29. String str = "0123456789qwertyuiopasdfghjklzxcvbnm";
  30. char[] rands = new char[4];
  31. Random random = new Random();
  32. for (int i = 0; i < 4; i++)
  33. {
  34. rands[i] = str.charAt(random.nextInt(36));
  35. }
  36. return new String(rands);
  37. }
  38. private void drawBackground(Graphics g)
  39. {
  40. // 画背景
  41. g.setColor(new Color(0xDCDCDC));
  42. g.fillRect(0, 0, WIDTH, HEIGHT);
  43. // 随机产生 120 个干扰点
  44. for (int i = 0; i < 120; i++)
  45. {
  46. int x = (int) (Math.random() * WIDTH);
  47. int y = (int) (Math.random() * HEIGHT);
  48. int red = (int) (Math.random() * 255);
  49. int green = (int) (Math.random() * 255);
  50. int blue = (int) (Math.random() * 255);
  51. g.setColor(new Color(red, green, blue));
  52. g.drawOval(x, y, 1, 0);
  53. }
  54. }
  55. private void drawRands(Graphics g, String rands)
  56. {
  57. g.setColor(Color.BLACK);
  58. g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18));
  59. // 在不同的高度上输出验证码的每个字符
  60. g.drawString("" + rands.charAt(0), 1, 17);
  61. g.drawString("" + rands.charAt(1), 16, 15);
  62. g.drawString("" + rands.charAt(2), 31, 18);
  63. g.drawString("" + rands.charAt(3), 46, 16);
  64. System.out.println(rands);
  65. }
  66. @Override
  67. public String execute() throws Exception
  68. {
  69. HttpServletResponse response = ServletActionContext.getResponse();
  70. // 设置浏览器不要缓存此图片
  71. response.setHeader("Pragma", "no-cache");
  72. response.setHeader("Cache-Control", "no-cache");
  73. response.setDateHeader("Expires", 0);
  74. String rands = createRandom();
  75. BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
  76. BufferedImage.TYPE_INT_RGB);
  77. Graphics g = image.getGraphics();
  78. // 产生图像
  79. drawBackground(g);
  80. drawRands(g, rands);
  81. // 结束图像 的绘制 过程, 完成图像
  82. g.dispose();
  83. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  84. ImageIO.write(image, "jpeg", outputStream);
  85. ByteArrayInputStream input = new ByteArrayInputStream(outputStream
  86. .toByteArray());
  87. this.setInputStream(input);
  88. HttpSession session = ServletActionContext.getRequest().getSession();
  89. session.setAttribute("checkCode", rands);
  90. input.close();
  91. outputStream.close();
  92. return SUCCESS;
  93. }
  94. }

四、打开struts.xml文件,把跳转代码写入:

  1. <action name="validimg" class="com.demo.food.action.CreateImageAction">
  2. <result name="success" type="stream" >
  3. <param name="contentType">image/jpeg</param>
  4. <param name="inputName">inputStream</param>
  5. </result>
  6. </action>

五、实现效果图:

0 条评论
发表评论…
0
李美诗

李美诗 public 前天下午

Web 框架 第十三周总结--授权认证

不是每一个都可以进行删除和修改和发布的功能,只有登录了帐号,才可以修改,如果没有登录,那么只能是查看页面的内容。
一、首先打开首页,我们因为要登录之后才能显示的,找到我们写修改和删除的位置。

  1. <div style="color:#666; margin-top:10px;">
  2. #if ($suser)
  3. <a href="product_edit.action?id=$!{product.id}">修改</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  4. <a href="product_delete.action?id=$!{product.id}">删除</a>
  5. #end
  6. </div>
  7. <!--在头部的内容上添加一句用来显示登录的名字->
  8. 当前的登录用户${name}

二、打开IndexAction文件,把判断语句写入。

  1. package com.demo.food.action;
  2. import java.util.List;
  3. import com.demo.food.dao.ProductDAO;
  4. import com.demo.food.model.Product;
  5. import com.demo.food.model.User;
  6. import com.opensymphony.xwork2.ActionContext;
  7. public class IndexAction extends AbstractBaseAction{
  8. private static final long serialVersionUID = 1L;
  9. private List<Product> list;
  10. private String suser;
  11. private String name;
  12. public String execute() throws Exception{
  13. User user=(User)ActionContext.getContext().getSession().get("user");
  14. if(null!=user){
  15. name=user.getName();
  16. suser=user.getAccount();
  17. }
  18. ProductDAO dao= new ProductDAO();
  19. list=dao.findAll(4);
  20. return SUCCESS;
  21. }
  22. //省略 get set 语句

三、打开struts.xml文件加上显示的语句。

  1. <action name="index" class="com.demo.food.action.IndexAction">
  2. <result type="velocity">/WEB-INF/html/index.html</result><!-- 通过indexaction访问index页面 -->
  3. </action>

四、可以看到,我运行之后的页面上是有显示用户的名字的

出现修改和删除按钮,那么下一周即将完成删除的功能。

0 条评论
发表评论…
0
李美诗

李美诗 public 前天下午

Web 框架 第十一周总结---产品的发布和产品的查询

上一周,我做了登录的功能,这一次在上一次的基础上,我要做一个产品的发布的功能。
一、新建一个HTML文件,命名为fbsp.html,如图,里面有产品的名称,价格,图片,产品描述等字段。

二、新建一个数据库表,里面的字段跟网页上对应,如图

三、根据数据库的字段,我们在model文件夹,新建一个class,里面写产品字段的模型。

  1. package com.demo.food.model;
  2. import java.sql.Timestamp;
  3. public class Product {
  4. private Integer id;
  5. private String name;
  6. private String content;
  7. private float price;
  8. private String pic;
  9. private Timestamp ctime;
  10. //跟上周一样的操作,把get,set的代码补全,此处略

四、在action文件夹上,新建一个ProductInputAction这个类,用于显示fbsp.html的内容

  1. package com.demo.food.action;
  2. import com.opensymphony.xwork2.ActionSupport;
  3. public class ProductInputAction extends ActionSupport {
  4. public String execute() throws Exception{
  5. return SUCCESS;
  6. }
  7. }

五、在dao文件下,新建一个class,里面放产品的添加和查询语句

  1. import java.sql.PreparedStatement;
  2. import java.sql.ResultSet;
  3. import java.sql.SQLException;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import com.demo.food.model.Product;
  7. public class ProductDAO extends AbstractBaseDAO {//引入AbstractBaseDAO

这个是查询语句。

  1. public List<Product> findAll(Integer size){
  2. List<Product> list=new ArrayList<Product>();
  3. try {
  4. PreparedStatement pstm = null;
  5. pstm = conn.prepareStatement("select *from product where 1 limit 0,4");
  6. ResultSet rs=pstm.executeQuery();
  7. while(rs.next()){
  8. Product product =new Product();
  9. product.setId(rs.getInt("id"));
  10. product.setName(rs.getString("name"));
  11. product.setContent(rs.getString("content"));
  12. product.setPrice(rs.getFloat("price"));
  13. product.setPic(rs.getString("pic"));
  14. list.add(product);
  15. }
  16. } catch (SQLException e) {
  17. e.printStackTrace();// TODO
  18. }
  19. return list;


保存数据的语句。

  1. public void save(String name,String content,double price, String pic){
  2. try {
  3. PreparedStatement pstm = null;
  4. pstm = conn.prepareStatement("insert into product(name,content,price,pic) values(?,?,?,?)");
  5. pstm.setString(1, name);
  6. pstm.setString(2, content);
  7. pstm.setDouble(3, price);
  8. pstm.setString(4, pic);
  9. pstm.executeUpdate();
  10. } catch (SQLException e) {
  11. e.printStackTrace();// TODO
  12. }
  13. }

六、在action文件,新建一个类,命名为ProductSaveAction,用于图片的保存

  1. package com.demo.food.action;
  2. import java.io.File;
  3. import java.util.List;
  4. import org.apache.commons.io.FileUtils;
  5. import org.apache.commons.lang.StringUtils;
  6. import org.apache.struts2.ServletActionContext;
  7. import com.demo.food.dao.ProductDAO;
  8. import com.opensymphony.xwork2.ActionSupport;
  9. public class ProductSaveAction extends ActionSupport {
  10. private Integer id;
  11. private String name;
  12. private String content;
  13. private double price;
  14. private List<File> upload;
  15. private List<String> uploadFileName;
  16. private List<String> uploadContentType;
  17. private String yldt;
  18. public String execute() throws Exception{
  19. ProductDAO dao= new ProductDAO();
  20. String pic="";//定义一个string pic类型
  21. if(null !=upload && upload.size()>0){
  22. String savepath=ServletActionContext.getServletContext().getRealPath("/upload");//文件夹的地址 ,savepath路径
  23. System.out.println(savepath);//输出文件地址
  24. File destfile=new File(new File(savepath),uploadFileName.get(0));//找到路径 文件名 目的地文件
  25. if(!destfile.getParentFile().exists()){//判断文件是否存在
  26. destfile.getParentFile().mkdirs();
  27. }
  28. FileUtils.copyFile(upload.get(0), destfile);//复制文件,文件夹的名字和文件名称
  29. pic="upload/"+ uploadFileName.get(0);
  30. dao.save(name, content, price, pic);
  31. return SUCCESS;
  32. }

七、打开struts.xml文件,把显示网页的代码和打开页面的地址,写上。

  1. <action name="product_input" class="com.demo.food.action.ProductInputAction">
  2. <result type="velocity">/WEB-INF/html/fbsp.html</result><!--显示发布产品的页面-->
  3. </action>
  4. <action name="product_save" class="com.demo.food.action.ProductSaveAction">
  5. <result type="redirect">/index.action</result><!--实现跳转到首页的action-->
  6. </action>

记得在发布页面上的跳转地址是:

  1. <form action="product_save.action" method="post" enctype="multipart/form-data" name="form"; >
  2. </form>

八、打开首页,我们要通过foreach循环语句,把我们所发的内容循环显示。

  1. <ul class="carousel1">
  2. #foreach($product in $list)
  3. <li><div><img src="$!{product.pic}" alt="">
  4. <div class="col1 upp"> <a href="#">$!{product.name}</a></div>
  5. <span> $!{product.content}</span>
  6. <div class="price">$!{product.price}</div></div>
  7. </li>
  8. #end
  9. </ul>

九、我们运行之后,输入域名为http://localhost:8080/food/product_input.action,
就可以看到,发布页面,我们填完字段之后,点击发布,就可以跳转。如图显示:

0 条评论
发表评论…
0
卢泽伟

卢泽伟 public 2016-06-24

  1. 通过两周不停的调试,我们飞行器已经可以上天了。从最初的的零件到一个成品完成,满满的成就感,特别是它飞起来的时候。期间我们遇到了很多的困难,多亏了拽权哥(淘宝店主)的帮忙。
  2. 通过这次活动我们学到了很多知识,提高了动手能力,兴趣是最重要的。如果不是对它有无限的兴趣,我想可能当初可能就已经放弃了。
  3. 组装飞行器的大致过程,由于之前飞控在组装的时候出了点意外。所以飞行器组装的拖了很长一段时间,当飞控重新买到手以后。我们便立即开始这个项目,组装期间没有遇到任何的问题,但是焊接线路的时候就遇到问题。第一次用烙铁,其实是蛮怕的。后面接触过一段时间以后才慢慢不畏惧。紧接着就是调试遥控器,在用软件调试的时候出现了问题,在模拟器上我们的飞机就是不停的坠机,根本飞不起来。这个问题弄了一个下午,最后发现是混控了,把遥控器恢复出厂设置才解决的。之前一直找不到问题的关键点,一直以为是我们的操作有问题才使得飞机一直坠毁,当发现问题关键点后便能很快的解决问题。之后我们遇到问题以后都是放下东西想想这个问题的根源,通过根源来想办法。
  4. 功夫不负有心人,我们的弄了两天以后,我们的电机终于能动了。于是我们便把浆装了上去,之后又遇到了问题了。就是任我们怎么加大马力,飞行器就是一直在原地,压根没有往上飞的迹象。通过查阅资料,和请教他人,最终解决了这个问题。开始以为是扇叶装反了,导致它风力是朝上方的,把扇叶反过来装以后,还是飞不起来。我们便去请教他人,群里问了下,各种答案都有。有说没电的、有说扇叶装反的、电机马力不够的等等,把他们都给的答案都不能解决我们的问题。最后我们查找了飞行器的飞行原理,发现相邻的两个电机的转向是不同的。调换了下电调与电机的接线就完美解决了这个问题,最后就是试飞。
  5. 试飞的过程中,由于操作还有调试不当,不能垂直起飞,总是朝一个方向飞。然后摔在了沙地上。等再次拨动油门以后,电调就不断的滴滴滴滴滴响。查找了很多资料未果,我们又去请教拽权哥,最后他叫我们重新校准遥控器以后这问题便不再出现了。最后校准一下水平以后,飞行器终于能够相对稳定的飞起来了。
  6. 通过这次活动学习到了最多的便是在遇到问题的时候,如何发现问题的根源、如何查找资料、如何询问他人寻找答案。

0 条评论
发表评论…
0
周文彪

周文彪 public 2016-06-24

第十一周学习总结

本周重新复习了Java面向对:Java面向对象中类与对象的概念和使用、Java面向对象的基本特征之一:封装性Java面向对象中引用的传递、Java面向对象基本特征继承、Java面向对象-抽象类与接口、Java面向对象多态性、Java面向对象之泛型。

Java抽象类
package com.jike.finaldemo;
abstract class Abs{
private int age;//属性
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void tell(){ //方法
}
//抽象方法:未必实现的方法
public abstract void say();//class未添加abstract声明,所以错误,在ABS类中添加abstract
public abstract void print();
}
class AbstractDemo2 extends Abs{//抽象类不可直接实例化,通过子类实例化,并重写所有抽象方法
public void say(){
System.out.println(getAge());
}
public void print(){
}
}
public class AbstractDemo {
public static void main(String[] args) {
AbstractDemo2 abs = new AbstractDemo2(); //重写完后可直接实例化
abs.setAge(13);
abs.say();

泛型在接口的使用
package com.jike.finaldemo;
interface GenInter<T>{
public void say();//抽象方法
}
class Gin implements GenInter<String>{
private String info;
public Gin(String info) {//构造方法作用是传递方便
super();
this.info = info;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public void say() {//重写
}
}
public class GenericDemo4 {
public static void main(String[] args) {
Gin g = new Gin(“hahahah”);
System.out.println(g.getInfo());
}

0 条评论
发表评论…
0
黄俊锋

黄俊锋 public 2016-06-24

Android:智能安装功能

那么对于ROOT过的手机,秒装功能确实可以避免弹出系统安装界面,在不影响用户操作的情况下实现静默安装,但是对于绝大部分没有ROOT的手机,这个功能是不可用的。那么我们应该怎么办呢?为此360手机助手提供了一种折中方案,就是借助Android提供的无障碍服务来实现智能安装。所谓的智能安装其实并不是真正意义上的静默安装,因为它还是要弹出系统安装界面的,只不过可以在安装界面当中释放用户的操作,由智能安装功能来模拟用户点击,安装完成之后自动关闭界面。这个功能是需要用户手动开启的,并且只支持Android 4.1之后的手机,如下图所示:

好的,那么接下来我们就模仿一下360手机助手,来实现类似的智能安装功能。
智能安装功能的实现原理要借助Android提供的无障碍服务,关于无障碍服务的详细讲解可参考官方文档:http://developer.android.com/guide/topics/ui/accessibility/services.html。
首先在res/xml目录下新建一个accessibility_service_config.xml文件,代码如下所示:

  1. <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:packageNames="com.android.packageinstaller"
  3. android:description="@string/accessibility_service_description"
  4. android:accessibilityEventTypes="typeAllMask"
  5. android:accessibilityFlags="flagDefault"
  6. android:accessibilityFeedbackType="feedbackGeneric"
  7. android:canRetrieveWindowContent="true"
  8. />

其中,packageNames指定我们要监听哪个应用程序下的窗口活动,这里写com.android.packageinstaller表示监听Android系统的安装界面。description指定在无障碍服务当中显示给用户看的说明信息,上图中360手机助手的一大段内容就是在这里指定的。accessibilityEventTypes指定我们在监听窗口中可以模拟哪些事件,这里写typeAllMask表示所有的事件都能模拟。accessibilityFlags可以指定无障碍服务的一些附加参数,这里我们传默认值flagDefault就行。accessibilityFeedbackType指定无障碍服务的反馈方式,实际上无障碍服务这个功能是Android提供给一些残疾人士使用的,比如说盲人不方便使用手机,就可以借助无障碍服务配合语音反馈来操作手机,而我们其实是不需要反馈的,因此随便传一个值就可以,这里传入feedbackGeneric。最后canRetrieveWindowContent指定是否允许我们的程序读取窗口中的节点和内容,必须写true。
记得在string.xml文件中写一下description中指定的内容,如下所示:

  1. <resources>
  2. <string name="app_name">InstallTest</string>
  3. <string name="accessibility_service_description">智能安装服务,无需用户的任何操作就可以自动安装程序。</string>
  4. </resources>

接下来修改AndroidManifest.xml文件,在里面配置无障碍服务:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.installtest">
  4. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  5. <application
  6. android:allowBackup="true"
  7. android:icon="@mipmap/ic_launcher"
  8. android:label="@string/app_name"
  9. android:supportsRtl="true"
  10. android:theme="@style/AppTheme">
  11. ......
  12. <service
  13. android:name=".MyAccessibilityService"
  14. android:label="我的智能安装"
  15. android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
  16. <intent-filter>
  17. <action android:name="android.accessibilityservice.AccessibilityService" />
  18. </intent-filter>
  19. <meta-data
  20. android:name="android.accessibilityservice"
  21. android:resource="@xml/accessibility_service_config" />
  22. </service>
  23. </application>
  24. </manifest>

这部分配置的内容多数是固定的,必须要声明一个android.permission.BIND_ACCESSIBILITY_SERVICE的权限,且必须要有一个值为android.accessibilityservice.AccessibilityService的action,然后我们通过<meta-data>将刚才创建的配置文件指定进去。
接下来就是要去实现智能安装功能的具体逻辑了,创建一个MyAccessibilityService类并继承自AccessibilityService,代码如下所示:

  1. /**
  2. * 智能安装功能的实现类。
  3. * 原文地址:http://blog.csdn.net/guolin_blog/article/details/47803149
  4. * @author guolin
  5. * @since 2015/12/7
  6. */
  7. public class MyAccessibilityService extends AccessibilityService {
  8. Map<Integer, Boolean> handledMap = new HashMap<>();
  9. public MyAccessibilityService() {
  10. }
  11. @Override
  12. public void onAccessibilityEvent(AccessibilityEvent event) {
  13. AccessibilityNodeInfo nodeInfo = event.getSource();
  14. if (nodeInfo != null) {
  15. int eventType = event.getEventType();
  16. if (eventType== AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED ||
  17. eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
  18. if (handledMap.get(event.getWindowId()) == null) {
  19. boolean handled = iterateNodesAndHandle(nodeInfo);
  20. if (handled) {
  21. handledMap.put(event.getWindowId(), true);
  22. }
  23. }
  24. }
  25. }
  26. }
  27. private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
  28. if (nodeInfo != null) {
  29. int childCount = nodeInfo.getChildCount();
  30. if ("android.widget.Button".equals(nodeInfo.getClassName())) {
  31. String nodeContent = nodeInfo.getText().toString();
  32. Log.d("TAG", "content is " + nodeContent);
  33. if ("安装".equals(nodeContent)
  34. || "完成".equals(nodeContent)
  35. || "确定".equals(nodeContent)) {
  36. nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
  37. return true;
  38. }
  39. } else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
  40. nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
  41. }
  42. for (int i = 0; i < childCount; i++) {
  43. AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
  44. if (iterateNodesAndHandle(childNodeInfo)) {
  45. return true;
  46. }
  47. }
  48. }
  49. return false;
  50. }
  51. @Override
  52. public void onInterrupt() {
  53. }
  54. }

代码并不复杂,我们来解析一下。每当窗口有活动时,就会有消息回调到onAccessibilityEvent()方法中,因此所有的逻辑都是从这里开始的。首先我们可以通过传入的AccessibilityEvent参数来获取当前事件的类型,事件的种类非常多,但是我们只需要监听TYPE_WINDOW_CONTENT_CHANGED和TYPE_WINDOW_STATE_CHANGED这两种事件就可以了,因为在整个安装过程中,这两个事件必定有一个会被触发。当然也有两个同时都被触发的可能,那么为了防止二次处理的情况,这里我们使用了一个Map来过滤掉重复事件。
接下来就是调用iterateNodesAndHandle()方法来去解析当前界面的节点了,这里我们通过递归的方式将安装界面中所有的子节点全部进行遍历,当发现按钮节点的时候就进行判断,按钮上的文字是不是“安装”、“完成”、“确定”这几种类型,如果是的话就模拟一下点击事件,这样也就相当于帮用户自动操作了这些按钮。另外从Android 4.4系统开始,用户需要将应用申请的所有权限看完才可以点击安装,因此如果我们在节点中发现了ScrollView,那就模拟一下滑动事件,将界面滑动到最底部,这样安装按钮就可以点击了。
最后,回到MainActivity中,来增加对智能安装功能的调用,如下所示:

  1. /**
  2. * 仿360手机助手秒装和智能安装功能的主Activity。
  3. * 原文地址:http://blog.csdn.net/guolin_blog/article/details/47803149
  4. * @author guolin
  5. * @since 2015/12/7
  6. */
  7. public class MainActivity extends AppCompatActivity {
  8. ......
  9. public void onForwardToAccessibility(View view) {
  10. Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
  11. startActivity(intent);
  12. }
  13. public void onSmartInstall(View view) {
  14. if (TextUtils.isEmpty(apkPath)) {
  15. Toast.makeText(this, "请选择安装包!", Toast.LENGTH_SHORT).show();
  16. return;
  17. }
  18. Uri uri = Uri.fromFile(new File(apkPath));
  19. Intent localIntent = new Intent(Intent.ACTION_VIEW);
  20. localIntent.setDataAndType(uri, "application/vnd.android.package-archive");
  21. startActivity(localIntent);
  22. }
  23. }

当点击了开启智能安装服务按钮时,我们通过Intent跳转到系统的无障碍服务界面,在这里启动智能安装服务。当点击了智能安装按钮时,我们通过Intent跳转到系统的安装界面,之后所有的安装操作都会自动完成了。
源代码下载网址:http://download.csdn.net/detail/sinyu890807/9351733

0 条评论
发表评论…
0
何镔

何镔 public 2016-06-24

第十六周学习笔记

这周根据上周设计出来的水果网站设计图,来做成网站。

0 条评论
发表评论…
0
卢泽伟

卢泽伟 public 2016-06-24

linux安装软件

1:RPM包,这种软件包就像windows的EXE安装文件一样,各种文件已经编译好,并打了包,哪个文件该放到哪个文件夹,都指定好了,安装非常方便,在图形界面里你只需要双击就能自动安装。  卸载:  1、打开一个SHELL终端  2、因为Linux下的软件名都包括版本号,所以卸载前最好先确定这个软件的完整名称。  查找RPM包软件:rpm -qa ×××*  注意:×××指软件名称开头的几个字母,*就是通配符号“*” 3、找到软件后,显示出来的是软件完整名称,如firefox-1.0.1-1.3.2  执行卸载命令:rpm -e firefox-1.0.1-1.3.2  ===安装目录,执行命令查找:rpm -ql firefox-1.0.1-1.3.2  2:tar.gz(bz或bz2等)结尾的源代码包,这种软件包里面都是源程序,没有编译过,需要编译后才能安装,安装方法为:  1、打开一个SHELL,即终端  2、用CD 命令进入源代码压缩包所在的目录  3、根据压缩包类型解压缩文件(*代表压缩包名称)  tar -zxvf ****.tar.gz  tar -jxvf ****.tar.bz(或bz2)  4、用CD命令进入解压缩后的目录  5、输入编译文件命令:./configure(有的压缩包已经编译过,这一步可以省去)  6、然后是命令:make  7、再是安装文件命令:make install  8、安装完毕 

0 条评论
发表评论…
0
黄俊锋

黄俊锋 public 2016-06-24

Android:一个改善的okHttp封装库

引入:
使用前,对于Android Studio的用户,可以选择添加:

  1. compile project(':okhttputils')
  2. 或者
  3. compile 'com.zhy:okhttputils:2.0.0'

基本用法
目前基本的用法格式为:

  1. OkHttpUtils
  2. .get()
  3. .url(url)
  4. .addParams("username", "hyman")
  5. .addParams("password", "123")
  6. .build()
  7. .execute(callback);

通过链式去根据自己的需要添加各种参数,最后调用execute(callback)进行执行,传入callback则代表是异步。如果单纯的execute()则代表同步的方法调用。
可以看到,取消了之前一堆的get重载方法,参数也可以进行灵活的选择了。
下面简单看一下,全部的用法:
(1)GET请求

  1. String url = "http://www.csdn.net/";
  2. OkHttpUtils
  3. .get()
  4. .url(url)
  5. .addParams("username", "hyman")
  6. .addParams("password", "123")
  7. .build()
  8. .execute(new StringCallback()
  9. {
  10. @Override
  11. public void onError(Request request, Exception e)
  12. {
  13. }
  14. @Override
  15. public void onResponse(String response)
  16. {
  17. }
  18. });

(2)POST请求

  1. OkHttpUtils
  2. .post()
  3. .url(url)
  4. .addParams("username", "hyman")
  5. .addParams("password", "123")
  6. .build()
  7. .execute(callback);

(3)Post String

  1. OkHttpUtils
  2. .postString()
  3. .url(url)
  4. .content(new Gson().toJson(new User("zhy", "123")))
  5. .build()
  6. .execute(new MyStringCallback());

将string作为请求体传入到服务端,例如json字符串。
(4)Post File

  1. OkHttpUtils
  2. .postFile()
  3. .url(url)
  4. .file(file)
  5. .build()
  6. .execute(new MyStringCallback());

将file作为请求体传入到服务端.

(5)基于POST的文件上传(类似web上的表单)

  1. OkHttpUtils.post()//
  2. .addFile("mFile", "messenger_01.png", file)//
  3. .addFile("mFile", "test1.txt", file2)//
  4. .url(url)
  5. .params(params)//
  6. .headers(headers)//
  7. .build()//
  8. .execute(new MyStringCallback());

(6)下载文件

  1. OkHttpUtils//
  2. .get()//
  3. .url(url)//
  4. .build()//
  5. .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "gson-2.2.1.jar")//
  6. {
  7. @Override
  8. public void inProgress(float progress)
  9. {
  10. mProgressBar.setProgress((int) (100 * progress));
  11. }
  12. @Override
  13. public void onError(Request request, Exception e)
  14. {
  15. Log.e(TAG, "onError :" + e.getMessage());
  16. }
  17. @Override
  18. public void onResponse(File file)
  19. {
  20. Log.e(TAG, "onResponse :" + file.getAbsolutePath());
  21. }
  22. });

(7)显示图片

  1. OkHttpUtils
  2. .get()//
  3. .url(url)//
  4. .build()//
  5. .execute(new BitmapCallback()
  6. {
  7. @Override
  8. public void onError(Request request, Exception e)
  9. {
  10. mTv.setText("onError:" + e.getMessage());
  11. }
  12. @Override
  13. public void onResponse(Bitmap bitmap)
  14. {
  15. mImageView.setImageBitmap(bitmap);
  16. }
  17. });

哈,目前来看,清晰多了。

三、对于上传下载的回调

  1. new Callback<?>()
  2. {
  3. //...
  4. @Override
  5. public void inProgress(float progress)
  6. {
  7. //use progress: 0 ~ 1
  8. }
  9. }

对于传入的callback有个inProgress方法,需要拿到进度直接复写该方法即可。

四、对于自动解析为实体类

目前去除了Gson的依赖,提供了自定义Callback的方式,让用户自己去解析返回的数据,目前提供了StringCallback,FileCallback,BitmapCallback 分别用于返回string,文件下载,加载图片。

当然如果你希望解析为对象,你可以:

  1. public abstract class UserCallback extends Callback<User>
  2. {
  3. //非UI线程,支持任何耗时操作
  4. @Override
  5. public User parseNetworkResponse(Response response) throws IOException
  6. {
  7. String string = response.body().string();
  8. User user = new Gson().fromJson(string, User.class);
  9. return user;
  10. }
  11. }

自己使用自己喜欢的Json解析库完成即可。

解析成List<User>,则如下:

  1. public abstract class ListUserCallback extends Callback<List<User>>
  2. {
  3. @Override
  4. public List<User> parseNetworkResponse(Response response) throws IOException
  5. {
  6. String string = response.body().string();
  7. List<User> user = new Gson().fromJson(string, List.class);
  8. return user;
  9. }
  10. }

五、对于https单向认证

非常简单,拿到xxx.cert的证书。

然后调用

  1. OkHttpUtils.getInstance()
  2. .setCertificates(inputstream);

建议使用方式,例如我的证书放在assets目录:

  1. /**
  2. * Created by zhy on 15/8/25.
  3. */
  4. public class MyApplication extends Application
  5. {
  6. @Override
  7. public void onCreate()
  8. {
  9. super.onCreate();
  10. try
  11. {
  12. OkHttpUtils
  13. .getInstance()
  14. .setCertificates(getAssets().open("aaa.cer"),
  15. getAssets().open("server.cer"));
  16. } catch (IOException e)
  17. {
  18. e.printStackTrace();
  19. }
  20. }
  21. }

即可。别忘了注册Application。

注意:如果https网站为权威机构颁发的证书,不需要以上设置。自签名的证书才需要。

六、配置

(1)全局配置

可以在Application中,通过:

  1. OkHttpClient client =
  2. OkHttpUtils.getInstance().getOkHttpClient();

然后调用client的各种set方法。

例如:

  1. client.setConnectTimeout(100000, TimeUnit.MILLISECONDS);

(2)为单个请求设置超时

比如涉及到文件的需要设置读写等待时间多一点。

  1. OkHttpUtils
  2. .get()//
  3. .url(url)//
  4. .tag(this)//
  5. .build()//
  6. .connTimeOut(20000)
  7. .readTimeOut(20000)
  8. .writeTimeOut(20000)
  9. .execute()

调用build()之后,可以随即设置各种timeOut.

(3)取消单个请求

  1. RequestCall call = OkHttpUtils.get().url(url).build();
  2. call.cancel();

(4)根据tag取消请求

目前对于支持的方法都添加了最后一个参数Object tag,取消则通过OkHttpUtils.cancelTag(tag)执行。

例如:在Activity中,当Activity销毁取消请求:

  1. OkHttpUtils
  2. .get()//
  3. .url(url)//
  4. .tag(this)//
  5. .build()//
  6. @Override
  7. protected void onDestroy()
  8. {
  9. super.onDestroy();
  10. //可以取消同一个tag的
  11. OkHttpUtils.cancelTag(this);//取消以Activity.this作为tag的请求
  12. }

比如,当前Activity页面所有的请求以Activity对象作为tag,可以在onDestory里面统一取消。

七、浅谈封装

其实整个封装的过程比较简单,这里简单描述下,对于okhttp一个请求的流程大致是这样的:

  1. //创建okHttpClient对象
  2. OkHttpClient mOkHttpClient = new OkHttpClient();
  3. //创建一个Request
  4. final Request request = new Request.Builder()
  5. .url("https://github.com/hongyangAndroid")
  6. .build();
  7. //new call
  8. Call call = mOkHttpClient.newCall(request);
  9. //请求加入调度
  10. call.enqueue(new Callback()
  11. {
  12. @Override
  13. public void onFailure(Request request, IOException e)
  14. {
  15. }
  16. @Override
  17. public void onResponse(final Response response) throws IOException
  18. {
  19. //String htmlStr = response.body().string();
  20. }
  21. });

其中主要的差异,其实就是request的构建过程。

我对Request抽象了一个类:OkHttpRequest

  1. public abstract class OkHttpRequest
  2. {
  3. protected RequestBody requestBody;
  4. protected Request request;
  5. protected String url;
  6. protected String tag;
  7. protected Map<String, String> params;
  8. protected Map<String, String> headers;
  9. protected OkHttpRequest(String url, String tag,
  10. Map<String, String> params, Map<String, String> headers)
  11. {
  12. this.url = url;
  13. this.tag = tag;
  14. this.params = params;
  15. this.headers = headers;
  16. }
  17. protected abstract Request buildRequest();
  18. protected abstract RequestBody buildRequestBody();
  19. protected void prepareInvoked(ResultCallback callback)
  20. {
  21. requestBody = buildRequestBody();
  22. requestBody = wrapRequestBody(requestBody, callback);
  23. request = buildRequest();
  24. }
  25. protected RequestBody wrapRequestBody(RequestBody requestBody, final ResultCallback callback)
  26. {
  27. return requestBody;
  28. }
  29. public void invokeAsyn(ResultCallback callback)
  30. {
  31. prepareInvoked(callback);
  32. mOkHttpClientManager.execute(request, callback);
  33. }
  34. // other common methods
  35. }

一个request的构建呢,我分三个步骤:buildRequestBody , wrapRequestBody ,buildRequest这样的次序,当以上三个方法没有问题时,我们就拿到了request,然后执行即可。

但是对于不同的请求,requestBody以及request的构建过程是不同的,所以大家可以看到buildRequestBody ,buildRequest为抽象的方法,也就是不同的请求类,比如OkHttpGetRequest、OkHttpPostRequest等需要自己去构建自己的request。

对于wrapRequestBody方法呢,可以看到它默认基本属于空实现,主要是因为并非所有的请求类都需要复写它,只有上传的时候呢,需要回调进度,需要对requestBody进行包装,所以这个方法类似于一个钩子。

其实这个过程有点类似模板方法模式,有兴趣可以看看一个短篇介绍设计模式 模版方法模式 展现程序员的一天 .

对于更加详细的用法,可以查看github上面的readme,以及demo,目前demo包含:https://github.com/hongyangAndroid/okhttp-utils
转载:http://blog.csdn.net/lmj623565791/article/details/49734867;

0 条评论
发表评论…
0
黄俊锋

黄俊锋 public 2016-06-24

Android:显示百度地图

百度地图SDK为开发者提供了便捷的显示百度地图数据的接口,通过以下几步操作,即可在您的应用中使用百度地图数据:
第一步:创建并配置工程(具体方法参见工程配置部分的介绍);
第二步:在AndroidManifest中添加开发密钥、所需权限等信息;
1)在application中添加开发密钥

  1. <application>
  2. <meta-data
  3. android:name="com.baidu.lbsapi.API_KEY"
  4. android:value="开发者 key" />
  5. </application>

2)添加所需权限

  1. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  2. <uses-permission android:name="android.permission.INTERNET"/>
  3. <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
  4. <uses-permission android:name="android.permission.WAKE_LOCK"/>
  5. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  6. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  7. <uses-permission android:name="android.permission.GET_TASKS" />
  8. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  9. <uses-permission android:name="android.permission.WRITE_SETTINGS" />

3)在布局xml文件中添加地图控件

  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. //在使用SDK各组件之前初始化context信息,传入ApplicationContext
  6. //注意该方法要再setContentView方法之前实现
  7. SDKInitializer.initialize(getApplicationContext());
  8. setContentView(R.layout.activity_main);
  9. }
  10. }

注意:在SDK各功能组件使用之前都需要调用
SDKInitializer.initialize(getApplicationContext());,因此建议该方法放在Application的初始化方法中
第五步,创建地图Activity,管理地图生命周期;

  1. public class MainActivity extends Activity {
  2. MapView mMapView = null;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. //在使用SDK各组件之前初始化context信息,传入ApplicationContext
  7. //注意该方法要再setContentView方法之前实现
  8. SDKInitializer.initialize(getApplicationContext());
  9. setContentView(R.layout.activity_main);
  10. //获取地图控件引用
  11. mMapView = (MapView) findViewById(R.id.bmapView);
  12. }
  13. @Override
  14. protected void onDestroy() {
  15. super.onDestroy();
  16. //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
  17. mMapView.onDestroy();
  18. }
  19. @Override
  20. protected void onResume() {
  21. super.onResume();
  22. //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
  23. mMapView.onResume();
  24. }
  25. @Override
  26. protected void onPause() {
  27. super.onPause();
  28. //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
  29. mMapView.onPause();
  30. }
  31. }

完成以上步骤后,运行程序,即可在您的应用中显示如下地图:

0 条评论
发表评论…
0
江佳俊

江佳俊 public 2016-06-24

补:MySQL 连接

可以使用MySQL二进制方式进入到MySQL命令提示符下来连接MySQL数据库。 通过java连接通过输入账号和密码 Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/User" ;//地址 String username = "root"; String password = "123456";

0 条评论
发表评论…
0