• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 224  文章 - 41  trackbacks - 0
            <2008年11月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            享受編程

            常用鏈接

            留言簿(11)

            隨筆分類(159)

            隨筆檔案(224)

            文章分類(2)

            文章檔案(4)

            經典c++博客

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            可參考下面的文章:http://www.ibm.com/developerworks/cn/opensource/os-cn-android-actvt/index.html

            原文地址:http://blog.csdn.net/lihaifeng555/archive/2009/09/27/4599691.aspx

            在Android里,應用程序是通過清單目錄定義的。每個應用程序都是定義在AndroidManifest.xml里,其聲明了其進入點(Entry Point)、通訊層(Communication Layer)、授權(Permission),以及活動(Activity)和意圖(Intent)等。其中,有4個基礎組件,我們稱之為Android的主要組件,他們組成了豐富的Android應用程序。

            Activity: Android 應用程序的UI(User Interface)基本組件。

            Intent receiver: 可隨時被啟動來處理Intent,并執行其任務。

            Service: 非UI功能的后臺處理組件。

            Content provider: 跨程序的共享資料之存儲者。

            Android vs. Java ME vs. BREW

            一個BREW應用程序,在所有絕大多數情況下,是由一個單獨的小程序組成,這個小程序是通過接收和發送活動與手機的其他部分通信的。另一方面,你可以將一個Java ME應用看做Midlet類的擴展。這個Midlet有啟動、停止、暫停、鍵處理(key handling)的功能,并且可以完成任何手機和應用的交互。一個Java ME應用程序通常由一個單獨的Midlet組成。

            Android應用程序有許多活動,通過AndroidManifest.xml文件,這些活動可以被注冊在手機中。 在面向Android的開發與面向其他手機開發工具包的開發之間,Android的multiactivity架構或許是的他們之間主要的區別。正是這個事實使編寫模塊化、分割的代碼(modular, compartmentalized code)更容易。在BREW和Java ME中,開發人員可以執行在Midlet或小程序范圍內的大部分功能。在Android中,你可以寫一個活動、內容處理程序(content handler)、意圖接收器(intent receiver)、或服務以應對幾乎任何東西。一旦你編寫了編輯文本文件的活動,通過發送和接收意向的行動,您可以引用這個活動在您將來所有編寫的應用中。這個這并不是說,這種架構在BREW或Java ME中是不能實現的,他們只是必須在Java和C或C++編程的基礎上,或在BREW中通過繁瑣的擴展實現,而不是被平滑地集成到應用框架中。

             


            Functionality

            就像Midlet,活動使用了一系列的功能與外面的世界進行交換。在他的基礎上,你編寫的活動必須重寫方法OnCreate,你還要重寫其他功能,包括:onStop、onPause、onResume和onKeyDown。這幾個功能可以讓最大限度地將你開發的活動綁定到Android手機中。在默認情況下,在Eclipse中創建新的Android應用程序將執行一個“Hello,World”應用程序。我會告訴你如何從這個基本應用到功能齊全的畫面。

            如何添加圖片(Image)資源

            首先將圖片資源(例如menu_background.jpg)直接拷貝到/res/drawable文件夾中。此時,Eclipse的Android插件(Android Plug-In)會自動將一個新的ID值添加到R.java里。所以R.java文檔中會多加了一行指令如下:

            public static final int menu_background=0x7f020001;

            在應用程序將就用此ID值來取得這個圖標文件,并顯示或處理它。

            如何定義XML布局 (Layout) 文件

            剛才已經新增了一個圖片資源文件。此時,在定義布局XML文件中,就可以引用此圖片。這些布局XML文件都放在在/res/layout文件夾中,其中Eclipse的Android插件已經生成了一個main.xml文件?,F在,你可利用Eclipse的 File>New>File菜單選項來生成新布局XML文件,例如:splash.xml。然后,以main.xml內容為模板,將之拷貝到新的splash.xml里,下一步移動<TextView>并且增加<ImageView>,內容如下:

            <ImageView android:src="@drawable/menu_background"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">
            </ImageView>

            在Android的XML布局文件里,使用@drawable/就能輕松地引用/res文件夾中的資源,例如上面的的android:src="@drawable/menu_background"。此外,layout_width和layout_height 則說明這個ImageButton顯示出來的大小(Size)。splash.xml也成為一項新的資源。所以在R.java裡也會自動產生新的一行,如下:

            public static final int splash=0x7f030001;


            繪制啟動畫面

             

            現在,你的初始畫面被定義完成,可以激活和顯示。你現有的Android活動已制定了main.xml,所以你要轉移到新的初始布局。為了切換,更改OnCreate方法中的代碼:

            setContentView(R.layout.main);

            setContentView(R.layout.splash);

            運行應用程序,看著你新創建的啟動畫面。到目前為止,如果你得到了錯誤信息,檢查以確認你的名字是否匹配。如果圖片沒有顯示,確保它被正確地放置在res/rawable文件夾,并splash.xml應用了正確的名稱和文件。

               

            時間可以解決任何問題

             

            啟動屏幕開始展現,但啟動畫面單獨作無聊的應用程序,所以你需要進入主菜單。你會使用簡單的內嵌定義線程來完成的定時器,有一些常數需要在定義線程前初始化。為了看上去完整,我將包括全部的OnCreate方法。代碼如下。

            Code Listing 2-1. Timing the Splash Screen

            long m_dwSplashTime = 3000;

            boolean m_bPaused = false ;

            boolean m_bSplashActive = true ;

            public void onCreate(Bundle icicle)

            {

            super .onCreate(icicle);

            //Draw the splash screen

            setContentView(R.layout.splash);

            //Very simple timer thread

            Thread splashTimer = new Thread()

            {

            public void run()

            {

            try

            {

            //Wait loop

            long ms = 0;

            while (m_bSplashActive && ms < m_dwSplashTime)

            {

            sleep(100);

            //Advance the timer only if we're running.

            if (!m_bPaused)

            ms += 100;

            }

            //Advance to the next screen.

            startActivity(new Intent(

            "com.google.app.splashy.CLEARSPLASH"));

            }

            catch (Exception e)

            {

            Log.e("Splash", e.toString());

            }

            finally

            {

            finish();

            }

            }

            };

            splashTimer.start();

            }

              

            到現在 , 你才開始看到一些 Java 代碼。這個簡單的線程直到運行時間計數器超過 m_dwSplashTime 才停止。雖然有實現一個計時器多種方式,選擇這種方式有兩個原因:


            此計數器可以暫停。該計時器只有m_bPaused標志為false時才推動。正如你將看到在一分鐘內,如果你調用活動的OnPause方法,可以方便暫停計時器。這并不總是對啟動畫面的需求,這對其他以時間為基礎的業務是重要的。
             


            移動到下一個屏幕很簡單,只要改變的m_bSplashActive標記為false。推進到下一個屏幕,如果你執行這在時尚,不要求你作出的行動,然后取消更傳統的計時器。
             

            有了這個代碼,只要你以毫秒為單位設置m_dwSplashTime,你應該看到啟動畫面。當時間到了或用戶使用按鍵中斷了啟動畫面,startActivity將被調用。finish可以關閉啟動活動,使用戶不必通過從主菜單上選擇Back返回。你需要執行一項活動,接受CLEARSPLASH意圖的行動。與此同時,讓我們回顧一些其他重要活動的方法你需要重寫。

             

            暫停,恢復,沖洗,重復

            由于呼入電話,短信或其他中斷,你的活動被掛起時,暫停啟動計時器,如下:

            protected void onPause()

            {

            super.onPause();

            m_bPaused = true;

            }

            對于這些大部分覆蓋的方法 , 在做任何事情之前 , 你需要調用超類。如果你查看計時器線程,如果m_bPaused是true,你會看到負責跟蹤時間的MS計數器保持時間沒有前進。在這一點上,我相信你可以猜測onResume的樣子:

            protected void onResume()

            {

            super.onResume();

            m_bPaused = false;

            }

            當你的應用程序恢復,計時器線程添加時間恢復到MS計數器。

             

            基礎的 Key Handling

            在活動內,Key Handling是處理覆蓋onKeyDown方法。我們將使用此功能允許用戶取消你不完美的啟動畫面。正如在本節開始你看到的計時器線程,通過m_bSplashActive設置,你在計時器循環中了異常語句。為了異常處理,你只需要重寫onKeyDown方法使之切換啟動標記為false。下面的代碼需要添加:

            public boolean onKeyDown(int keyCode, KeyEvent event)

            {

            //if we get any key, clear the splash screen

            super .onKeyDown(keyCode, event);

            m_bSplashActive = false ;

            return true;

            }

            現在 , 當用戶按下任意鍵 , 屏幕將被推進到下一個路程通過計時器循環。

             

            Clear intent

            有一件事你需要在啟動畫面之前做 , 我相信你想知道有關 startActivity 方法調用。這里應該簡單介紹一下intent。Intent是一個對象,在兩個或兩個以上活動、內容處理(content handlers)、意圖接收器(intent receiver)、或服務之間,可以作為一個通訊事件。你會使用com.google.app.splashy.CLEARSPLASH調用 startActivity 。當startActivity被調用時,Android搜索所有配置清單文件,尋找已注冊為CLEARSPLASH Intent action節點。

            你要增加一個新類MainMenu,其作為主菜單activity。它要繼承Activity類,實現OnCreate方法,在R.layout.main中調用setContentView方法。你要打開的AndroidManifest.xml并增加新的 activity 元素。在 </activity> 結束符之后, 你應該插入以下內容:

            <activity android:name=".MainMenu"

            android:label="@string/app_name">

            <intent-filter>

            <action android:name=

            "com.google.app.splashy.CLEARSPLASH"/>

            <category android:name=

            "android.intent.category.DEFAULT"/>

            </intent-filter>

            </activity>

            確定活動的名稱為 .MainMenu 。這會告訴 Android 加載和運行 Java 類。在 Intent filer 標簽中 , 注冊為 com.apress.splash.CLEARSPLASH 的 Intent Action 。在現實中,名稱意圖可能是beef.funkporium.swizzle,只要名稱在startActivity調用和前面的Android配置清單中一致,所有正確的事情應繼續發生。

             

            一項活動的生命周期

            Activity的生命周期被包括在Google的文檔中。但是,如果你先仔細考慮生產Activity的底層原理,你不能錯過這個重要的信息。在這一點,你的啟動畫面,你應該準備好推出。

            為了說明,我還增加了以功能在啟動畫面活動中:

            protected void onStop()

            {

            super.onStop();

            }

            protected void onDestroy()

            {

            super.onDestroy();

            }

            如果你方斷點在上面活動的所有功能,在調試模式下運行它,你會看到斷點與下面順序一致:

            1. onCreate

            2. onStart

            3. onResume

            4. 在這一點上,你的活動目前已經運行。在三秒鐘內,計時器線程將達到結束,并調用startActivity結算的意圖。下一步,它將調用finish,它告訴Android關閉啟動畫面活動。

            5. onPause

            6. onStop

            7. onDestroy

            5. onPause

            6. onStop

            7. onDestroy

            從開始到結束 Activity , 這是一般的生命周期來。你可以找到對生命和時代的 Android 活動更全面地披露 , 在谷歌的文檔活動中 http://code.google.com/android/reference/android/app/ Activity.html 。你甚至可以找到漂亮圖形。從本質上講,手機使用了以前的組合功能提醒你的主要事件可以發生在你的應用程序:啟動,關閉,暫停和恢復。我已經討論過,Activity將要成為任何傳統應用的的核心組件;他們給你控制了屏幕,能夠接收用戶輸入。

             

            總結

            到目前為止,我已經探討了活動如何成在手機中,他們如何啟動和停止,以及他們如何與基礎層溝通。我演示了如何顯示一個簡單的XML視圖屏幕,以及如何活性之間切換兩個反應都在一個關鍵的事件和結束時的一個指定的時間量。在短期內,你需要了解更多有Android如何使用意向,意圖接收器,過濾器和意圖溝通。要做到這一點,你需要一個示例應用程序。

             

            創建一個Intent Receiver

            Intent Receiver是Android重要的組成部分,從它的名字可以看出其作用。它的作用是等待接收注冊的Intent Action,Android是按照BREW的通知模式實現的。我們將使用一個簡單的應用,展現一個復雜的Intent Receiver任務:輸入文本消息的接收和響應。

             

            事情的起因

            我們開始設想這樣一幅畫面:一天下午,當你回到你的辦公桌,你發現你的辦公桌,從地毯到天花板與可愛的粉紅色的圖片,鋪滿最令人討厭的圖畫。你知道這是誰在做,現在是你報復的時候了。你也知道你的工程部副總裁最厭惡一首特殊的歌。這首歌是 “ La Bamba “ 。讓你決定通過一個休眠程序操縱你同事的Android手機。我會告訴你如何制作一個Android應用程序,收到特定的短信后,播放這種恥辱效應的音頻文件。這會使你的副總對你的新敵人產生強烈的憤慨。同時,你要給他一個機會關閉聲音了。這種惡作劇程序要求Intent Receiver,Activity,Service,以及所有三種方式進行通信。

               

            這有什么實際的通途嗎?這可能有嗎?

            這是一個很好的問題。雖然表面上看來不是很實用應用,我相信,如果有一點想像力,你可以發現其很多重要的現實用途:從推送電子郵件通知到內部電話應用通信。

            你將向前邁進四個階段。在每個階段,你將了解更多關于Intent receives,services,所有這些應用程序之間的相互作用件:


            通知收到一個短信
             


            打開短信的內容和找到特殊的凈荷
             


            當短信到達Activity啟動,并且意識到啟動發生在接收器的控制下
             


            開始一個新的服務,將播放音頻文件
             

               

            使用Intent Receiver

            在你開始編寫Intent Receiver之前,你需要了解你為什么會使用他。Intent Receriver沒有或幾乎沒有內存占用、linkage和系統開銷。在啟動時,一個活動必須將所有大量的引入的類加載,Intent Receriver則沒有這些約束。由于某種類型的新Intent可以達到破碎頻率(例如網絡狀態更新),一個輕量級的對象必須在分析數據的第一階段。如果它是一個適當的時間喚醒一個更大的用戶界面程序或大幅后臺服務,意圖接收機應采取這種行動。

             

            提示:意圖接收器可以經常的啟動和關閉(這依靠他們的監聽),試圖讓它們變地重量輕,使用盡可能少的類庫。你的用戶不會高興,如果他們電話在緩慢地爬行,因為你已經插入到太多特定的事件處理開銷。

             

            編寫Intent Receiver

            第一件事首先你需要創建一個這個小惡作劇應用程序建立新項目。在源目錄中,創建一個新類,將成為新的Intent Receiver。在第一階段,它看起來應該像這樣:

            public class PrankSMSReceiver extends IntentReceiver

            {

            public void onReceiveIntent

            (Context context, Intent intent)

            {

            return;

            }

            }

            現在你已經設定了階級 , 你必須告訴你想要 Android 接收 SMS 事件。你可以通過修改 AndroidManifest.xml 文件給你許可和登記 RECEIVE_SMS 的 Intent action 。

             

            權限

            運營商,用戶,甚至開發人員可能不希望給Android應用自由支配,貫穿其手機和網絡的特權層。因此,谷歌推出一種被移動發人員認可的權限概念。為了能夠接收短信息,你需要通知手機你可以接收。

            在Android中,所有元素的權限聲明在特別的配置文件中,你添加的權限在<manifest>標記后(代碼2-2)。該示例應用程序將被稱為PrankApp。其活動主要是rankActivity。

            Code Listing 2-2. Adding Permissions to Receive SMS Messages

            <?xml version="1.0" encoding="utf-8"?>

            <manifest xmlns:android=

            "

            package="com.apress.book.PrankApp">

            <uses-permission android:name=

            "android.permission.RECEIVE_SMS" />

            沒有權限標志,Android將你的應用程序無法啟動當它接收到一個短信。還有其他的權限我需要涵蓋你向前看。在此期間 , 你可以找到所有在列表的權限 Android 的文件資料 http://code.google.com/android/reference/android/ Manifest.permission.html 。

             

            向我發送短信!

            現在,你已經允許進行與手機的SMS層交互,你必須告訴手機做什么,當一個新的文本信息到達時。要做到這一點,你必須打開AndroidManifest.xml文件,添加一個新的Intent Receiver。代碼清單2-3顯示了要插入的代碼。

            Code Listing 2-3. Registering the New Intent Receiver for

            Incoming SMSs

            </activity>

            <receiver android:name=

            "PrankSMSReceiver"android:enabled="true">

            <intent-filter>

            <actionandroid:name="android.provider.Telephony.SMS_RECEIVED"

            />

            <categoryandroid:name="android.intent.category.DEFAULT" />

            </intent-filter>

            </receiver>

            這就是你每次必須要接受的 Intent notification , 當手機得到一個接收到的 SMS 。

             

               

            在 Action 中分析 Intent Receiver

            要完成這個要比我們想象的有一點困難。一個進程必須在一個 DDMS 中運行 。但在大多數情況下,你不想讓應用程序運行,除非新的事件觸發它。這問題的解決方案在Eclipse IDE中只是一個小小的把戲。當你一步一步往下走時,這可能會一點一點變得復雜。

            在你的onReceiveIntent方法中放置一個斷點。開始調試應用程序,并讓模擬器位于“Hello World,PrankActivity”屏幕上。在Eclipse中,切換視圖到DDMS。你可以按這命令+ F8鍵幾次或選擇菜單 Window ?? Open Perspective ?? DDMS 。

             

            沿著左邊窗口,在Device選項卡上,你現在應該看有一個綠色bug圖標在你的應用旁邊。這是DDMS告訴你調試器附加到你的PrankApp進程中。在它的下面是Emulator Control選項卡。在這里你可以發送短信消息。首先輸入任何一個電話號碼,選擇SMS,鍵入一個測試消息,并按下Send。

             

            如果你的配置正確,你應該看到Eclipse切換到Debug透視圖,并停止在你的新設置斷點上。

             

            注意:如果沒有發生,首先確保你設置了權限正確。如果他們不正確,你應該看到一個失敗的權限信息顯示在DDMS屏幕底部的LogCat標簽中。此外,請確保你的應用程序已經在運行,并在Devices選項卡有綠色調試圖標在它的旁邊。如果所有這些都不奏效,比較你的項目與文中的示例。

             

            目前為止,如果你正確地完成了。你的Intent的onReceiveIntent功能被調用,當每一個SMS消息發送到手機上。接下來,你就必須弄清楚如何得到短信的內容。

             

            什么是在一個SMS中?

            可悲的是,到目前為止Android關于接收和過濾SMS信息的文檔只不過是混亂的。我懷疑這不是一項需要告訴開發人員的重要功能。我不同意這些優先事項,但是使我有機會填補空缺。

            下面是methodonReceiveIntent的代碼,功能是監聽新的SMS信息:

            public void onReceiveIntent

            (Context context, Intent intent)

            {

            SmsMessage msg[] =

            Telephony.Sms.Intents.getMessagesFromIntent(intent);

            for(int i = 0; i < msg.length; i++)

            {

            String msgTxt = msg[i].getMessageBody();

            if (msgTxt.equals("0xBADCAT0_Fire_The_Missiles!"))

            {

            //Start the pranking here

            }

            }

            return;

            }

            你還需要輸入兩個類庫來完成這項工作:

            Import android.telephony.gsm.SmsMessage;

            Import android.provider.Telephony;

            getMessageFromIntent 方法是在 Telephony 類中 , 這將返回 SMS 信息的數組?,F在剩下的就是得到短信的有效載荷。你要找的觸發惡作劇活動的特殊代碼為文本

            “ 0xBADCAT0_Fire_The_Missiles ! ”

            它必須是一個適當的獨特組合,以便它不會被觸發事故。你不會希望自己的惡作劇失火并提醒受害人太早的。

            注意:在Android里,沒有記載的功能是很可能還沒有完成。由于接收短信的文檔幾乎不存在,你應該會有些變化在如何處理手機簡訊上。更可能的是整體的方法應該是相似的,但它有把握地認為其中的一些細節將改變SDK的前到達它的最終版本。這個例子是有關學習如何使用意圖接收器多是有關文本的消息通信資料。

             

            觸發活動

            重要的是要記住,意圖接收器的生命周期短,只有只要方法調用onReceiveIntent。一旦出于這一職能,Android是免費殺死進程中運行你的應用程序。任何異步功能會死去,如果是一個十分棘手的死亡開始。如果你想要做超越了簡單的處理方法內的任何事情,你需要啟動服務或活動。既然你要同時播放音樂和警報你的受害者,他們去過了,你需要啟動的一項活動。你完成此情況如下:

            if (msgTxt.equals("0xBADCAT0_Fire_The_Missiles!"))

            {

            //Start the Activity

            Intent startActivity = new Intent();

            startActivity.setLaunchFlags(Intent.NEW_TASK_LAUNCH);

            startActivity.setAction("com.apress.START_THE_MUSIC");

            context.startActivity(startActivity);

            }

            你會看到這里是增補 NEW_TASK_LAUNCH 在 setLaunchFlags 。你需要做任何你要發送的 Intent action , 將啟動一項新的活動。此外,正如你在啟動畫面示例應用程序,你必須添加一個新的行動,你的Activity的Intent filter。那個過程應該看起來很熟悉:

            <intent-filter>

            <action android:name="android.intent.action.MAIN" />

            <action android:name="com.apress.START_THE_MUSIC" />

            <category android:name=

            "android.intent.category.LAUNCHER" />

            <category android:name=

            "android.intent.category.DEFAULT" />

            </intent-filter>

            現在 , 如果你在前面正確地添加了代碼 , 當你從 DDMS 透視圖中 發送 SMS 消息時 , 你應該看到你的應用跳出到前臺 , 顯示 “Hello World ,PrankActivity ” 文本在屏幕上。

             

            索具的活動

            一個最后的工作你需要添加 , 在得到卑鄙的音樂播放服務之前 : 裝配 Activity , 以回應你的 Intent Receiver 發送的活動 。如果應用程序正常啟動,你要立即關閉了。同樣,如果可以通過菜單啟動,這樣你的惡作劇的計劃就會過早的曝光。要做到這一點,你必須檢索發射的Intent,并調用getAction方法來計算出在什么情況下,它已經啟動。該PrankActivity的OnCreate方法現在看起來應該代碼2-4。

            Code Listing 2-4. Launching on a Specific Intent Action

            public void onCreate(Bundle icicle)

            {

            super .onCreate(icicle);

            Intent i = getIntent();

            String action = i.getAction();

            if (action != null &&

            action.equals("com.apress.START_THE_MUSIC"))

            {

            setContentView(R.layout.pranked);

            //We'll need to start the music service here

            }

            else

            finish();

            }

             

            首先你會得到發起 Activity 的Intent 。使用目前得到的 Intent , 你可以用 getAction 方法檢索調用的行動。這個將返回一個包含啟動事件的字符串,你核對你的著名音樂行動列在原來的XML。如果在啟動事件為你的活動來自正常的方式(從菜單或從啟動調試器),該行動字符串將是null。如果是這樣的話,你要立即使用finish方法關閉活動。

            注意:OnCreate方法被調用當你的應用被首次啟動時。如果你已經啟動你的應用程序,然后退出(使用返回鍵),應用程序仍然在后臺運行。如果在這時,你發送短信,你的活動將回到前臺,但其OnStart方法將調用而不是OnCreat。

             

            你今天想羞辱誰呢?

            雖然可能有些矯枉過正,你要使用Android的service對象來處理音樂播放。我打算這樣做有因為另個原因:

            n         ?? 這是一個好的機會來展示以簡單的方式service的使用,在簡單的環境。

            n         ?? 潛在的,它會讓你啟動音樂不用看到應用程序,使你的惡作劇的應用程序更卑鄙。

            神經與服務

            為什么你要使用的服務?從本質上講,它意味著是一個對象,與用戶界面分離的可運行地過程。這是完美的情況,當一個開發人員希望的功能(無論是網絡或多媒體相關)能夠獨立運行。例子包括:音頻播放,網絡交易的后臺,和邪惡的惡作劇程序。雖然服務允許多個應用程序(打開通信信道)與他們綁定,你會使用它作為一個簡單的后臺進程。同樣,services有很多用途不只是這個簡單的例子。

            創建service

            添加一個新類的源碼包。我已經再次調用PrankService(沒有點創意)。在最基本的層面,service要重寫onBind方法。要獲得服務類編譯,它必須看,至少有一點點,如代碼2-5。

            Code Listing 2-5. A Stripped-Down Service

            public class PrankService extends Service

            {

            public IBinder onBind(Intent intent)

            {

            return null;

            }

            }

            在這個例子中,你不會使用該服務onBind方法進行互動。你可以簡單地啟動和停止服務在你的主要活動內。要做到這一點,你必須重寫兩個方法在服務類:

            OnStart (Int startId ,Bundle argument )
            onDestroy()

            當OnStart被調用時,你會開始播放的媒體文件。當服務被破壞,就會明確地停止。這不是必然要求,但你會明白。

            啟動服務

            開始一個新的服務應該類似于開始活動。自從你已經接觸到這是幾次,我就在給你一段代碼,讓你整理一下。 調用前面列出的PrankActivity OnCreate方法。簡單替換注釋“ We’ll need to start the music service here ”用下面的代碼行:

            startService(new Intent

            ("com.apress.START_AUDIO_SERVICE"), null );

            同樣,這個看上去很熟悉。啟動Activity和啟動service之間唯一的區別是(除了不同的方法調用)是隨Intent傳遞bundle(實際上是一個地圖或哈希表)參數的能力。這bundle將被傳遞到OnCreate方法服務。

            啟動音樂

            BREW和Java一樣,Android的媒體播放(簡單的播放/停止計算)非常簡單易用。當你服務的OnStart函數被調用,你會加載和播放/res/raw 目錄中的測試音頻文件首先要做的是復制音頻樣本文件導入/res/raw(如果沒有這個目錄,繼續并創建它)。下一步,放下羞辱,并復制寫入尊重,音頻文件原始文件夾。如果你使用Eclipse,你應該添加相應的元素R.raw。在你的情況下,它的R.raw.test。

            現在你有一個音樂文件的引用,你可以添加程序 PrankService 的要求如下 :

            public void onStart(int startId, Bundle arguments)

            {

            MediaPlayer p;

            super .onStart(startId, arguments);

            player = MediaPlayer.create(this , R.raw.test);

            player.start();

            }

            請記住 , 是一個重寫的 OnStart 方法 , 因此你必須調用父類同一函數或 Android 將變得不穩定。在這一點上,你需要用MediaPlayer的靜態類創建一個新的媒體播放器對象。因為service是context的子類,你將一個指針傳遞給你當前的context和靜態變量代表你的測試媒體。在這一點上,你可以調用play,現在你可以開始忙了。播放會繼續在后臺運行,直到stopService這個方法是由你的主Activity調用。

            當stopService被調用時,下面的方法將調用:

            public void onDestroy()

            {

            super.onDestroy();

            player.stop();

            }

             

            同情的行動

            既然你是一個不錯的愛開玩笑的人 , 你要給你的受害者一個臺階下。正如你之前見過的,Activity是由Intent Receiver觸發的,在活動啟動服務的時間點上。正如你剛才看到的,service是負責播放噪聲激怒你副總工程師。同樣,因為你是仁慈的在你的執行回報的同時,你必須為受害者設計關閉音樂方法。添加在你的PrankActivity下面的方法可以實現你善意的行動:

            public boolean onKeyDown(int keyCode, KeyEvent event)

            {

            stopService(new Intent(

            "com.apress.START_AUDIO_SERVICE"));

            finish();

            return true;

            }

             

            配置文件

            下面是表現如下所示 :

            <service android:name=".PrankService">

            <intent-filter>

            <action android:name=

            "com.apress.START_AUDIO_SERVICE" />

            <category android:name=

            "android.intent.category.DEFAULT" />

            </intent-filter>

            </service>

             

             

            禪宗和報復的藝術

            通過不光明正大的小惡作劇應用程序的使用 , 你應該明白了 Intents ,Intent Receivers ,services 和Activities 如何 共同在先進的 、 主要是后臺 的 應用程序中運行的。我現在要改變一下方式,一步一步做,你做了什么以及如何實現它。

            讓我做的更好

            你做了以下內容:

            1。你使用正確的權限和系統接收器的意圖級短信的意圖安排的對象是PrankSMSReciever每次實例化一個手機上的SMS到達。如果你的Intent Receiver發現一個非常特定的SMS的有效載荷,它將通過發送Intent將啟動你的活動。

            2。這項活動名為PrankActivity,會監聽被PrankSMSReceiver的特定intent action。當它收到確切intent action,你的活動將顯示一個“gotcha”消息給受害者。同時,該活動將發出意圖旨在啟動服務。如果在任何時候受害人/用戶按下一個電話上的鍵,應用程序將退出,音樂服務將終止。

            3。服務類,稱為PrankService,監聽PrankActivity的intent,將啟動并開始播放令人討厭,預定義的音頻文件。它將繼續播放,直到它被要求停止通過PrankActivity的調用方法stopService。

            注意:此示例應用程序不涉及手機的本地短信應用。因為所有的intent receiver傳入的通知意圖,你的應用將被爭奪用戶與Android的關注短信收件箱的應用。在生產中,這可能需要相當計時器也許觸發文本有效載荷,這是一個微妙多一點 “0xBADCAT0_Fire_The_Missiles !”

             

            在Android中移動數據

            最后,你需要把重點放在內容解析器。 Android不會給SDK特別的手機文件系統的訪問權限,如Brew一樣。它也沒有提供一個RecordStore,像Java ME一樣。在你的Activities、Intent  Receiver和services之間,你傳遞數據的主要方法是必須通過ContentResolver超類。雖然你可以存儲數據通過文件,參數,和其他數據庫,可以采取許多形式,Android附帶的幾個重要內置content resovlers。這里有一個列表,Android的主要content resovlers,你可能要經?;踊A上:


            瀏覽器

            書簽
            搜索歷史


            電話呼叫
            通話記錄
            最近通話


            聯系

            系統設置
            硬件設置(藍牙,網絡設置)
            軟件設置

            Android 的文檔提供了非常好的示例 :http://code.google.com/android/ devel /data/contentproviders.html #usingacp 。馬上我要給你演示怎樣添加一個書簽到手機瀏覽器的書簽列表。首先,你要搜索當前的書簽列表,查看你的鏈接是否存在。第二,你要添加書簽,如果不存在。

             

            注意:可以創建你自己的content provider,作為一種方式,為了公共訪問封裝Android的SQLite的執行。你將進入如何在后面的章節中這一點。現在你只是去處理content resolver交給的“client”方面。

             

            Android采用了自定義的SQLite實現,來存儲本地信息。如果你不熟悉SQL的基礎知識,現在也許是一個學習的機會。為表述方便,我要假設你了解基本的SQL查詢命令。如果你需要進一步提高,Apress上有一個很好的資源http://apress.com/book/ catalog?category=145 。

             

            無恥的自我推銷

            讓我們說一下你的應用程序中“about”部分,你想有一個按鈕,添加你的商業軟件網頁到用戶的web書簽。你要確保它不添加兩次,如果你的用戶有再次點擊該按鈕意外。為了使這個實例簡單,你將觸發這個事件在你示例應用程序中,當用戶按下一個鍵。

            注意:在一個有趣的注意,如果你需要證明,作為一個開發人員,Android是還沒有完全成熟的,你只要看看比對下文件的android.content.ContentResolver方法getDataFilePath,其中規定: “ 請不要使用此功能!有人說這一點,他們不應該。你沒有直接的訪問文件內的內容提供商。不要碰這個。走開。 “ 這是好,知道即使是對Android的文檔技術作家有幽默感。

             

            獲取用戶的書簽

            這應該是顯而易見的,至少在這一點,開發人員可以做一些非常邪惡的事情,訪問用戶的書簽。目前還不清楚,在這一點,Android會做什么以防止發生這類事情。我想這得由運營商來鎖定或監視此行為。在任何情況下,你將使用一個調用方法managedQuery,它將返回一個列表用戶的書簽:

             

            Cursor bookmarks =

            android.provider.Browser.getAllBookmarks

            (getContentResolver());

            int urlColumn = bookmarks.getColumnIndex(

            android.provider.Browser.BookmarkColumns.URL );

            Cursor results;

            String[] proj = new String[]

            {

            android.provider.BaseColumns._ID,

            android.provider.Browser.BookmarkColumns.URL,

            android.provider.Browser.BookmarkColumns.TITLE

            };

            results =

            managedQuery(android.provider.Browser.BOOKMARKS_URI,

            proj, null ,

            android.provider.Browser.BookmarkColumns.URL

            + " ASC");

            現在我將分解每一個操作。你首先要書簽網址列索引。再次,因為Android通過SQL格式提供其多數內部數據的訪問,你應該習慣于用數據庫的方式引你保存的信息。接下來,你將設置游標,一個類似Java ME中RecordStore枚舉對象,設置字符串數值的映射。因為你只關心列包含的網址,它保存非常簡單。方法調用managedQuery是調用將返回你的數據。你可以通過URI中為書簽存儲字符串,交給你了簡單的映射數值,不需要where語句,并告訴它按降序排列的網址。

             

            搜索結果

            搜索結果很簡單只要迭代游標對象,是通過簡單的光標迭代對象和退出一列從URL字符串ID你檢索前 :

            Cursor results =

            android.provider.Browser.getAllBookmarks

            (getContentResolver());

            int urlColumn =

            results.getColumnIndex

            (android.provider.Browser.BookmarkColumns.URL);

            results.first();

            do

            {

            //url is a method param

            //containing what we're looking for

            if(results.getString(urlColumn).equals(url))

            return false;

            } while (results.next());

            你可以做更多的基于 URL 的內容 , 但現在你會只是看你的 www.apress.com 鏈接。很明顯,如果此代碼的運行是上述Apress網址,你不會找到它。因為用戶希望添加貴公司的網址在虛擬的“About” ” 部分中,你也要給他們。

            使用Content Resolver添加邪惡公司網址

            也許他們不是邪惡,但你加入他們。由于Apress也許是公司最邪惡那里(不是我有偏見,記?。?,你讓他們擺脫它,只此一次。下面是一個美麗的ContentReceiver方式添加書簽記錄:

            ContentValues inputValues = new ContentValues();

            inputValues.put

            (android.provider.Browser.BookmarkColumns.BOOKMARK,

            "1");

            inputValues.put

            (android.provider.Browser.BookmarkColumns.URL,

            "

            inputValues.put

            (android.provider.Browser.BookmarkColumns.TITLE,

            "Apress, the not so evil company");

            ContentResolver cr = getContentResolver();

            Uri uri =

            cr.insert

            (android.provider.Browser.BOOKMARKS_URI,

            inputValues);

            想大多數軟件開發工具包,有不止一種方法來完成相同的任務。早些時候,你有更復雜的方法加書簽。這個方法是有用的,因為它給你一個參考如何添加元素通過ContentResolver不具有輔助功能?,F在,這里的簡單的方法:android.provider.Browser.saveBookmark(this,“Apress”,url);幫助函數會啟動一個對話框,要求用戶確認增加書簽。這可能是最用戶友好的方式來添加書簽,除非你想控制對話框的模樣。

            平衡早餐的組成

            在過去的三個例子你探討了Android的所有主要構建模塊。一開始你看到了實用的啟動畫面。這讓你探索了基本知識關于啟動、維護和移動通過Activity對象。這是你學習intents and interprocess/object communication邁出的第一步。使用和傳遞意圖在活動,服務,內容處理,接收器和意圖之間可能是一個最重要的事情,這是Android與其他移動環境的區別。

            對于Activity和通信基礎知識,你已經有了經驗,你繼續學習服務和意圖接收器。要使用這兩個組成部分,你烹調了 狡猾的 惡作劇應用程序,既能強迫你使用所有3個組建(活動,服務,和意圖的接收器),使所有三個互相溝通。幾乎是旁注,你研究什么需要得到通知時,短信在手機上到達。最后,你探討如何檢索和寫入的內容是解析器本機設備:瀏覽器的書簽數據庫。事情的證明并非總是按計劃進行,Android拒絕加入你在一個新的嘗試通過傳統的書簽內容解析方法,該方法forcedthat我已經介紹的基本知識,現在是時候讓手機用戶在權衡多一點。

             

            本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/lihaifeng555/archive/2009/09/27/4599691.aspx

            posted on 2010-05-10 20:51 漂漂 閱讀(1820) 評論(0)  編輯 收藏 引用 所屬分類: android 開發
            人妻精品久久久久中文字幕69 | 久久亚洲日韩精品一区二区三区| 免费精品久久天干天干| 亚洲精品国产字幕久久不卡 | 久久久无码精品亚洲日韩软件| 久久人人爽人人爽人人片AV高清 | 热99RE久久精品这里都是精品免费| 国产aⅴ激情无码久久| 国产免费福利体检区久久| 久久无码人妻一区二区三区| 精品久久久久久久久久中文字幕 | 97精品依人久久久大香线蕉97| 99久久人妻无码精品系列蜜桃| 久久国产精品波多野结衣AV| 欧美喷潮久久久XXXXx| 伊人久久大香线蕉AV一区二区 | 丁香狠狠色婷婷久久综合| 亚洲国产成人乱码精品女人久久久不卡| 久久狠狠爱亚洲综合影院| 精品久久人人爽天天玩人人妻| 91精品国产9l久久久久| 久久一日本道色综合久久| 99久久99久久精品国产片果冻| 国产精品亚洲综合久久| 人妻精品久久久久中文字幕| 九九热久久免费视频| 中文字幕久久欲求不满| 国产精品成人精品久久久 | 久久无码人妻精品一区二区三区| 久久青青草原综合伊人| 日本久久久久久中文字幕| 91麻豆精品国产91久久久久久| 亚洲国产成人久久精品影视| 国产69精品久久久久99| 久久久艹| 久久综合视频网站| 午夜精品久久久内射近拍高清| 国产成人久久精品一区二区三区 | 色妞色综合久久夜夜| AV无码久久久久不卡蜜桃| 精品国产一区二区三区久久|