2013年 的存档
201312 月25

Nutz:上传文件的配置项扩展,实现对文件类型的限制及分类

upload.json 配置文件,增加扩展配置项extOption,内容可以由用户自定义,返回一个Map对象。

我要实现功能是,用户在相册里只允许上传图片文件、视频里只允许上传视频格式的文件等,

结合上传控件和JS,实现在页面级和代码级的文件类型分类限制、分类保存等功能。

Nutz issue 提交需求不被接纳所以只好自己实现了,大家如需要的话可以提issue,希望以后Nutz能内置:

https://github.com/nutzam/nutz/issues/568

upload.json:

var ioc = {
		upload : {
			type : "org.nutz.mvc.upload.UploadAdaptor",
			args : [{refer : "uploadCtx"}]
		},
		uploadCtx : {
			type : "org.nutz.mvc.upload.UploadingContext",
			args : [{refer: "filePool"}],
			fields : {
				ignoreNull : true,
				maxFileSize : 10485760,
				nameFilter : ".+(jpg|gif|png|jpeg|doc|docx|xls|xlsx|ppt|pptx|wps|pdf|txt|chm|mp3|mp4|3gp|rm|swf|flv|asf|wmv|wma|z|zip|rar|ios|jar)",
				extOption: {
					"images":"jpg,gif,png,jpeg",
					"document":"doc,docx,xls,xlsx,ppt,pptx,wps,pdf,txt,chm",
				    "music":"mp3",
				    "video":"mp4,3gp,rm,swf,flv,asf,wmv,wma",
				    "archive":"z,zip,rar,ios,jar"			            
				   }
			}
		},
		filePool : {
			type : "com.hits.common.file.FilePool",
			args : ["/temp/", 2000]
		}
};

改写Nutz源码:

org.nutz.mvc.upload.UploadingContext 类,增加代码:

    /**
     * 一个扩展配置项,用户可自定义内容
     */
    private Map<String, String> extOption;

    public Map<String, String> getExtOption() {
        return extOption;
    }

    public UploadingContext setExtOption(String extOption) {
        this.extOption = Json.fromJsonAsMap(String.class,extOption);
        return this;
    }

增加一个调用类:

FileType.java

/** 
 * 类描述: 
 * 创建人:Wizzer 
 * 联系方式:www.wizzer.cn
 * 创建时间:2013-12-25 下午1:13:30 
 * @version 
 */
public class FileType { 
	/**
	 * 根据文件名获取文件类型,默认返回other
	 * @param upload
	 * @param suffixname
	 * @return
	 */
	public static String getFileType(UploadAdaptor upload,String suffixname) {
		Map<String,String> hm=upload.getContext().getExtOption();
		String str = StringUtil.null2String(suffixname).toLowerCase();
		Set<Map.Entry<String, String>> set = hm.entrySet();
        for (Iterator<Map.Entry<String, String>> it = set.iterator(); it.hasNext();) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
            if(entry.getValue().toLowerCase().indexOf(str)>-1)
            	return entry.getKey();
        }
		return "other";
	}
	/**
	 * 根据文件类型获取文件后缀名,默认返回nameFilter配置
	 * @param upload
	 * @param filetype
	 * @return
	 */
	public static String getSuffixname(UploadAdaptor upload,String filetype) {
		Map<String,String> hm=upload.getContext().getExtOption();
		String str = StringUtil.null2String(filetype).toLowerCase();
		if(!"".equals(str)){
			Set<Map.Entry<String, String>> set = hm.entrySet();
	        for (Iterator<Map.Entry<String, String>> it = set.iterator(); it.hasNext();) {
	            Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
	            if(entry.getKey().toLowerCase().equals(str))
	            	return entry.getValue();
	        }
		}
        String name=upload.getContext().getNameFilter(); 
		return name.substring(name.indexOf("(")+1,name.lastIndexOf(")")).replace("|", ",");
	}
}

使用示例:

	@Inject
	protected UploadAdaptor upload;

	@At
	@Ok("->:/private/file/uploadOne.html")
	public void uploadOne(@Param("filetype") String filetype,HttpServletRequest req){
		req.setAttribute("filetype", filetype);
		req.setAttribute("allowExtensions", FileType.getSuffixname(upload, filetype));

	}

 

如上所述,在限制文件上传类型的同时,还可以将文件分类保存在不同类型的目录下。

201312 月25

CDMA iPhone 4 iOS7.0.4/7.1 越狱并解决联系人括号问题的办法

1、先使用evasi0n7越狱;
2、进入Cydia按照提示更新Cydia到最新版;
3、Cydia软件源添加 http://apt.weiphone.com;
4、Cydia搜索afc2add选择威锋源安装;
5、使用同步助手或其他工具浏览iPhone文件系统:
浏览至目录 /System/Library/PrivateFrameworks/AppSupport.framework
用压缩包里的 Default.phoneformat 替换之,重启后即可。
为防万一最好备份此文件。

绿色evasi0n7及Default.phoneformat 文件下载:http://pan.baidu.com/s/1nt16UgD

 

PS:CDMA iPhone 4 用了快三年了,有些毛病,坚持到明年iPhone6再换。。

201312 月20

Nutz:通过URL路径查找对应的类及入口函数

由于Nutz是零配置的,所以通过URL找到处理类以及跳转的页面,就显得很麻烦,不方便维护。

于是,我在大神兽的指导下,实现如下功能:在项目启动时,将URL路径、类、方法、以及跳转页面写入项目中的一个文件中,方便查看。

@UrlMappingBy(value=UrlMappingSet.class)
public class MainModule { 
}

在Nutz入口类,加入 @UrlMappingBy。

UrlMappingSet.java 实现在 /WEB-INF/ 目录下生成 paths.txt 文件,记录路径,文件格式如下:
       QQ截图20131220094847
UrlMappingSet.java 源码:
package com.hits.core;

import java.io.File;
import java.lang.reflect.Method;

import org.nutz.lang.Files;
import org.nutz.lang.Lang;
import org.nutz.mvc.ActionChainMaker;
import org.nutz.mvc.ActionInfo;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.NutConfig;
import org.nutz.mvc.impl.UrlMappingImpl;

/**
 * 类描述: 创建人:Wizzer 联系方式:www.wizzer.cn 创建时间:2013-12-19 下午10:36:17
 * 
 * @version
 */
public class UrlMappingSet extends UrlMappingImpl {
	private static int count = 0;

	public void add(ActionChainMaker maker, ActionInfo ai, NutConfig config) {
		super.add(maker, ai, config);
		printActionMappingThis(ai);

	}

	protected void printActionMappingThis(ActionInfo ai) {

		String[] paths = ai.getPaths();
		StringBuilder sb = new StringBuilder();
		if (null != paths && paths.length > 0) {
			sb.append(paths[0]);
			for (int i = 1; i < paths.length; i++)
				sb.append(",").append(paths[i]);
		} else {
			throw Lang.impossible();
		}
		sb.append("\n");
		// 打印方法名
		Method method = ai.getMethod();
		String str;
		if (null != method)
			str = String.format("%-30s : %-10s", Lang.simpleMetodDesc(method),
					method.getReturnType().getSimpleName());
		else
			throw Lang.impossible();

		sb.append("\t" + ai.getModuleType().getName());
		sb.append("\n\r");
		sb.append("\t" + str);
		sb.append("\n");
		String filepath = Mvcs.getServletContext().getRealPath("/WEB-INF/")
				+ "/paths.txt";
		File f = new File(filepath);
		if (count == 0) {
			Files.write(f, sb.toString());
		} else {

			Files.appendWrite(f, sb.toString());
		}
		count++;
	}
}
201312 月15

Nutz:自定义取值区间(可分页查询)

使用示例:

			/**
			你可以自定义取数据区间的值,如下:

			offset=0,count=5     取0到5的记录
			offset=5,count=10    取5到15的记录
			page=3, offset=15,count=20   取15到35的记录
			**/
			int offset=0;
			int count=5;
			ExplicitPager pager=new ExplicitPager(offset,count);
			QueryResult file=daoCtl.listPage(dao, Oa_doc_file.class, cri,pager);

 

ExplicitPager 类源码:

package com.hits.common.page;

import org.nutz.dao.pager.Pager;

/** 
 * 类描述: 
 * 创建人:Wizzer 
 * 联系方式:www.wizzer.cn
 * 创建时间:2013-12-12 下午3:16:21 
 * @version 
 */
public class ExplicitPager extends Pager {

	private static final long serialVersionUID = 1L;
	int offset;
	int count;

	public ExplicitPager(int offset, int count) {
		super();
		this.offset = offset;
		this.count = count;
	}

	public void setOffset( int offset) {
		this.offset = offset;
	}

	public void setSelectCount( int count) {
		this.count = count;
	}

	@Override
	public int getPageSize() {
		return count;
	}

	@Override
	public int getOffset() {
		return offset;
	}

}

分页源代码(可参考上一篇文章,实现自定义SQL多表分页区间取值):

	/**
	 * 根据查询条件分页,返回封装好的QueryResult对象
	 * 
	 * @param dao
	 * @param obj
	 * @param cnd
	 * @param pager
	 * @return
	 */
	public <T> QueryResult listPage(Dao dao, Class<T> obj, Condition cnd,Pager pager) { 
		List<T> list = dao.query(obj, cnd, pager);
		pager.setRecordCount(dao.count(obj, cnd));// 记录数需手动设置
		return new QueryResult(list, pager);
	}
	/**
	 * 根据自定义SQL分页,返回封装好的QueryResult对象
	 * @param dao
	 * @param sql
	 * @param pager
	 * @return
	 */
        public  QueryResult listPageSql(Dao dao, Sql sql, Pager pager) {
		if(pager==null)
			return null;
		pager.setRecordCount(Daos.queryCount(dao, sql.getSourceSql()));// 记录数需手动设置
		sql.setPager(pager);
		sql.setCallback(Sqls.callback.records());
		dao.execute(sql);  
		return new QueryResult(sql.getList(Map.class), pager);
	}
201312 月15

Nutz:自定义SQL多表多字段分页查询方法

easyui.datagrid 调用示例:

    @At
    @Ok("raw")
    public String test(@Param("page") int curPage, @Param("rows") int pageSize){
    	Sql sql=Sqls.create("select a.name,b.loginname From sys_unit a,sys_user b where a.id=b.unitid");
    	return daoCtl.listPageJsonSql(dao, sql, curPage, pageSize);
    }

源代码:

	/**
	 * 根据自定义SQL分页,返回封装好的QueryResult对象
	 * @param dao
	 * @param sql
	 * @param curPage
	 * @param pageSize
	 * @return
	 */
	public  QueryResult listPageSql(Dao dao, Sql sql, int curPage,int pageSize) {
		Pager pager = dao.createPager(curPage, pageSize);

		pager.setRecordCount(Daos.queryCount(dao, sql.getSourceSql()));// 记录数需手动设置
		sql.setPager(pager);
		sql.setCallback(Sqls.callback.records());
		dao.execute(sql); 
		return new QueryResult(sql.getList(Map.class), pager);
	}
	/**
	 * 根据自定义SQL分页,返回封装好的 Easyui.datagrid JSON
	 * @param dao
	 * @param sql
	 * @param curPage
	 * @param pageSize
	 * @return
	 */
	public String listPageJsonSql(Dao dao, Sql sql, int curPage, int pageSize) {
            Pager pager = dao.createPager(curPage, pageSize);
            pager.setRecordCount(Daos.queryCount(dao, sql.toString()));// 记录数需手动设置
            sql.setPager(pager);
            sql.setCallback(Sqls.callback.records());
            dao.execute(sql);
            Map<String, Object> jsonobj = new HashMap<String, Object>();
            jsonobj.put("total", pager.getRecordCount());
            jsonobj.put("rows", sql.getList(Map.class));
            return Json.toJson(jsonobj);
       }
201311 月26

Nutz开发日志

计划基于Nutz开发一套全新的系统管理-权限框架。界面演示:/?p=2586
之前尝试Nutz做过一个demo,但有很多不足,比如没有做防SQL注入、不能兼容多数据库、列表没有实现Ajax等。

基于多年来开发过程接触的各式各样的框架,想整一套开发方便UI简洁的框架,要求有如下功能:
1.开发简便、框架结构清晰
2.性能优越、兼容主流数据库、兼容各版本浏览器
3.UI简洁、开发简单、主流JS插件集成、全Ajax
4.集成权限框架、单点登陆、登陆日志、操作日志
5.工作流引擎、表单自定义
6.代码生成器

JS引入:
jquery-1.10.2.min.js
ueditor-1.2.6.1
My97Datepicker-4.8 Beta4
zDialog-2.0
ztree-3.5.15

框架引入:
Nutz-1.49.r2
log4j-1.2.17
json-1.0
c3p0-0.9.1.2
classes12
mysql-connector-java-5.1.14
ojdbc14
slf4j-api-1.6.1
slf4j-log4j12-1.6.1
sqljdbc4
velocity-1.7
velocity-tools-2.0
velocity-tools-generic-2.0
velocity-tools-view-2.0
json-lib-2.4-jdk15
ezmorph-1.0.6
commons-beanutils-1.7.0
commons-chain-1.1
commons-collections-3.2
commons-digester-1.8
commons-lang-2.2
commons-logging-1.1
commons-validator-1.3.1
待更新。

——————————————————–
在Eclipse中处理图片,需要引入两个包:
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
报错:
Access restriction: The type JPEGImageEncoder is not accessible due to restriction on required library C:\Java\jre1.6.0_07\lib\rt.jar

此时解决办法:
Eclipse默认把这些受访问限制的API设成了ERROR。只要把Windows-Preferences-Java-Complicer-Errors/Warnings里面的Deprecated and restricted API中的Forbidden references(access rules)选为Warning就可以编译通过。

—————————————————————
Nutz开发说明:

您一定了解SSH,还有Strust1+Velocity框架

2013年11月30日(星期六) 晚上7:03给我写信

您一定了解SSH,还有Strust1+Velocity框架。前者配置文件实在是太多,多层架构,开发一个功能模块涉及很多类、很多关系,一方面上手非常难另外开发效率也不高。后者随着技术发展,对前端技术支持不太友好,比如AjaxJS框架等,需要中间跳转页面进行输出,再者也需要配置。

根据项目开发中实际遇到的各种问题,研究各种框架优缺点之后,决定选择Nutz国产开源框架作为基础来构建本开发框架。选择Nutz有如下优点:

1URL“零”配置

您再也不用为繁琐的配置文件烦恼了,Nutz-Mvc使用全注解的方式来封装URL,使用简单的@At 在类或方法上实现URL映射。

2、灵活的多数据源支持

通过Nutz.Ioc您只要在数据库配置文件datasource.json中配置对象,如dao1dao2,那么在Action类中,

@Inject

    protected Dao dao1;

@Inject

protected Dao dao2;

即可使用daoCtl的方法直接操作这两个数据库。daoCtl里集成了常用的添加、修改、查询、分页等方法。

3、功能强大的视图

Nutz-Mvc使用@Ok @Fail 注解,来实现执行成功或失败后的输出,可以外部重定向、内部重定向、返回字符串、返回JSON等等,总之您想要什么结果就能给您返回什么,再也不用使用单独的Action类来封装JSON数据了,您想要随时都可以有。

4、功能强大的数据库操作

Nutz.Dao封装了常用的数据库操作,减少自定义SQL的编写,提高开发效率和安全性,通过工具类

Cnd.where(“loginname”, “=”,
user.getLoginname())

        Sql sql = Sqls.create("DELETE FROM $table WHERE name=@name");

sql.vars().set(“table”,”t_abc”);

sql.params().set(“name”,”Peter”);

中的sql.params().set() 方法,可以有效的防止SQL注入。

更多使用方法请参考本目录下的nutz开发手册。

5Velocity

对于大家常用的Velocity模板语言,本框架也进行了整合。

req.setAttribute(“menulist”,
menulist);

将对象输出到页面,在页面上即可直接使用模板语言输出。

 

UI表现层上面,本次框架也进行了调整,原则上支持纯Ajax开发。后台集成jQuery EasyUIzDialogEasyUI.DataGridztreeMy97DatePickerJS组件。

1、兼容主流浏览器

您再也不用考虑浏览器兼容性问题,只要您的JS全部使用jQuery来编写,那么还用担心什么呢,本框架目前在IE6/IE7/IE8/IE9/IE10/IE11ChromeFrieFox360测试通过。

2zDialog的使用更加简便

通过使用Ajax以及对zDialog的优化,您再也不需要写中间页面进行页面跳转了。您可以在弹出框的父页面进行弹出表单的提交,在父页面写弹出框按钮的事件。

通过$DW.$(“#form1”).serialize();  获取弹出窗口表单内容

         $DW.$Z(“name”).focus();     操作弹出框内容,赋值等

         $D.close();                                  关闭弹出窗口

让我们看一个完成的示例:

function addSave(){ 



if($DW.Verify.hasError()){


return;


}


jQuery.ajax({


type:
‘POST’,


url :
“/private/sys/unit/addSave” ,


data :
$DW.$(“#form1”).serialize(),


success :
function (res) {


if(res!=””){


$D.close();


Dialog.alert(“
添加成功!“);


initTree();


view(res);


}else{


Dialog.alert(“
添加失败!“);


}



return
false;


},


fail :
function(res) {


Dialog.alert(“
系统错误?!”);


}


});


}

3Ajax分页支持

集成jQuery.Easyui.DataGrid,从后台封装的JSON数据格式,到前台展示,分页查询从来没有如此简便过。

daoCtl.getListPageJson()
封装了easyui.datagrid分页所需格式数据,更不用您手动写烦人的JSON了。

4、权限控制到按钮

您只需要在JS中使用

              Page.initBtn();


$!initBtn

即可控制页面按钮是否可用,当然,在此之前,您需要在资源菜单管理中添加按钮ID,在角色管理中对用户分配按钮权限。

 

 

201311 月22

Can’t get hostname for your address

skip-name-resolve #加上这一个属性

201311 月20

新鲜出炉:百度电视云V3.2.2评测

电视型号:创维4K ,39E780U

分辨率:4096×2160

网络链接:有线链接,20M电信光纤

USB:外接2T移动硬盘

1、图片

打开速度很快,无bug,建议按时间倒序排序(或按菜单选择排序方式)。

2、音乐

网盘音乐:列表空白,什么也没有?网盘里明明有几百首。(已绑定帐号)

在线音乐:音乐不能播放。播放不了会自动跳转到下一首,自动跳了几首都不能播放后,按“返回”到歌曲界面,按任何键都没有反应,等半天只有强制关机。歌曲界面“播放”和按钮背景错位。

3、电影

网盘视频:和音乐一样,列表空白啥也木有。加载半天没任何反应,退不出界面,只有按“主页”强制退出。

电影:介绍界面上“收藏”按钮文字和背景错位。《金刚》电影不能播放,其他电影能播放但按“菜单”没有像其他客户端那样有清晰度选项,视频清晰度比其他TV客户端都低。播放比较流畅。按“返回”退出播放,弹出的确定或取消,“确定”文字不显示。

电视剧:介绍界面上的“选集”功能设计的不好,占用了这个屏幕,不像其他客户端那样合理方便。“收藏”按钮文字和背景错位。按“返回”退出播放,弹出的确定或取消,“确定”文字不显示。看《我们结婚吧》半小时左右,中途毫无征兆的自动退出播放,到介绍界面去了。

视频播放:不知道连续长时间播放会不会出现其他TV客户端出现的短暂音画不同步的情况?按这么低的清晰度来说,应该不会出现吧,但队友4K电视来说,这些视频分辨率也太寒碜了。另外能增加电视直播功能、英雄联盟比赛直播等功能就太好了。

4、以下是运行截图

2013-11-20 185200
电视上已安装的软件。
2013-11-20 185221

百度电视云主界面。

 

2013-11-20 185250

设置界面。

 

2013-11-20 185456

照片,速度很快。

 

2013-11-20 185834

网盘音乐空白。

 

2013-11-20 185906

在线音乐按钮太小,错位。

 

2013-11-20 185932

 

在线音乐不能播放,返回后死机。

 

2013-11-20 190303

 

网盘视频空白。

 

2013-11-20 190549

 

在线视频界面。

 

2013-11-20 190605

 

电影介绍,收藏按钮有问题。

 

2013-11-20 190825

 

退出播放,按钮变形。

 

2013-11-20 191510

电视剧介绍界面选集覆盖了整个屏幕,设计不太合理。

 

201311 月20

SSH:id元素中的generator

<id>元素中的<generator>用来为该持久化类的实例生成唯一的标识,hibernate提供了很多内置的实现。

Increment:由hibernate自动递增生成标识符,用于为long, short或者int类型生成唯一标识。
identity :由底层数据库生成标识符(自动增长),返回的标识符是 long, short 或者int类型的。
sequence :hibernate根据底层数据库序列生成标识符,返回的标识符 是long, short或者 int类型的。

hilo     :使用一个高/低位算法来高效的生成long, short 或者int类型的标识符。
uuid.hex :用一个128-bit的UUID算法生成32位字符串类型的标识符。
native   :根据底层数据库的能力选择identity, sequence 或者hilo中的一个。
assigned :让应用程序在save()之前为对象分配一个标示符。
foreign :使用另外一个相关联的对象的标识符。和<one-to-one>联合一起使用。

201311 月19

Java 加Filter过滤器的时候一定记得设置编码格式

package web;

import web.sys.Globals;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

public class SqlFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
	req.setCharacterEncoding("GBK");
        res.setCharacterEncoding("GBK");
        //获得所有请求参数名
        Enumeration params = req.getParameterNames();

        String sql = "";
        while (params.hasMoreElements()) {
            //得到参数名
            String name = params.nextElement().toString();
            //得到参数对应值
            String[] value = req.getParameterValues(name);
            for (int i = 0; i < value.length; i++) {
                sql = sql + value[i];
            }
        }

        //有sql关键字,跳转到error.html
        if (sqlValidate(sql)) {
            res.sendRedirect("/"+Globals.APP_BASE_NAME+"/include/404error.html");
            //String ip = req.getRemoteAddr();
        } else {
            chain.doFilter(req, res);
        }
    }

    //效验
    protected static boolean sqlValidate(String str) {
        str = str.toLowerCase();//统一转为小写
        String badStr = "and|exec|execute|insert|create|drop|table|from|grant|use|" +
                "group_concat|column_name|information_schema.columns|table_schema|" +
                "where|select|delete|update|order|by|*|chr|char" +
                "|declare|;|--|+|,|%|#";//过滤掉的sql关键字,可以手动添加  qxmore000400010009
        String[] badStrs = badStr.split("\\|");

        for (int i = 0; i < badStrs.length; i++) {
            if (str.indexOf(badStrs[i]) != -1) {

                return true;
            }
        }
        return false;
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void destroy() {
        //throw new UnsupportedOperationException("Not supported yet.");
    }
}
201311 月7

JS+CSS 幻灯片下载效果非常好

QQ截图20131107163030

使用时候注意两处,
一是图片宽度、高度要固定,
二是如果图片宽度变了,那s.js也要改成一样的。

下载地址:

http://pan.baidu.com/s/1eiYiz

201311 月7

三星GT-P6200 4.0.4国行固件下载

文件名称:Samsung-Updates.com-GT-P6200-CHN-P6200ZCLPR-1363586771

国行Android 4.0.4 版本,,,逛了一圈论坛,要么收费(鄙视之),要么不能用会变砖,,自己从官网翻,墙下到的固件,分享一下。

 

http://yun.baidu.com/s/1h6JRR

 

 

 

201311 月4

创维4K电视 TV客户端使用体验及汇总下载

目前市面上的智能电视、4K电视,多采用Android 4.0以上版本系统,这给电视上安装各类应用提供了可能。

下面我来像大家介绍一下,截至目前各类软件的使用体验,当然软件是逐步升级完善的,文中提到的缺陷可能在下个版本解决。

以下介绍已通过楼主亲身体验测试,电视型号:创维39E780U  4K电视 Android 4.0系统。

Top 1 :优酷机顶盒客户端

下载地址:http://mobile.youku.com/index/wireless

推荐理由:运行稳定、支持各类电视遥控器、登陆后可与电脑手机同步观看记录、自动跳过片头片尾、自动播放到上一次观看时间点。运行稳定是最重要的一点,搜索功能强大,视频内容和网站同步。

缺点:可能是电视处理器和内存较低的原因,偶尔会出现音画不同步停顿几秒后就正常的情况。这个情况在我的电视上,不同的客户端软件都出现,应该是电视的原因。

Top 2 :转屏助手

下载地址:http://tt.showkey.tv/

推荐理由:非常方便,支持电驴、磁力链地址, BT种子上传,在线视频网站地址云端转码,无需下载。

缺点:播放种子视频和迅雷云播关联很大,要是迅雷云播服务器挂了(一般不会挂),就不能播放了。对有些视频支持不是太好,可能会自动退出播放。

Top 3 :电驴大全HD

下载地址:http://www.verycd.com/app/

推荐理由:运行稳定,集成各视频网站资源,做了比较合理的分类梳理,可以看海贼王。

Top 4 :PPTV聚力 HD

下载地址:http://yun.baidu.com/s/19rfzm

推荐理由:运行稳定,内容丰富。

缺点:菜单图标较大,浏览查找内容没优酷那么方便。官方不提供TV版本下载,说是集成在盒子里,所以需要提取软件。

Top 5:搜狐视频TV版

下载地址:http://yun.baidu.com/s/19rfzm

推荐理由:运行稳定。

缺点:切换菜单有点慢,视频内容较少。

Top 6 :MoreTV

下载地址:http://www.moretv.com.cn/plus/view.php?aid=22

推荐理由:视频资源丰富。

缺点:界面菜单没有优酷设计的那么合理。

Top 7:小鹰直播

下载地址:http://eagleapp.tv/

推荐理由:电视直播资源丰富,视频源可用率较高。

缺点:有些电视台清晰度较低,画质和卫星锅差不多。

Top 8:泰捷视频、阿狸直播

下载地址:泰捷视频  http://www.togic.com/livetv 阿狸直播 http://down.7po.com/alizhibo/1-1.html

推荐理由:电视直播资源丰富。

缺点:在我的电视上运行不太稳定,直播资源打不开的时候会导致电视死机重启。

其他运行稳定的视频软件:

1、BiliBili弹幕网客户端 http://www.bilibili.tv/

其他目前运行不稳定、还不成熟但具有潜力的视频软件:

1、迅雷云播:http://vip.xunlei.com/app/android/?dlxunlei

迅雷的资源丰富大家都很清楚,和转屏助手一样方便(转屏助手是基于迅雷云播的资源做的),官方没有出TV专用客户端。

2、百度云电视:http://tv.baidu.com/

百度的电视客户端,百度大家都知道,但百度云电视目前是小作坊产品,使用还不方便,BUG也很多。希望后期能发力,潜力巨大。

3、爱奇艺影视、PPTV等视频网站客户端,没有还没有针对电视的版本,待发展有,但是集成在盒子里布公开下载地址可恶啊,爱奇艺和创维搞创维盒子,PPTV被苏宁收购也搞集成,比起优酷来真是倒退。

4、乐视TV客户端,从乐视盒子中破解提取出,菜单和播放器不能自适应4K屏幕,首页视频不能播放的bug。

 

PS:2013-11-07 更新内容

 

从乐视盒子提取出的TV客户端不能自适应4K分辨率,还有bug。

搜狐的TV客户端做得比较稳定,但加载慢而且内容不丰富。

PPTV HD内容和速度都不错,但界面菜单似乎设计的不太好,不方便找内容。还是优酷给力。

以上三个客户端下载地址:

http://yun.baidu.com/s/19rfzm

 

 2013-11–11 更新:

终于找到一款更好的直播软件——VST全聚合,不用忍受泰捷视频的死机、小鹰直播的视频源无法打开等问题,还有几个高清频道,比如湖南卫视HD。问题是除了看电视还行,其他的功能都是鸡肋,迅雷云播获取不到列表、电影电视基本上打开就报错退出。。就不能有一款如优酷运行那么稳定的直播软件么。。。

201310 月29

电信光纤猫 中兴F660 超级密码破解方法

cmd
telnet 192.168.1.1
root
root
sendcmd 1 DB p UserInfo

看telecomadmin后面8位数,就是超级密码
201310 月24

Discuz! X2.5 修改管理员密码的方法

在网站根目录下的子目录uc_server/data中打开找到文件config.inc.php
以及 config/config_global.php、config/config_ucenter.php (这两个如果没有下面代码可以不用修改)
找到类似以下代码:
define(‘UC_FOUNDERPW’, ’256955f2e034sad74f0e2953572ea360′);
define(‘UC_FOUNDERSALT’, ’217804′);

然后用以下代码替换
define(‘UC_FOUNDERPW’, ’047099adb883dc19616dae0ef2adc5b6′);
define(‘UC_FOUNDERSALT’, ’311254′);

修改完后,Ucenter创始人的密码就变为: 123456789

201310 月24

创维4K电视:ROOT局域网远程安装软件教程

楼主电视型号:创维39E780U  4K电视

软件下载地址:

http://pan.baidu.com/s/1BZZAY

经过验证,优酷TV客户端、Bilibili 弹幕网客户端  最稳定,但后者列表字体过小。
MoreTV、小鹰直播、泰捷电视,大部分情况下可用,但如果视频打不开容易把电视搞死机。

百度云、迅雷云播,目前还不稳定,百度云不能播放,迅雷云很卡。
1 2 3

优酷TV客户端下载:

http://mobile.youku.com/index/wireless  优酷机顶盒客户端

使用教程:

1、将电视和路由器通过有线或者是无线连接到同一个路由器(路由的LAN 口IP建议使用默认如果不是默认请改为192.168.1.1 或192.168.0.1

2、电脑端运行安装工具 无标题-1.jpg ,该工具可以在广东分公司服务部技术联盟群下载。

3、双击打开工具

无标题-2.jpg

4、查看电视端获取到网络的IP 在光标闪烁处输入IP(电视IP 查看在电视的网络设置)回车键确认

无标题-3.jpg

5、输入1 回车注意提示如果显示unable to 就表示没有连接上电视需要检查一下网络连接如果没有问题可以再重新连接一次

无标题-4.jpg

6、如果连接成功会出现下图所示connected to 输入1 回车键确认

无标题-5.jpg

7、如果连接正常程序会自动调出APK 安装器,点击设备管理,选中你的电视。

无标题-6.jpg

8、将下载好的APK 文件拖入APK 安装器如果安装到机身内存请去掉优先安装到SD 卡上。建议外接优盘或SD 卡安装到外挂存储。

无标题-7.jpg

9、安装过程中

无标题-8.jpg

10、安装完成就可以在电视我的应用里面出现刚才安装的应用程序也可以点击APK 安装器的立即运行电视端运行应用建议使用鼠标操作电视。左键确定右键退出。

无标题-9.jpg

11、建议电视安装一个安卓市场TV版,或者乐视TV 应用然后就可以在应用商场里面管理应用下载海量应用。

12、由于CPU 架构的不同和机器配置的差异。和应用的繁杂不保证所有程序都可以在电视上运行,ARM 架构的CPU 兼容的程序较多,同时安装的应用大多都是针对手机开发的。是否可以正常运行需要实践安装检验。

201310 月9

Java 数字图形验证码源码

package web.common.util;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import java.io.IOException;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author Wizzer.cn
 * @time   2012-9-13 上午10:54:04
 *
 */
public class ImageUtil extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private static final String CONTENT_TYPE = "image/jpeg;charset=GB2312";
	private static final String allcode[] = { "0", "1", "2", "3", "4", "5",
			"6", "7", "8", "9" };

	private static final Font mFont = new Font("Times New Roman", Font.BOLD, 18);// 设置字体

	public static Font IFont = new Font("宋体", Font.PLAIN, 18);// 设置字体

	public static int x = 10; // 坐标
	public static int y = 10;

	public void init() throws ServletException {
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType(CONTENT_TYPE);
		ServletOutputStream out = response.getOutputStream();
		getImage(out, request, response);
		out.close();
	}

	private void getImage(ServletOutputStream out, HttpServletRequest request,
			HttpServletResponse response) {
		try {

			HttpSession session = request.getSession(true);

			response.setContentType("image/gif");
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			int width = 60, height = 20;

			BufferedImage image = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_RGB); // 设置图片大小的
			Graphics gra = image.getGraphics();
			Random random = new Random();

			gra.setColor(getRandColor(200, 250)); // 设置背景色
			gra.fillRect(0, 0, width, height);

			gra.setColor(Color.black); // 设置字体色
			gra.setFont(mFont);

			// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到

			for (int i = 0; i < 100; i++) {
				gra.setColor(getRandColor(120, 220));
				x = random.nextInt(width);
				y = random.nextInt(height);
				int xl = random.nextInt(12);
				int yl = random.nextInt(12);
				gra.drawLine(x, y, x + xl, y + yl);
			}

			// 取随机产生的认证码(4位)
			String sRand = "";
			for (int i = 0; i < 4; i++) {
				String rand = allcode[random.nextInt(10)];
				sRand += rand;
				// 将认证码显示到图象中
				gra.setColor(new Color(20 + random.nextInt(110), 20 + random
						.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
				gra.drawString(rand, 13 * i + 6, 12 + random.nextInt(5));
			}
			session.setAttribute("ValidateCode", sRand);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(image);
			out.close();

		} catch (Exception e) {
			e.printStackTrace();

		}
	}

	static Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色

		Random random = new Random();
		if (fc > 255)
			fc = 255;
		if (bc > 255)
			bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

	public static Font getIFont() {
		return IFont;
	}

	public static void setIFont(Font IFont) {
		ImageUtil.IFont = IFont;
	}

	public static int getY() {
		return y;
	}

	public static void setY(int y) {
		ImageUtil.y = y;
	}

	public static int getX() {
		return x;
	}

	public static void setX(int x) {
		ImageUtil.x = x;
	}

}

若提示找不到包:

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

则做如下修改即可:

Eclipse 默认把这些受访问限制的API设成了ERROR。

只要把 Deprecated and restricted API中的Forbidden references(access rules) 选为Warning 就可以编译通过。

QQ截图20131009111758

201310 月8

自定义EditText实现信纸效果

自定义EditText实现信纸效果

作者:wtmdbf 

一、引言

用户在提交表单的时候,我们可能会希望展示一个美观的输入框,以提升用户体验。

二、效果

图片说明文字

三、实现细节

读者可以看到就是给EditText设置一个黄色的背景,然后给每一行添加一个下划线。为了看出不同,我们这里拿android提供的notepad这个demo的效果来做下比较,下面是notepad的截图
图片说明文字

从从上可以看出,notepad的下划线是在产生新的行以后才绘制出来的,为了读者阅读的方便,我把notepad的源码贴出来如下:

public static class LinedEditText extends EditText {
        private Rect mRect;
        private Paint mPaint;

        // This constructor is used by LayoutInflater
        public LinedEditText(Context context, AttributeSet attrs) {
            super(context, attrs);

            // Creates a Rect and a Paint object, and sets the style and color of the Paint object.
            mRect = new Rect();
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(0x800000FF);
        }

        /**
         * This is called to draw the LinedEditText object
         * @param canvas The canvas on which the background is drawn.
         */
        @Override
        protected void onDraw(Canvas canvas) {

            // Gets the number of lines of text in the View.
            int count = getLineCount();

            // Gets the global Rect and Paint objects
            Rect r = mRect;
            Paint paint = mPaint;

            /*
             * Draws one line in the rectangle for every line of text in the EditText
             */
            for (int i = 0; i < count; i++) {

                // Gets the baseline coordinates for the current line of text
                int baseline = getLineBounds(i, r);

                /*
                 * Draws a line in the background from the left of the rectangle to the right,
                 * at a vertical position one dip below the baseline, using the "paint" object
                 * for details.
                 */
                canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
            }

            // Finishes up by calling the parent method
            super.onDraw(canvas);
        }
    }

那是如何实现我所说的一开始就绘制好下划线的效果呢,在此之前,你需要了解如何在android中获得字体的高度,网上有很多,为了方便大家阅读特摘录如下,先看图:
图片说明文字
然后我们可以通过下面的代码获得字体大高度

Paint p = new Paint();  
p.setTextSize(50);  
p.setAntiAlias(true);  
FontMetrics fm = p.getFontMetrics();  
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);

读者了解了上面的知识点以后就可以,在看我是如何实现的。

基本思想是根据字体的高度,在view的对应位置上绘制好每条line,代码如下:

package com.example.customedittext;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.EditText;

public class CustomEditText extends EditText {

    private Paint mPaint;
    private int lines = 0;
    private float fontHeight = 0;
    private float leading = 0;

    public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initPaint();
    }

    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public CustomEditText(Context context) {
        super(context);
        initPaint();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.parseColor("#CDDCD5"));
        mPaint.setAntiAlias(true);
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        int lineHeight = getLineHeight();
        int viewHeight = getHeight();
        lines = viewHeight / lineHeight;
        setGravity(Gravity.TOP);
        float textSize = getTextSize();
        Paint paint = new Paint();
        paint.setTextSize(textSize);
        FontMetrics fontMetrics = paint.getFontMetrics();
        fontHeight = fontMetrics.descent - fontMetrics.ascent;
        leading = fontMetrics.leading;// leading == 0
        setBackgroundColor(Color.parseColor("#F8F6DF"));
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int count = getLineCount();
        if (count <= lines) {
            for (int i = 1; i < lines; i++) {

                canvas.drawLine(0, fontHeight * i + leading * i, getWidth(),
                        fontHeight * i + leading * i, mPaint);
            }
        } else {
            for (int i = 1; i < count; i++) {
                canvas.drawLine(0, fontHeight * i + leading * i, getWidth(),
                        fontHeight * i + leading * i, mPaint);
            }
        }
    }

}

四、存在的问题和遗留点

虽然最主要的效果已经实现了,但还有一些问题

  • 如何定义一个只能输入固定行数的EditText?
  • 细心的朋友会发现当输入的行数过多的时候会发现字体与横线的距离会发生偏差,原因是画出来的线不精确,如果按照android notepad那样绘制出来的线是精确的,但达不到我们一开始想要的那种效果,如何让我们的绘制更加精确,**热心的朋友如果知道或者有更好的方法的话,欢迎分享**?

原文作者: wtmdbf

原文地址: http://my.eoe.cn/readonly/archive/15757.html

20139 月24

Weblogic 数据入库时间晚8个小时

替换Weblogic 下 时区配置文件即可。

20138 月12

一直很安静……

 

忙着装修  忙着置办家当

新家暂时不能接宽带

于是  许久没更新网站了……