amp@java

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            99 隨筆 :: 0 文章 :: 228 評(píng)論 :: 0 Trackbacks

          #

          JMF(Java Media Framework)是Java平臺(tái)使用攝像頭、麥克風(fēng)等媒體設(shè)備的應(yīng)用程序框架,但到了2.1.1e就不再更新,在Windows 7 X64上還能正常運(yùn)行,只是安裝的界面讓你感覺(jué)回到了Windows98的時(shí)代。


          不過(guò)年代久遠(yuǎn)的東西,雖然還能用,但可能會(huì)遇到一些奇怪的問(wèn)題,折騰了兩個(gè)月,發(fā)現(xiàn)了兩個(gè)比較大的問(wèn)題:

          第一個(gè)是在Windows 7 x64上提示攝像頭初始化失敗的問(wèn)題。這個(gè)問(wèn)題很奇怪,電腦剛開(kāi)機(jī)的時(shí)候可以順利找到一次攝像頭并正常操作,但是第二次就會(huì)提示攝像頭初始化失敗。有人提出的解決方法是安裝一個(gè)叫ManyCamera的程序,這個(gè)程序可以把一個(gè)攝像頭供多個(gè)程序同時(shí)使用,其實(shí)就等于中間加了一層轉(zhuǎn)換,效果會(huì)有點(diǎn)差別,免費(fèi)版還會(huì)加上水印,要求比較高的人可能會(huì)不爽,但是目前找不到其他辦法。

          第二個(gè)是在程序中找不到攝像頭,不光找不到攝像頭,其他媒體設(shè)備通通找不到,使用以下語(yǔ)句:
          vector = CaptureDeviceManager.getDeviceList ( null )
          按照文檔說(shuō)明是返回所有媒體設(shè)備,但每次vector都是null。
          在Eclipse中運(yùn)行又能正常,導(dǎo)出成jar之后運(yùn)行就會(huì)找不到攝像頭。
          原因在于找不到j(luò)mf.properities文件,該文件包含所有檢測(cè)到的媒體設(shè)備的信息,最簡(jiǎn)單的解決方法就是把JMF安裝目錄下lib子目錄中的jmf.properties文件復(fù)制到最后運(yùn)行的jar所在的目錄,不過(guò)如果攝像頭改過(guò)的話,重新檢測(cè)后要把新的文件復(fù)制到j(luò)ar目錄,因?yàn)闄z測(cè)到的媒體設(shè)備信息都會(huì)存放在JMF安裝目錄里面的jmf.properties文件里。

          StackOverflow里面有個(gè)人對(duì)這個(gè)問(wèn)題解釋得比較清楚:
          http://stackoverflow.com/questions/8768142/java-capturedevicemanagergetdevicelist-is-empty


          雖然問(wèn)題解決了,但是還是不明白為何在Eclipse中可以正常運(yùn)行,導(dǎo)出jar后運(yùn)行卻找不到攝像頭,即使把JMF所有jar和lib目錄都加入系統(tǒng)的CLASSPATH環(huán)境變量里還是不行。


          另外,JMF安裝程序會(huì)自動(dòng)把它的jar和lib目錄加入系統(tǒng)的%CLASSPATH%環(huán)境變量,但是如果你卸載了再重新安裝到其他目錄,并不會(huì)改變%CLASSPATH%的值,需要手動(dòng)修改。不過(guò)這個(gè)環(huán)境變量似乎沒(méi)啥用處。
          最好不要把JMF安裝到默認(rèn)的Program Files目錄,可能會(huì)運(yùn)行不了,安裝到短目錄會(huì)比較保險(xiǎn),它似乎還是只認(rèn)Dos時(shí)代的8.3目錄結(jié)構(gòu),但偏偏又默認(rèn)安裝到Program Files里面。
          posted @ 2014-07-01 10:33 amp@java 閱讀(7304) | 評(píng)論 (0)編輯 收藏

          其實(shí)我也搞不懂Windows的域,反正能用就行了。
          但是最近有一臺(tái)客戶端的時(shí)間改不了,總是提示特權(quán)級(jí)不夠,按理說(shuō)應(yīng)該是組策略限制了,但是我把那臺(tái)計(jì)算機(jī)從包含該組策略的OU中移出來(lái),還是不行,這就奇怪了,難道組策略不是指針對(duì)OU里面的成員的嗎?百思不得其解啊,最后只能在BIOS里面把時(shí)間改了。
          今天發(fā)現(xiàn)我自己的電腦設(shè)置不了屏幕保護(hù),也是組策略限制了,然后把我的用戶和計(jì)算機(jī)都移出了組策略應(yīng)用的OU,結(jié)果發(fā)現(xiàn)還是設(shè)置不了,這下肯定是組策略的應(yīng)用上有問(wèn)題了。
          搜索了半天發(fā)現(xiàn)有個(gè)叫rsop.msc的管理工具,可以看到某用戶在某計(jì)算機(jī)上應(yīng)用的組策略,結(jié)果發(fā)現(xiàn)我還是應(yīng)用之前的組策略,但是計(jì)算機(jī)配置和用戶配置前面都有個(gè)紅叉,右鍵-屬性-錯(cuò)誤信息里面顯示:
          Title
          由于下面列出的錯(cuò)誤,組策略結(jié)構(gòu) 失敗。

          系統(tǒng)找不到指定的路徑。

          注意: 由于 GP Core 失敗,其它組策略組件沒(méi)有一個(gè)處理了它們的策略。因此,其它組件的狀態(tài)信息不可用。
          好像是有某個(gè)組策略找不到,所以不能應(yīng)用的意思。
          然后想起來(lái)在域名下面有個(gè)“新建組策略”,但是沒(méi)有做過(guò)任何配置,應(yīng)該是有人手賤點(diǎn)了一下新建按鈕加進(jìn)去的,于是把它刪除,還是不行。
          重啟了一下客戶端,居然好了,時(shí)間也可以改了,屏幕保護(hù)也可以改了,一切都按計(jì)劃進(jìn)行。


          莫名其妙~~
          posted @ 2014-06-23 16:11 amp@java 閱讀(1363) | 評(píng)論 (0)編輯 收藏

          現(xiàn)在的手機(jī)攝像頭動(dòng)輒幾百萬(wàn)上千萬(wàn)像素,如果電腦需要用到攝像頭又沒(méi)有的話,不妨用手機(jī)的攝像頭代替。

          我是在做一個(gè)電腦二維碼識(shí)別器的時(shí)候,因?yàn)樵瓉?lái)的攝像頭太差,從而想到用一臺(tái)淘汰的Android手機(jī)來(lái)代替。

          這類應(yīng)用應(yīng)該不少,我首先找到的是一個(gè)叫DraoidCam的應(yīng)用,裝好之后發(fā)現(xiàn)免費(fèi)版沒(méi)法調(diào)整分辨率,于是放棄之。

          然后又找到了一個(gè)國(guó)內(nèi)做的免費(fèi)軟件,叫魅色,非常簡(jiǎn)單,支持USB和WiFi連接方式,如果是USB連接的話,打開(kāi)USB調(diào)試模式之后,運(yùn)行電腦的客戶端,手機(jī)上就自動(dòng)裝上了App并且自動(dòng)運(yùn)行,可以調(diào)整分辨率,不過(guò)最高只有640*480,幀率不到10,不過(guò)已經(jīng)能夠滿足我的需求了。

          然后就可以像普通PC攝像頭一樣使用了,在JMF里面也能找到,于是就可以被Java調(diào)用了。經(jīng)測(cè)試,效果比原來(lái)的PC攝像頭好多了。

          軟件主頁(yè):http://www.libfetion.org/meise/
          posted @ 2014-06-05 15:35 amp@java 閱讀(1739) | 評(píng)論 (4)編輯 收藏

               摘要: TabActivity在API 13(Android 3.2)被標(biāo)記為過(guò)期,需要使用Fragment來(lái)實(shí)現(xiàn),F(xiàn)ragment是Android 3.0引入的一個(gè)概念,主要就是為了適應(yīng)各種不同的屏幕大小(手機(jī)、平板電腦)。Android 4.1發(fā)布時(shí),google還發(fā)布了一個(gè)Android Support v4的包,用于Android 1.6以上的系統(tǒng)兼容新的特性,其中包括Fragment。為了在低于...  閱讀全文
          posted @ 2012-12-27 19:07 amp@java 閱讀(15663) | 評(píng)論 (0)編輯 收藏

          SQL Server 2000的導(dǎo)入導(dǎo)出功能還是不錯(cuò)的,支持各種各樣的數(shù)據(jù)庫(kù),但是卻有好多奇怪的bug,不能直接操作,幾乎每一步都要上網(wǎng)搜索,最后搞定了,一定要記下來(lái):
          1、在同一臺(tái)電腦上裝好SQL Server 2000的客戶端和Oracle 10g的客戶端,并分別設(shè)置好到源數(shù)據(jù)庫(kù)(SQL Server 2000數(shù)據(jù)庫(kù))和目標(biāo)數(shù)據(jù)庫(kù)(Oracle 數(shù)據(jù)庫(kù))的連接,兩個(gè)數(shù)據(jù)庫(kù)都有圖形界面的企業(yè)管理器,很容易設(shè)置好;
          2、在控制面板-管理工具-數(shù)據(jù)源里添加一個(gè)DSN,驅(qū)動(dòng)程序選擇類似“Oracle in OraClient10g_home1”的,確定之后輸入Data Source Name(隨意),Description(隨意),TNS Service Name(在企業(yè)管理器里設(shè)置好的連接名),User ID(用戶名),然后按Test Connection測(cè)試是否連接成功,成功之后點(diǎn)OK;
          3、在SQL Server 2000的企業(yè)管理器里,在任意一個(gè)表上點(diǎn)右鍵,所有任務(wù),導(dǎo)出數(shù)據(jù),在目的里選擇“Oracle in OraClient10g_home1”,用戶/系統(tǒng)DSN里面就會(huì)出現(xiàn)剛才設(shè)置好的DSN名字,選中,然后輸入用戶名密碼,點(diǎn)兩次下一步就會(huì)出現(xiàn)選擇源表和視圖對(duì)話框
          4、這里要注意的是,勾上源中的某個(gè)表,在目的里面就會(huì)出現(xiàn)"用戶名"."表名"的默認(rèn)選項(xiàng),如果你剛才使用的Oracle用戶名是小寫的話,這里也會(huì)是小寫,一定要改成大寫,否則會(huì)提示該用戶名不存在

          目的也可以使用Microsoft OLE DB Provider for Oracle,在屬性里面設(shè)置服務(wù)器名稱為Oracle的TNS名稱,用戶名和密碼輸入Oracle用戶名和密碼,測(cè)試連接通過(guò)即可,后面的步驟都一樣。

          如果出現(xiàn)以下錯(cuò)誤:

          OLE DB 提供程序 'MSDAORA' 報(bào)錯(cuò)。

          [OLE/DB provider returned message: 未找到 Oracle 客戶端和網(wǎng)絡(luò)組件。這些組件是由 Oracle 公司提供的,是 Oracle 8i (或更高) 客戶軟件安裝的一部分。

           

          在安裝這些組件之前,將無(wú)法使用此提供程序。]

          OLE DB 錯(cuò)誤跟蹤[OLE/DB Provider 'MSDAORA' IDBInitialize::Initialize returned 0x80004005:  


          就要修改注冊(cè)表,有人已經(jīng)作出了詳細(xì)的修改說(shuō)明,在這里可以看到:
          http://www.cnblogs.com/autumn/articles/splinkedserver.html

          我把那個(gè)表也貼在這里:
          Oracle Client  Microsoft Windows NT、
          Oracle Microsoft Windows 95、
          Client Windows 98 和 Windows 98 SE
          Microsoft Windows 2000/XP/2003
          7.x [HKEY_LOCAL_MACHINE\SOFTWARE
          \Microsoft\TransactionServer\Local Computer\My Computer]
          "OracleXaLib"="xa73.dll"
          "OracleSqlLib"="SQLLib18.dll"
          "OracleOciLib"="ociw32.dll

           

          [HKEY_LOCAL_MACHINE\SOFTWARE
          Microsoft\MSDTC\MTxOCI]
          "OracleXaLib"="xa73.dll"
           "OracleSqlLib"="SQLLib18.dll"
           "OracleOciLib"="ociw32.dll"
           
          8.0 [HKEY_LOCAL_MACHINE\SOFTWARE
          \Microsoft\Transaction Server
          \Local Computer\My Computer]
          "OracleXaLib"="xa80.dll"
          "OracleSqlLib"="sqllib80.dll"
          "OracleOciLib"="oci.dll"
           
          [HKEY_LOCAL_MACHINE\SOFTWARE
           \Microsoft\MSDTC\MTxOCI]
           "OracleXaLib"="xa80.dll"
           "OracleSqlLib"="sqllib80.dll"
          "OracleOciLib"="oci.dll"
          8.1 [HKEY_LOCAL_MACHINE\SOFTWARE
          \Microsoft\Transaction Server
          \Local Computer\My Computer]
          "OracleXaLib"="oraclient8.dll"
          "OracleSqlLib"="orasql8.dll"
          "OracleOciLib"="oci.dll"
           
          [HKEY_LOCAL_MACHINE\SOFTWARE
           \Microsoft\MSDTC\MTxOCI]
          "OracleXaLib"="oraclient8.dll"
          "OracleSqlLib"="orasql8.dll"
          "OracleOciLib"="oci.dll"
           
          9.0 [HKEY_LOCAL_MACHINE\SOFTWARE
          \Microsoft\Transaction Server
          \Local Computer\My Computer]
          "OracleXaLib"="oraclient9.dll"
          "OracleSqlLib"="orasql9.dll"
          "OracleOciLib"="oci.dll"
          [HKEY_LOCAL_MACHINE\SOFTWARE
           \Microsoft\MSDTC\MTxOCI]
          "OracleXaLib"="oraclient9.dll"
          "OracleSqlLib"="orasql9.dll"
          "OracleOciLib"="oci.dll"
           
          10.0 [HKEY_LOCAL_MACHINE\SOFTWARE
          \Microsoft\Transaction Server
          \Local Computer\My Computer]
          "OracleXaLib"="oraclient10.dll"
          "OracleSqlLib"="orasql10.dll"
          "OracleOciLib"="oci.dll"
          [HKEY_LOCAL_MACHINE\SOFTWARE
           \Microsoft\MSDTC\MTxOCI]
          "OracleXaLib"="oraclient10.dll"
          "OracleSqlLib"="orasql10.dll"
          "OracleOciLib"="oci.dll"
           
          posted @ 2012-04-28 10:22 amp@java 閱讀(2577) | 評(píng)論 (0)編輯 收藏

          當(dāng)讀寫二進(jìn)制文件,或者要把非標(biāo)準(zhǔn)長(zhǎng)度的整數(shù)與標(biāo)準(zhǔn)長(zhǎng)度的整數(shù)互相轉(zhuǎn)換時(shí),就要用到大量的位操作,雖然看起來(lái)很簡(jiǎn)單,實(shí)際上里面卻有很多細(xì)節(jié)很容易出錯(cuò)。

          首先,Java有些標(biāo)準(zhǔn)跟C/C++是不同的:

          1、Java采用高字節(jié)在前的方式讀寫數(shù)據(jù),例如要把一個(gè)4字節(jié)的int數(shù)值寫入文件時(shí),它是按照從高字節(jié)到低字節(jié)的順序?qū)懭氲模x取的時(shí)候也是這樣讀出來(lái)。
          而C/C++則采用平臺(tái)相關(guān)的方式,在Windows平臺(tái)采用低字節(jié)在前的方式,在Linux/Unix平臺(tái)則采用高字節(jié)在前的方式。
          如果Java要讀取C/C++創(chuàng)建的二進(jìn)制文件,就要注意這個(gè)問(wèn)題,最好先搞清楚原來(lái)的文件是采用哪種方式創(chuàng)建的。網(wǎng)絡(luò)通信也要注意。

          2、Java沒(méi)有無(wú)符號(hào)數(shù),無(wú)論byte,short,int,long都是有符號(hào)整數(shù),而C/C++有個(gè)unsigned關(guān)鍵字可以設(shè)置一個(gè)數(shù)值為無(wú)符號(hào)數(shù)。

          3、Java的整數(shù)基本數(shù)據(jù)類型就是byte,short,int,long這幾個(gè),長(zhǎng)度分別為1,2,4,8字節(jié),C/C++可以用typedef定義各種數(shù)據(jù)類型。

          第二,Java是采用補(bǔ)碼來(lái)存放整數(shù)的。
          有時(shí)候覺(jué)得補(bǔ)碼的定義有些奇怪,實(shí)際上可以這樣理解:

          把一個(gè)整數(shù)從0一直往上加1,加到溢出就變成了負(fù)數(shù)的最小值,然后再繼續(xù)加1,最后又能回到0,實(shí)際上就是一個(gè)輪回。
          例如一個(gè)byte類型的整數(shù),一共有8位,能表示256個(gè)數(shù)值,采用補(bǔ)碼的話數(shù)值范圍就是-128~127,表示方法如下:
          0        0000 0000
          1        0000 0001
          .
          .
          126    0111 1110
          127    0111 1111
          -128   1000 0000
          -127   1000 0001
          .
          .
          -1       1111 1111
          0         0000 0000

          第三、不同長(zhǎng)度的整數(shù)轉(zhuǎn)換。
          如果是從較短的數(shù)轉(zhuǎn)成較長(zhǎng)的數(shù),很簡(jiǎn)單,如果是正數(shù)就在高字節(jié)補(bǔ)0,如果是負(fù)數(shù)就在高字節(jié)補(bǔ)1。
          例如byte的127轉(zhuǎn)為short的127:
          byte:0111 1111
          short:0000 0000 0111 0111
          byte的-127轉(zhuǎn)為short的-127
          byte:1000 0001
          short:1111 1111 1000 0001
          如果是從較長(zhǎng)的數(shù)轉(zhuǎn)成較短的數(shù),實(shí)際上就是把高位都截?cái)嗔耍赞D(zhuǎn)出來(lái)的數(shù)值可能完全不是一回事了。
          例如short的256轉(zhuǎn)為byte:
          short:0000 0001 0000 0000
          byte: 0000 0000
          把256變成了0
          short的-255轉(zhuǎn)成byte:
          short:1111 1111 0000 0001
          byte:0000 0001
          把-255變成了1

          第四、位運(yùn)算操作符及它們的優(yōu)先級(jí)
          Java的位運(yùn)算操作符包括:~非,|按位或,&按位與,^按位異或,<<左移,>>右移,>>>右移左側(cè)補(bǔ)0
          各種運(yùn)算符的優(yōu)先級(jí)如下表所示:
          優(yōu)先級(jí)
          運(yùn)算符
          結(jié)合性
          1
          () [] .
          從左到右
          2
          ! +(正) -(負(fù)) ~ ++ --
          從右向左
          3
          * / %
          從左向右
          4
          +(加) -(減)
          從左向右
          5
          << >> >>>
          從左向右
          6
          < <= > >= instanceof
          從左向右
          7
          == !=
          從左向右
          8
          &(按位與)
          從左向右
          9
          ^
          從左向右
          10
          |
          從左向右
          11
          &&
          從左向右
          12
          ||
          從左向右
          13
          ?:
          從右向左
          14
          = += -= *= /= %= &= |= ^= ~= <<= >>= >>>=
          從右向左
          根據(jù)該表可以看到,位運(yùn)算操作符的優(yōu)先級(jí)各有不同,分別為:
          1、~
          2、>> << >>>
          3、&
          4、^
          5、|
          另外需要特別注意的是,除了~,其他位運(yùn)算操作的優(yōu)先級(jí)都低于加減,所以要記得以下語(yǔ)句是返回32而不是7!
          1<<2+3
          還有就是&、^、|的優(yōu)先級(jí)都是低于邏輯操作符的,因此下面的語(yǔ)句會(huì)編譯出錯(cuò),幸好Java不像C那樣對(duì)所有大于1的值都認(rèn)為是真,否則下面的語(yǔ)句也能編譯通過(guò),但可能與你的意圖不太一樣,可能調(diào)試半天才發(fā)現(xiàn)。
          if(3&1>0)
          如果記不清楚,還是按照你的意圖加上括號(hào)最保險(xiǎn)。

          第五、字節(jié)數(shù)組與整數(shù)之間的轉(zhuǎn)換
          為了把一個(gè)整數(shù)存入文件,或者從文件中讀取一個(gè)整數(shù),需要經(jīng)常在字節(jié)數(shù)組和整數(shù)之間轉(zhuǎn)換,這個(gè)過(guò)程要用到大量的位運(yùn)算。
          首先需要記住的是,在參與所有運(yùn)算前,Java都會(huì)把byte、short類型的值都轉(zhuǎn)換成int,然后再對(duì)轉(zhuǎn)換后的int進(jìn)行操作。例如下面的語(yǔ)句會(huì)編譯出錯(cuò):
          byte a=10,b=20,c;
          c=a+b;

          因?yàn)閍和b在相加前都被轉(zhuǎn)成了int,最后得到的結(jié)果是個(gè)int類型的值,如果要賦給byte類型的c,必須顯式地進(jìn)行類型轉(zhuǎn)換,即把第二句改為:
          c=(byte)(a+b)

          這一點(diǎn)很關(guān)鍵,因?yàn)閷?duì)于一個(gè)最高位為1的byte類型的整數(shù)(負(fù)數(shù)),在運(yùn)算之前它會(huì)被強(qiáng)制轉(zhuǎn)換成int類型,根據(jù)上面所說(shuō)的第三點(diǎn),其實(shí)就是往前面的三個(gè)高字節(jié)補(bǔ)上1,這樣一來(lái),它在參與位運(yùn)算的過(guò)程中,就不僅僅是它本身的8個(gè)bit參與了,實(shí)際上連前3個(gè)字節(jié)的24個(gè)bit(均為1)也參與了。例如有一個(gè)整數(shù)i=1082163328,它的二進(jìn)制表示為:
          01000000 10000000 10000000 10000000
          分為4個(gè)字節(jié)存儲(chǔ),除了第一個(gè)字節(jié)是正數(shù)外,其余3個(gè)字節(jié)均為負(fù)數(shù)。假如用a代表最高字節(jié)的值,用b代表其他三個(gè)字節(jié)的值,如果按照通常的理解,你可能會(huì)這樣得到i的值:
          i=(a<<24)+(b<<16)+(b<<8)+b

          如果a和b都是正數(shù),上面的等式是成立的,但是在這個(gè)例子里,卻是錯(cuò)的,因?yàn)樯鲜街械腶和b都已經(jīng)被強(qiáng)制轉(zhuǎn)換成了int類型再參加運(yùn)算,實(shí)際上
          a=00000000 00000000 00000000 01000000
          b=11111111 11111111 11111111 10000000
          i=01000000 00000000 00000000 00000000+11111111 10000000 00000000 00000000+11111111 11111111 10000000 00000000+11111111 11111111 11111111 10000000
          最后得到的結(jié)果是1065320320,不是原來(lái)的值了。
          為了不讓byte在強(qiáng)制轉(zhuǎn)換成int的過(guò)程加入了我們不想要的高位1,我們需要把它跟0xff進(jìn)行與操作,i的值應(yīng)該這樣運(yùn)算:
          = ( ( a& 0xff ) << 24 ) +( ( b & 0xff ) << 16 ) + ( ( b & 0xff ) << 8 ) + ( b & 0xff )

          注意,因?yàn)?amp;和<<的優(yōu)先級(jí)都低于+,所以上面的括號(hào)是不能少的。不過(guò)由于跟0xff與操作之后,其余24位都變成了0,因此可以把+改為|操作,因?yàn)槿魏沃蹬c0進(jìn)行或操作都得到本身:
          = ( a & 0xff ) << 24 | ( b & 0xff ) << 16 | ( b & 0xff ) << 8 | ( b & 0xff )

          由于<<的優(yōu)先級(jí)高于|,所以省了一些括號(hào)。最高字節(jié)可以不與0xff進(jìn)行與操作,因?yàn)樗D(zhuǎn)換成int后左邊增加的3個(gè)字節(jié)都在左移24位時(shí)被去掉了:
          = a << 24 | ( b & 0xff ) << 16 | ( b & 0xff ) << 8 | ( b & 0xff )


          把int轉(zhuǎn)為字節(jié)數(shù)組的時(shí)候比較簡(jiǎn)單,直接右移截?cái)嗉纯桑?/span>
          byte[] b = new byte[4];
          b[0= (byte) (i >> 24);
          b[1= (byte) (i >> 16);
          b[2= (byte) (i >> 8);
          b[3= (byte) i;


          第六、非標(biāo)準(zhǔn)長(zhǎng)度整數(shù)的存儲(chǔ)和讀取
          假如有兩個(gè)變量,他們的值可以用12個(gè)bit來(lái)表示,如果我們用16bit的short類型來(lái)表示一個(gè)變量,那么兩個(gè)變量就需要4個(gè)字節(jié),而實(shí)際上它們只需要3個(gè)字節(jié)就能表示出來(lái),如果存儲(chǔ)空間比較有限,寫入文件時(shí)可以把它們存放在3個(gè)字節(jié)里面,但是讀寫過(guò)程就需要進(jìn)行轉(zhuǎn)換。
          在內(nèi)存里,它們都是標(biāo)準(zhǔn)的數(shù)據(jù)類型:
          short a,b;

          寫入文件時(shí),我們用第一個(gè)字節(jié)和第二個(gè)字節(jié)的前半部分來(lái)表示a,把第二個(gè)字節(jié)的后半部分和第三個(gè)字節(jié)來(lái)表示b,即:
          1:xxxx xxxx
          2:xxxx yyyy
          3:yyyy yyyy
          x和y都表示一個(gè)bit,分別用來(lái)存放a和b。寫入時(shí)先把a(bǔ)和b轉(zhuǎn)為字節(jié)數(shù)組:
          byte[] out = new byte[3];
          out[
          0= (byte) ( a >> 4 );//把a(bǔ)的高8位放在第一個(gè)字節(jié)
          out[1= (byte) ( a << 4 );//先把a(bǔ)左移四位,在右邊補(bǔ)上4個(gè)0,第二個(gè)字節(jié)的高4位就是a的低4位了,第二個(gè)字節(jié)的高4位已經(jīng)生成,低4位還是0
          out[1|= (byte) ( b >> 8 & 0x0f );//b右移8位,并與0x0f進(jìn)行與操作,實(shí)際上就只保留了b的高4位,并且是在字節(jié)的低4位上,跟第二步得到的字節(jié)進(jìn)行或操作,就生成了第二個(gè)字節(jié)
          out[2= (byte) b;//把b的高4位截?cái)嗑偷玫搅说?位
          然后再把這個(gè)字節(jié)數(shù)組寫入文件,就可以用3個(gè)字節(jié)表示兩個(gè)整數(shù)了。
          讀取:
          =(short)( (out[0& 0xff<< 4 | ( out[1& 0xf0 )>>4);
          = (short)((out[1& 0x0f<< 8 | ( out[2& 0xff));
          posted @ 2012-04-08 16:56 amp@java 閱讀(1860) | 評(píng)論 (2)編輯 收藏

          AdMob是往手機(jī)應(yīng)用程序里添加廣告的最流行的方式,Android程序基本都是靠這個(gè)賺錢。看文檔似乎很簡(jiǎn)單,但是操作起來(lái)卻不是那么回事,今天搞了一上午才弄明白怎么正確添加,網(wǎng)上搜索到的資料都不適合最新的SDK。

          按照AdMob的官方文檔,很簡(jiǎn)單,只要把AdMob的開(kāi)發(fā)包jar放到Build Path的Libraries里面就行了,這樣做編譯是沒(méi)問(wèn)題的,但是一運(yùn)行就會(huì)出錯(cuò),提示
          java.lang.NoClassDefFoundError:com.google.ads.AdView
          這是因?yàn)镚oogle最近更新了ADT到17.0,改變了項(xiàng)目依賴的檢測(cè)方式,官方的說(shuō)明在這里,不過(guò)看得不是很懂。有人用圖形的方式標(biāo)了出來(lái),容易理解一些,看這里。如果不求甚解,就把剛才放到Build Path里面的jar移除,直接在項(xiàng)目目錄下建立一個(gè)libs目錄,然后把那個(gè)jar文件放進(jìn)去就行了。

          AdMob SDK也更新到了4.3.1,網(wǎng)上搜索到的在XML文件里面設(shè)置AdView屬性的方法也已過(guò)時(shí),現(xiàn)在不需要建立attrs.xml文件,直接增加一個(gè)
          xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
          就可以在AdView標(biāo)簽里面設(shè)置ads開(kāi)頭的屬性了,關(guān)于xml設(shè)置AdView屬性的官方文檔隱藏得比較深,沒(méi)有在目錄中列出來(lái),只能在其他文檔里面的鏈接里進(jìn)去,在這里
          另外,按照官方說(shuō)明,要在AndroidManifest.xml里面添加一個(gè)Activity的聲明:
              <activity android:name="com.google.ads.AdActivity"
                        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
          后面那個(gè)屬性android:configChanges的最后兩個(gè)值screenSize|smallestScreenSize是在Android 3.2后面才增加的,這兩個(gè)值必須填上去,否則運(yùn)行的時(shí)候會(huì)報(bào)錯(cuò)。如果你使用的SDK是3.2以下的,識(shí)別不了這兩個(gè)值,編譯也不會(huì)報(bào)錯(cuò)。因此你的項(xiàng)目必須使用Android 3.2以上的SDK,也就是項(xiàng)目根目錄下的project.properties文件里面的屬性target的值必須是android-13以上,例如
          target=android-15
          但是可以在AndroidManifest.xml里面設(shè)置android:minSdkVersion和android:targetSdkVersion為比13低的值,這樣就不需要安裝Android 3.2以上的手機(jī)或平板來(lái)運(yùn)行這個(gè)程序,實(shí)際上AdMob支持Android 1.5以上的系統(tǒng),只是開(kāi)發(fā)需要更高版本的SDK而已。


          這次折騰讓我真正體會(huì)到Android更新得實(shí)在太快了,連官方的文檔都來(lái)不及更新,開(kāi)發(fā)人員只能自己摸索總結(jié),幸好有強(qiáng)大的搜索工具,只要你遇到的問(wèn)題不是第一個(gè),就會(huì)有人找到解決方案。



          posted @ 2012-03-25 19:23 amp@java 閱讀(3728) | 評(píng)論 (7)編輯 收藏

          SWT里TableEditor的作用是可以在表格里面顯示一些控件,例如列表、按鈕等,有時(shí)候是根據(jù)表格的內(nèi)容在控件上顯示不同內(nèi)容的,如果更新了表格內(nèi)容,就要同時(shí)更新控件,但是表格內(nèi)容可以通過(guò)Table控件的removeAll()來(lái)清除,而表格中的控件則無(wú)法用這個(gè)方法清除,你調(diào)用Table的removeAll()方法,往表格里填入新內(nèi)容后,控件還是上次的控件,但是你一操作那些控件就會(huì)出異常,提示那些控件已經(jīng)disposed。

          解決方法是顯式地調(diào)用控件及TableEditor的dispose()方法,在你建立TableEditor的時(shí)候,把它的引用保存起來(lái),把里面的控件的引用也保存起來(lái),到整個(gè)表格需要的清除的時(shí)候,通過(guò)引用先把控件dispose掉,再把TableEditor也dispose掉,這樣整個(gè)表格的內(nèi)容就真正清除了。

          例如有一個(gè)表格名為table,里面的每一行都有3列,第一列是文本,第二列是Combo,第三列是Button,繪制表格的時(shí)候是這樣的:

          TableItem ti = new TableItem(table,SWT.NONE);
          ti.setText(
          0,"some string");
          te 
          = new TableEditor(table);
          Combo combo 
          = new Combo(table,SWT.NONE);
          controls.add(combo);
          te.setEditor(combo,ti,
          1);
          Button button 
          = new Button(table,SWT.NONE);
          controls.add(button);
          te.setEditor(button,ti,
          2);

          其中te和controls都是成員變量,te的類型是TableEditor,controls的類型是ArrayList<Control>。
          當(dāng)整個(gè)table要清除內(nèi)容時(shí),可以這樣:
          //刪除控件
          for(Control control:controls){
          control.dispose();
          }
          //刪除TableEditor
          te.dispose();
          //刪除文本
          table.removeAll();
          posted @ 2012-03-09 11:09 amp@java 閱讀(3867) | 評(píng)論 (0)編輯 收藏

          mars課程里關(guān)于Socket通信那一課說(shuō)那些程序只能在真機(jī)上運(yùn)行,模擬器模擬不了,實(shí)際上是可以的。
          Android模擬器是通過(guò)一個(gè)類似路由器的虛擬網(wǎng)絡(luò)層與電腦相連,可以看作模擬器是處于“內(nèi)網(wǎng)”當(dāng)中,每個(gè)模擬器都有自己的虛擬路由器,而且虛擬路由器的地址總是10.0.2.1,在模擬器看來(lái),電腦的地址是10.0.2.2,模擬器自己的地址是10.0.2.15,無(wú)論你啟動(dòng)多少個(gè)模擬器,對(duì)于模擬器來(lái)說(shuō)都是這樣的地址,模擬器之間不能直接通信。
          啟動(dòng)模擬器的時(shí)候,電腦會(huì)給模擬器分配兩個(gè)端口,通過(guò)這兩個(gè)端口,電腦就能操作模擬器。第一個(gè)啟動(dòng)的模擬器的端口是5554和5555,第二個(gè)是5556和5557,以此類推,最多可以同時(shí)啟動(dòng)32個(gè)模擬器。第一個(gè)端口(偶數(shù)端口)可以接受telnet連接,對(duì)模擬器進(jìn)行設(shè)置,第二個(gè)端口(奇數(shù)端口)則接受adb連接,可以用來(lái)調(diào)試。第一個(gè)端口可以在模擬器窗口的標(biāo)題欄看到,如下圖所示:

          5554表示端口號(hào),t表示模擬器名稱。
          實(shí)際上,這些端口也是電腦監(jiān)聽(tīng)的端口,在電腦上通過(guò)netstat可以看到本機(jī)正在監(jiān)聽(tīng)這些端口,因此通過(guò)telnet localhost 5554就能連上第一臺(tái)模擬器,連上之后通過(guò)help命令可以查看操作幫助。
          為了實(shí)現(xiàn)電腦和模擬器上的android程序進(jìn)行socket通信,需要把程序開(kāi)啟的端口通過(guò)端口映射設(shè)置到電腦上,這跟家里的路由器端口映射概念是一樣的。telnet到模擬器之后,通過(guò)
          redir add tcp:1234:1234
          就能把模擬器上的1234端口映射到電腦上,第一個(gè)表示電腦端口,第二個(gè)表示模擬器程序要使用端口,這兩個(gè)數(shù)字可以相同也可以不同,要映射udp端口就把tcp改為udp即可
          redir add udp:1234:1234
          這樣一來(lái),當(dāng)模擬器的程序打開(kāi)1234端口時(shí),在電腦上也打開(kāi)了對(duì)應(yīng)的端口,只要通過(guò)電腦連接127.0.0.1的對(duì)應(yīng)端口,就連上了模擬器的程序端口,就可以通過(guò)電腦上的client向模擬器的server發(fā)送數(shù)據(jù),不需要通過(guò)真機(jī)運(yùn)行。
          如果要讓第一個(gè)模擬器向第二個(gè)模擬器發(fā)送數(shù)據(jù),也可以把第二個(gè)模擬器的端口映射到電腦上,然后在第一個(gè)模擬器程序中向10.0.2.2的對(duì)應(yīng)端口發(fā)送數(shù)據(jù)即可。


          模擬器還有一個(gè)很有意思的功能,每個(gè)模擬器默認(rèn)的電話號(hào)碼就是它的第一個(gè)端口號(hào),例如開(kāi)了兩個(gè)模擬器,第一個(gè)撥打5556,第二個(gè)就會(huì)顯示5554來(lái)電,還能接通,發(fā)短信也可以,這樣就能模擬電話和短信功能。

          詳細(xì)的信息可以看Dev Guide的模擬器部分:http://developer.android.com/guide/developing/devices/emulator.html
          posted @ 2012-02-24 10:37 amp@java 閱讀(2422) | 評(píng)論 (0)編輯 收藏

          前天是情人節(jié),雖然結(jié)婚好多年了,但是老婆一直都喜歡驚喜的浪漫,可惜我卻是個(gè)木訥的呆子,做不出那些轟動(dòng)的事情。那天下午馬上就要下班回家了,突然在微博上看到有人談到geek的情人節(jié)禮物,雖然我不是geek,但是最近在學(xué)Android,老婆的手機(jī)也是Android系統(tǒng)的,何不專門做個(gè)程序給她?

          想法可嘉,但是動(dòng)起手來(lái)卻不是那么回事。學(xué)了那么多天,真正派上用場(chǎng)的還沒(méi)學(xué)到。時(shí)間只剩下不到一個(gè)小時(shí)了,我會(huì)的只是在屏幕上顯示幾個(gè)大字:XXX,我愛(ài)你!

          后來(lái)想想似乎太單調(diào),如果能夠加上點(diǎn)背景音樂(lè)可能好點(diǎn),但是還沒(méi)學(xué)會(huì)怎么使用,上網(wǎng)搜了一下,幸好很簡(jiǎn)單,用MediaPlayer就可以了,幾條語(yǔ)句就能搞定。音樂(lè)文件怎么來(lái)呢?通過(guò)網(wǎng)絡(luò)在線播放是最簡(jiǎn)單的,于是就到百度MP3搜了一下“情人節(jié)快樂(lè)”,我記得有一首歌里面一直在喊“情人節(jié)快樂(lè)”的,結(jié)果最后發(fā)現(xiàn)那首歌名字叫《沒(méi)有情人的情人節(jié)》……

          算了,管它呢,有老婆就行了,沒(méi)有情人照樣過(guò)情人節(jié),打開(kāi)發(fā)現(xiàn)鏈接居然是百度的,以前百度不是說(shuō)它只負(fù)責(zé)搜索,不負(fù)責(zé)存放嗎,怎么現(xiàn)在的MP3都放在百度的服務(wù)器了?把鏈接復(fù)制下來(lái),在模擬器上運(yùn)行還是挺好的,因?yàn)樗玫氖请娔X的寬帶,呵呵。不過(guò)過(guò)了一會(huì)提示下載失敗,把那個(gè)地址往瀏覽器一貼,果然打不開(kāi)了,原來(lái)百度這種下載鏈接是有有效期的,只能讓你試聽(tīng)一下,然后下載,不是長(zhǎng)期有效的。這就麻煩了,到時(shí)候裝在手機(jī)上沒(méi)聲音豈不是很糗?

          再搜索一下,還好,可以把MP3文件放在assets里面,發(fā)布程序的時(shí)候把它包含在apk里面就行了,不用聯(lián)網(wǎng)了。

          現(xiàn)在可以在顯示大字的同時(shí)播放《沒(méi)有情人的情人節(jié)》了。看了一下效果,還是有點(diǎn)怪異,手機(jī)的狀態(tài)欄和程序的標(biāo)題跟黑色的背景,紅色的大字似乎不太搭配,于是繼續(xù)搜索全屏代碼,哈哈,兩句搞定,這樣炫多了。

          不過(guò)一直看著那幾個(gè)字沒(méi)任何反應(yīng),似乎太單調(diào)了,于是就想讓它們不斷變色,或者動(dòng)一下也好,但是無(wú)論怎么弄都搞不定,下班時(shí)間到了,要去接老婆了,就這樣吧。

          之前都是在模擬器上運(yùn)行,或者接個(gè)USB在手機(jī)上運(yùn)行,還不知道怎么打包成apk呢,這下居然沒(méi)搜索到,可能太簡(jiǎn)單了,大家都沒(méi)說(shuō)。于是在項(xiàng)目上點(diǎn)右鍵,果然看到導(dǎo)出apk的菜單,我選擇了unsigned方式導(dǎo)出,在手機(jī)上居然安裝不了。再搜索一下,哦,原來(lái)是要導(dǎo)出成signed apk才能裝的,但是我沒(méi)有證書,怎么signed呢?沒(méi)想到ADT還可以生成證書,一下就搞定了,這比Symbian那種簽名簡(jiǎn)單多了,但是可能也是導(dǎo)致Android惡意軟件泛濫的原因之一。

          去接老婆的時(shí)候通過(guò)藍(lán)牙把a(bǔ)pk發(fā)到她手機(jī)上,裝上,運(yùn)行,從她表情上看出,我的努力沒(méi)有白費(fèi)。不過(guò)最后還是發(fā)現(xiàn)了個(gè)嚴(yán)重的bug,那首歌還沒(méi)放完,另外一個(gè)聲音已經(jīng)重新開(kāi)始了,形成了“二重唱”的效果,而且程序退出之后還在唱,趕工造成的悲劇啊。

          下面是代碼:
          public class LoveActivity extends Activity {
              TextView text;
              
          /** Called when the activity is first created. */
              @Override
              
          public void onCreate(Bundle savedInstanceState) {
                  
          super.onCreate(savedInstanceState);
                  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   
                  WindowManager.LayoutParams.FLAG_FULLSCREEN);  
                  requestWindowFeature(Window.FEATURE_NO_TITLE);  
                  setContentView(R.layout.main); 
                  MediaPlayer mp 
          = new MediaPlayer();
                  
          try{
                      AssetManager assetManager 
          = getAssets();
                      AssetFileDescriptor afd 
          = assetManager.openFd("a.mp3");
                      mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                      mp.prepare();
                      mp.start();
                  }
                  
          catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }
          main.xml:
          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation
          ="vertical"
              android:layout_width
          ="fill_parent"
              android:layout_height
          ="fill_parent"
              
          >
              
          <TextView 
              
          android:id="@+id/textView1" 
              android:text
          ="@string/loveyou" 
              android:layout_width
          ="match_parent" 
              android:layout_height
          ="match_parent" 
              android:gravity
          ="center" 
              android:textColor
          ="#ff0000"
              android:textStyle
          ="bold"
              android:textSize
          ="50dip"
              
          />
              
             
          </LinearLayout>
          strings.xml:
          <?xml version="1.0" encoding="utf-8"?>
          <resources>
              
          <string name="hello">Hello World, LoveActivity!</string>
              
          <string name="app_name">Love</string>
              
          <string name="loveyou">XXX\n我愛(ài)你</string>
          </resources>
          再把那首mp3放到assets里,改名為a.mp3即可。




          希望明年能做出個(gè)更好的。
          posted @ 2012-02-16 11:06 amp@java 閱讀(2317) | 評(píng)論 (2)編輯 收藏

          僅列出標(biāo)題
          共10頁(yè): 上一頁(yè) 1 2 3 4 5 6 7 8 9 下一頁(yè) Last 
          主站蜘蛛池模板: 红河县| 静乐县| 晋城| 和林格尔县| 黑水县| 濮阳市| 蓬溪县| 永仁县| 常山县| 基隆市| 保亭| 台东县| 河东区| 溧水县| 焦作市| 岳西县| 长宁区| 宜兰市| 徐水县| 元氏县| 伽师县| 乌兰察布市| 巴南区| 府谷县| 梁平县| 齐齐哈尔市| 岳阳县| 谷城县| 巧家县| 松滋市| 汉中市| 青田县| 永平县| 孟连| 江源县| 建瓯市| 屏南县| 安泽县| 海盐县| 吴堡县| 达尔|