2012-12-01 35 views
0

我有一個服務,是假設啓動android音樂應用程序,基本上使音樂應用程序彈出在屏幕上。我試圖這樣做的方式是:是否可以在try/catch中啓動一個活動?

public void onStart(Intent intent, int startId) 
{ 
    // TODO Auto-generated method stub 
    super.onStart(intent, startId); 
    System.out.println("LOGS STARTED"); 
    ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE); 
    List l = am.getRunningAppProcesses(); 
    Iterator i = l.iterator(); 
    PackageManager pm = this.getPackageManager(); 
    while(i.hasNext()) 
    { 
     ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next()); 
     try 
     { 
      CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA)); 
      Log.w("LABEL", c.toString()); 
      if(c.equals("Music")) 
      { 
       System.out.println("HELLO \n"); 
            Intent in = new Intent(); 
       in.setClassName("com.android.music", "com.android.music.MediaButtonIntentReceiver"); 
       startActivity(in); 
      } 
     } 
     catch(Exception e) 
     { 
      //Name Not FOund Exception 
     } 
    } 

} 

logcat確實顯示你好,但由於某種原因,音樂無法啓動。但是當我將它移動到另一個位置時,它確實開始。有沒有辦法做到這一點,或者我必須以另一種方式做到這一點?我希望音樂應用程序在用戶點擊圖標後彈出。這就是爲什麼我做了如果c.equals(「音樂」)的一部分。之所以說它是try裏面是因爲該行:

CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA)); 

會得到一個錯誤,快速修復是爲它由try/catch語句包圍。

+1

只是一個猜測......「com.android.music.MediaButtonIntenrtReceiver」 - >「com.android.music.MediaButtonIntentReceiver」 – dougcunha

+0

這絕對有可能。如果音樂沒有啓動,會有一些其他問題... – user219882

+0

@Thomas我不想讓音樂開始,我只想讓應用彈出,但不會彈出。 –

回答

7

這裏對Intents,Activity和BroadcastReceivers之間的區別以及Android爲這類事情設置的一般方式存在很多誤解。讓我們看看我們是否可以清除一些。 :)

您已經創建了一個意圖,並且您正試圖將其作爲目標,然後致電startActivity。但是您試圖將組件com.android.music.MediaButtonIntentReceiver作爲目標,這不是一個活動。用此Intent調用startActivity可能會失敗。

雖然比這還糟糕。即使您有精確的活動名稱來發送com.android.music包的意圖,那麼安裝了不同音樂應用程序的用戶又該如何呢?許多原始設備製造商在設備上出售他們自己的音樂播放器的變體,這意味着明確指出該軟件包名稱會在其設備上失敗。例如,在Nexus設備上發佈的Google Play音樂使用包名稱com.google.android.music,而不是上面指定的包。

根據匹配本地化應用標籤字符串進行過濾也會導致您遇到問題。您正在尋找名爲「音樂」的應用,但該字符串會根據特定的音樂應用和區域設置而有所不同。例如,Google Play音樂使用字符串「Google Play音樂」,而翻譯成其他語言的「音樂」也不會與此確切字符串匹配。

最後,您只是通過ActivityManager查看正在運行的應用程序進程。這會給你帶來問題,因爲如果應用程序當前沒有運行,該怎麼辦? Android可以在後臺爲資源殺死一個應用程序進程,用戶不需要知道這一點。您正在編寫的代碼會爲用戶意外中斷。

那麼你能做什麼?

意圖是通用的。不要使用特定的人類可讀標籤字符串爲特定的包提取正在運行的進程列表,請告訴Android您想要在語義上做什麼。你想開始音樂應用程序。

Intent musicIntent = new Intent(Intent.ACTION_MAIN) 
     .addCategory(Intent.CATEGORY_LAUNCHER) 
     .addCategory(Intent.CATEGORY_APP_MUSIC) 
     .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(musicIntent); 

一行去一行,我們所做的是告訴Android版:

  • 我們要推出一個「主」的行動,而不是更多的東西專門
  • 我們希望它是用戶通常從啓動器(主屏幕)啓動的活動
  • 我們希望它成爲一個可以播放音樂的廣告應用程序
  • 我們希望它在新任務中啓動o如果該應用程序的任務已經存在,請將其帶到最前面。

現在更少的代碼,我們已經成功的也就是邊緣的情況下更耐,也將自動跟隨音樂應用程序的用戶的喜好更普遍的方式來做到這一點。 (如果有多個應用程序與Intent匹配,則會詢問用戶要啓動哪個應用程序,並且有機會將其設置爲下次的默認設置。)

所有這一切,你也提到你從一個服務開始一個活動。一般認爲,如果這種情況發生在無處不在的地方,而不是響應用戶所採取的行動,那麼用戶體驗設計就會很差,所以請牢記這一點。

+0

+1(投票)我同意你@ adamp.Thanks這麼多分享這個詳細的信息。 –

相關問題