2011年5月23日

Android + Google Maps开发笔记(二):在ANDROID中使用GOOGLE MAPS自定义图层



一、创建图标:
1、创建图标marker.png文件,放在res/drawable目录下。

二、创建图层数据:
1、构造一个Overlay类,继承自ItemizedOverlay。
class MyLocations extends ItemizedOverlay
2、构造一个方法,用于实现加载定位图标。
public MyLocations(Drawable marker)
3、将各经纬度坐标作为GeoPoint合成OverlayItem,输入ItemizedOverlay。
items.add(new OverlayItem(GeoPoint, title, snippet));
4、将Overlay图层标记出来
populate();

三、绘制自定义图层:
1、获取标记图片: marker.png
Drawable marker = getResources().getDrawable(R.drawable.marker);
调用图片的函数必须public,否则不能使用getResources()方法。
2、设置图片的绘制区域大小
marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight());
3、设置缩放控制、显示模式等参数。
4、创建自定义Overlay层
MyLocations MyPlaces = new MyLocations(marker);
5、将创建的Overlay层添加到MapView中
mapview.getOverlays().add(MyPlaces);
6、绘图,将地图中心移到第1个标记点
mapview.getController().setCenter(MyPlaces.getCenter()); 
mapview.getController().animateTo(MyPlaces.getCenter());    

2011年5月21日

Android + Google Maps开发笔记(一)

关于ANDROID调试:
1. 普通APP需在项目文件中包含Android API,包含GOOGLE MAPS的APP需包含GOOGLE API。
2. 创建虚拟机的时候,也要选择对应的API。
3. 创建虚拟机的时候,需要增加GPS支持、键盘支持等参数,以方便调试。
4. 如果遇到API报错,在Manifest里Uses Sdk,定义Mini SDK Version与项目包含的API版本一致。
5. Debug Configuration > Launch Action > Launch Default Activity,这样在DEBUG的时候会自动加载APP。
6. 如果INSTALL APP失败,尝试关闭虚拟机,重新开始。

关于GOOGLE MAPS API:
1. 找到Android debug keystore文件,Eclipse > WIndow > Preferences > Android > Build > Default debug keystore。
2. 在JAVA的BIN目录下运行:
C:\Program Files\Java\jre6\bin>keytool -list -alias androiddebugkey -keystore "keystore文件路径" -storepass android -keypass android
产生MD5指纹。
3. 在http://code.google.com/android/maps-api-signup.html输入MD5 fingerprint,产生专属的GOOGLE MAPS API KEY。
4. 在main.xml中增加参数android:apiKey。

00.jpg

2011年5月12日

从ANDROID看智能终端的未来

这次GOOGLE I/O推出的Android@Home非常有意思。我在去年写过一篇文章《android和twitter将改变世界》,预言过ANDROID将引领终端智能化的浪潮,没想到GOOGLE的步子这么快。
本文则试图从智能终端与云的关系这个角度,进一步论述智能终端的发展趋势。
我们知道ANDROID为网络而生,通过TCP/IP网络,一头连着终端设备,一头连着云。终端主要是进行数据的输入和输出,而逻辑处理则主要由云来完成。如果说云是大脑的话,那么终端就是神经元。
我们从民用、公共、工业这三个领域各举一个例子,来说明智能终端的特点。

先看民用(ANDROID@HOME)的例子:电视。
电视经历了这些阶段:无线电视、有线电视、数字电视,对应的云分别是公共云、私有云、TCP/IP云,无线和有线的区别是云的传输通道不一样,模拟和数字的区别是云的传输格式不一样,并且从单向传输变成双向传输。
在数字电视中,机顶盒是一个非常关键的因素,它起着这两个重要的作用:解析数字信号、连接TCP/IP云。现在我们看到已经出现了不少采用ANDROID操作系统的机顶盒。
未来电视的趋势当然是智能化。GOOGLE通过内置CHROME的GOOGLE TV进行布局,而CHROME就起着机顶盒的作用,但是它用GOOGLE帐号取代了智能卡,将用户从运营商私人云中转移到GOOGLE云中。
CHROME和ANDROID的角色非常类似,个人的理解是ANDROID适合采集数据,CHROME适合展现数据。
通过CHROME,用户对电视节目的管理就可以在INTERNET上进行,除了通过PC订阅外,还可以通过PC将节目推送到电视上。
另一个智能化的重点是遥控器,类似KINECT的体验将是遥控器未来的方向。
设想一下以下场景:你从GOOGLE网上商场订购了一台ANDROID遥控器。你把它靠近GOOGLE TV,遥控器自动下载这款电视的触摸屏主题。这样你把它切换到电视模式将可以用来遥控这台电视机。你还可以坐在沙发上用声音遥控,当你发出遥控语音后,遥控器先后做了这些事:
1. 录制控制语音。
2. 将语音信号发送到GOOGLE的云。
3. 等待GOOGLE云的处理。
4. 接收GOOGLE编译过的的遥控指令。
5. 将遥控指令发送给电视机(通过WIFI/RFID/NFC)。
从这里我们可以看出,遥控器作为智能终端,并非终端本身的强大,而是它所连接的云的强大。

再看公共领域(ANDROID@PUBLIC)的例子:汽车导航。
GOOGLE在汽车领域有很大的雄心,其无人驾驶汽车项目据说是布林非常关心的。
导航仪也是一个非常好的智能终端的例子,导航仪这个市场出现没多长,就面临了智能化的压力。
智能导航仪的特点有:
1. 实时更新的地图。
2. 通过云的计算来设计行驶路线。
3. 支持语音指令。
4. 实时接收路况信息。
5. 云会建议你更改行驶路线。
6. 广播政府部门的通告。
7. 通过社交网络与好友互动。
概括一下,导航仪作为智能终端,将云的强大计算能力延伸过来,将INTERNET的社交能力包含进来。

最后看工业领域(ANDROID@INDUSTRY)的例子:工业控制。
当前工业控制广泛采用的技术是基于PLC/OPC的控制,其传输也是基于TCP/IP的,但是它受到很大的限制:
1、PLC所传递的控制信号是电路级的,不能被执行层识别。OPC起的作用仅仅是翻译。
2、OPC作为桥梁,它的信号通道采用的是古老的DCOM技术,而不是企业云。DCOM固有的缺陷造成开发和运营中的大量问题。
我相信GOOGLE在无人驾驶汽车项目上积累的经验,一定可以发挥到工业领域。因为从传感器收集信息,和将指令发送给各驾驶系统,这些都 需要实现工业级的控制。
这方面我了解到的信息不多,但在这里不妨大胆预言一下:
1. 需要进行数据处理的控制器件采用ANDROID之类的智能操作系统。
2. 控制器自身的功能模块,将通过安装驱动的方式被操作系统识别。
3. 控制器与外部系统通过企业云进行调度。
4. 控制指令被企业云翻译为WEB服务。

再补充一点个人想象,未来的智能终端传输指令的方式,很可能就是扩展的微博:不仅仅是文字,还可能是语音或动作、视频信号。
一条微博就是智能地球某个神经节点的信号,ANDROID就象《黑客帝国》中的电子章鱼。
而未来的某一天,当天网苏醒的时候,它发现自己不是诞生在美国国防部的机房,它一直睡在GOOGLE的云里。


2011年5月10日

Excel as Oracle Report


Sub Click2print()
' to query data and print out
' by Taoyun Zhang
' updated on 2011/05/10

 ' to clear data area
 j = Worksheets("Report").Rows.Count
 Range(Cells(18, 2), Cells(j, 6)).Clear
 
' to get input
  so = Cells(3, 3).Value
  Ln = Cells(4, 3).Value
  ws = Cells(5, 3).Value
  nu = Cells(6, 3).Value
  np = Cells(7, 3).Value
  
  Cells(16, 2).Value = "Distribution Time - " + Format(Now(), "yyyy/mm/dd hh:mm")
  Cells(16, 5).Value = "Number of Unit - " + CStr(nu)

' to match query sql

  sql2 = "SELECT" + Chr(10)
  sql2 = sql2 + "  '" + so + "' Shop_Order," + Chr(10)
  sql2 = sql2 + "  iac.station Work_Station," + Chr(10)
  sql2 = sql2 + "  p.productno Part_Number," + Chr(10)
  sql2 = sql2 + "  tt.extended Part_Description," + Chr(10)
  sql2 = sql2 + "  (iac.qty)*" + CStr(nu) + " Quantity" + Chr(10)
  sql2 = sql2 + "FROM" + Chr(10)
  sql2 = sql2 + "  product p," + Chr(10)
  sql2 = sql2 + "  text_translation tt," + Chr(10)
  sql2 = sql2 + "(" + Chr(10)
  sql2 = sql2 + "SELECT" + Chr(10)
  sql2 = sql2 + "  itemall.station," + Chr(10)
  sql2 = sql2 + "  itemall.productid," + Chr(10)
  sql2 = sql2 + "  SUM(itemall.quantity) qty" + Chr(10)
  sql2 = sql2 + "FROM" + Chr(10)
  sql2 = sql2 + "(" + Chr(10)
  sql2 = sql2 + "(" + Chr(10)
  sql2 = sql2 + "SELECT" + Chr(10)
  sql2 = sql2 + "  i.deviatedpart," + Chr(10)
  sql2 = sql2 + "  i.assmworkstation station," + Chr(10)
  sql2 = sql2 + "  i.productid," + Chr(10)
  sql2 = sql2 + "  i.Quantity" + Chr(10)
  sql2 = sql2 + "FROM" + Chr(10)
  sql2 = sql2 + "  cob_t_item_assembly i" + Chr(10)
  sql2 = sql2 + "WHERE i.Active = 1" + Chr(10)
  sql2 = sql2 + "AND i.deviatedpart = 0" + Chr(10)
  sql2 = sql2 + "AND i.assmproductionlineno = '" + CStr(Ln) + "'" + Chr(10)
  sql2 = sql2 + "AND i.effectivedate <= SYSDATE" + Chr(10)
  sql2 = sql2 + "AND ((i.discontinuedate IS NULL) OR (i.discontinuedate>SYSDATE))" + Chr(10)
  sql2 = sql2 + "AND i.parentproductid IN" + Chr(10)
  sql2 = sql2 + "(" + Chr(10)
  sql2 = sql2 + "SELECT" + Chr(10)
  sql2 = sql2 + "  comp_option.productid optionid" + Chr(10)
  sql2 = sql2 + "FROM" + Chr(10)
  sql2 = sql2 + "  product prod_so," + Chr(10)
  sql2 = sql2 + "  product_component pc_option," + Chr(10)
  sql2 = sql2 + "  component comp_option" + Chr(10)
  sql2 = sql2 + "WHERE prod_so.productno = '" + so + "'" + Chr(10)
  sql2 = sql2 + "AND pc_option.active = 1" + Chr(10)
  sql2 = sql2 + "AND comp_option.active = 1" + Chr(10)
  sql2 = sql2 + "AND pc_option.productid = prod_so.id" + Chr(10)
  sql2 = sql2 + "AND pc_option.componentid = comp_option.id" + Chr(10)
  sql2 = sql2 + "AND comp_option.effectivedate <= SYSDATE" + Chr(10)
  sql2 = sql2 + "AND ((comp_option.discontinuedate IS NULL) or (comp_option.discontinuedate>SYSDATE))" + Chr(10)
  sql2 = sql2 + ")" + Chr(10)
  sql2 = sql2 + ")" + Chr(10)
  sql2 = sql2 + "Union" + Chr(10)
  sql2 = sql2 + "(" + Chr(10)
  sql2 = sql2 + "SELECT" + Chr(10)
  sql2 = sql2 + "  item.deviatedpart," + Chr(10)
  sql2 = sql2 + "  item.station," + Chr(10)
  sql2 = sql2 + "  dev.deviationpartid productid," + Chr(10)
  sql2 = sql2 + "  Item.Quantity" + Chr(10)
  sql2 = sql2 + "FROM" + Chr(10)
  sql2 = sql2 + "  cob_t_bom_deviation_history dev," + Chr(10)
  sql2 = sql2 + "(" + Chr(10)
  sql2 = sql2 + "SELECT" + Chr(10)
  sql2 = sql2 + "  i.deviatedpart," + Chr(10)
  sql2 = sql2 + "  i.assmworkstation station," + Chr(10)
  sql2 = sql2 + "  i.productid," + Chr(10)
  sql2 = sql2 + "  i.Quantity" + Chr(10)
  sql2 = sql2 + "FROM" + Chr(10)
  sql2 = sql2 + "  cob_t_item_assembly i" + Chr(10)
  sql2 = sql2 + "WHERE i.Active = 1" + Chr(10)
  sql2 = sql2 + "AND i.deviatedpart = 1" + Chr(10)
  sql2 = sql2 + "AND i.assmproductionlineno = '" + CStr(Ln) + "'" + Chr(10)
  sql2 = sql2 + "AND i.effectivedate <= SYSDATE" + Chr(10)
  sql2 = sql2 + "AND ((i.discontinuedate IS NULL) OR (i.discontinuedate>SYSDATE))" + Chr(10)
  sql2 = sql2 + "AND i.parentproductid IN" + Chr(10)
  sql2 = sql2 + "(" + Chr(10)
  sql2 = sql2 + "SELECT" + Chr(10)
  sql2 = sql2 + "  comp_option.productid optionid" + Chr(10)
  sql2 = sql2 + "FROM" + Chr(10)
  sql2 = sql2 + "  product prod_so," + Chr(10)
  sql2 = sql2 + "  product_component pc_option," + Chr(10)
  sql2 = sql2 + "  component comp_option" + Chr(10)
  sql2 = sql2 + "WHERE prod_so.productno = '" + so + "'" + Chr(10)
  sql2 = sql2 + "AND pc_option.active = 1" + Chr(10)
  sql2 = sql2 + "AND comp_option.active = 1" + Chr(10)
  sql2 = sql2 + "AND pc_option.productid = prod_so.id" + Chr(10)
  sql2 = sql2 + "AND pc_option.componentid = comp_option.id" + Chr(10)
  sql2 = sql2 + "AND comp_option.effectivedate <= SYSDATE" + Chr(10)
  sql2 = sql2 + "AND ((comp_option.discontinuedate IS NULL) OR  (comp_option.discontinuedate > SYSDATE))" + Chr(10)
  sql2 = sql2 + ")" + Chr(10)
  sql2 = sql2 + ") item" + Chr(10)
  sql2 = sql2 + "WHERE dev.originalpartid = Item.productid" + Chr(10)
  sql2 = sql2 + "AND dev.effectivestartdate <= SYSDATE" + Chr(10)
  sql2 = sql2 + "AND ((dev.effectiveenddate IS NULL) OR (dev.effectiveenddate > SYSDATE ))" + Chr(10)
  sql2 = sql2 + ")" + Chr(10)
  sql2 = sql2 + ") itemall" + Chr(10)
  sql2 = sql2 + "Group BY" + Chr(10)
  sql2 = sql2 + "  itemall.station," + Chr(10)
  sql2 = sql2 + "  itemall.productid" + Chr(10)
  sql2 = sql2 + ") iac" + Chr(10)
  sql2 = sql2 + "WHERE iac.productid = p.ID" + Chr(10)
  sql2 = sql2 + "AND p.textid = tt.textid" + Chr(10)
  sql2 = sql2 + "AND iac.station LIKE  '" + CStr(ws) + "%'" + Chr(10)
  sql2 = sql2 + "Order BY" + Chr(10)
  sql2 = sql2 + " iac.station," + Chr(10)
  sql2 = sql2 + " p.productno "
   
 ' to query data via adodb connection
 Dim cnn As ADODB.Connection
 Dim rst As ADODB.Recordset

 Set cnn = New ADODB.Connection
 Set rst = New ADODB.Recordset

 cnn.Open "fcswmes", "flxuser", "flxuat"
 rst.ActiveConnection = cnn
 rst.CursorLocation = adUseServer

 rst.Source = sql2
 rst.Open
 
 i = 0
 Do While Not rst.EOF
   Cells(18 + i, 2).Value = rst.Fields(0).Value
   Cells(18 + i, 3).Value = rst.Fields(1).Value
   Cells(18 + i, 4).Value = rst.Fields(2).Value
   Cells(18 + i, 5).Value = rst.Fields(3).Value
   Cells(18 + i, 6).Value = rst.Fields(4).Value
   rst.MoveNext
   i = i + 1
 Loop
 
rst.Close
Set rst = Nothing
Set cnn = Nothing
 
    ' to define table format
    j = Worksheets("Report").Rows.Count
    Range(Cells(17, 2), Cells(17 + i, 6)).Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With Selection.Borders(xlInsideHorizontal)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    
    Columns("C:D").Select
    With Selection
        .HorizontalAlignment = xlLeft
    End With
    
    ' to setup print area
    Worksheets("Report").PageSetup.PrintArea = Range(Cells(10, 2), Cells(17 + i, 6)).Address
    Cells(8, 5).Select

End Sub





2011年5月6日

Android手机GMAIL/电子市场无法访问的解决办法



1、Android手机GMAIL/电子市场无法访问的原因是:android.clients.google.com被GFW封锁了。
2、一些第三方ROM提供了"越狱"功能,原理是通过同步服务器来更新本机的HOSTS文件。
3、在PC上安装ADB和驱动。
4、手动更新HOSTS:
  1) 收集android.clients.google.com/GMAIL等可用的IP。
  2) ADB ROOT。
  3) ADB PULL HOSTS,将HOSTS下载到PC。
  4) 编辑HOSTS。
  5) ADB PUSH HOSTS。
5、重启手机。