2014-01-22 57 views
0

我試圖從我的apk啓動外部服務,使用盡可能少的代碼。在4.0 AVD上測試軟件包並驗證logcat中的響應似乎給出了正確的結果;但是,在實際的設備上它不會加載。實際上,它甚至似乎完全不在logcat中列出。無法從boot_complete接收器啓動外部服務

這可能是我忽略的東西,只需要第二對眼睛來確認。

StartService.java:

package com.winca.service.start; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 

public class StartService extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Intent i = new Intent(); 
     i.setClassName("com.winca.service", "com.winca.service.StartService"); 
     context.startService(i); 
    } 
} 

AndroidManifest.xml中

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.winca.service.start" 
    android:versionCode="13" 
    android:versionName="1.3" > 

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 
    <uses-sdk android:targetSdkVersion="14" android:minSdkVersion="14"/> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <receiver android:name="com.winca.service.start.StartService"> 
      <intent-filter> 
       <action android:name="android.intent.action.BOOT_COMPLETED"/> 
      </intent-filter> 
     </receiver> 
    </application> 
</manifest> 

AVD響應:

# getprop ro.build.fingerprint 
generic/sdk/generic:4.0.2/ICS_MR0/229537:eng/test-keys 
# logcat -c; sleep 1; am broadcast -a android.intent.action.BOOT_COMPLETED; sleep 20; logcat -d | grep winca 
Broadcasting: Intent { act=android.intent.action.BOOT_COMPLETED } 
Broadcast completed: result=0 
W/ActivityManager( 80): Unable to start service Intent { cmp=com.winca.service/.StartService }: not found 
# 

我居然想到 「找不到」,因爲它包含服務的實際包沒有安裝在AVD上。由於系統SharedUserID,我無法安裝它。但是,至少我可以看到它試圖用AVD加載它,而實際的設備甚至沒有在logcat消息中列出。

爲了說明一下爲什麼,當第三方啓動器設置爲默認時,此特定Android設備不會加載「com.winca.service/.StartService」服務。這可以防止設備上的許多音頻服務在激活之前保持禁用狀態。所以,我認爲可能需要快速打包才能做到這一點;而不是使用Tasker之類的東西(由於某種未知的原因,這種裝置會關閉這個裝置)。

回答

1

只有其中一個組件響應明確的Intent,您的接收器才能工作。這種工作的典型方式是由用戶運行你的一項活動。在此之前,在Android 3.1+上,您的應用程序處於「停止狀態」,其中沒有清單註冊的接收器會響應廣播。

+0

雖然它在4.0 AVD上沒有響應,但有點奇怪。你會認爲他們會給出與真實設備相同的響應。 我可以逃脫一個簡單的意向活動,彈出一個簡單的吐司消息? – Donaldta

+0

@Donaldta:「你會認爲他們會給出與真實設備相同的迴應」 - 通常他們會這樣做。但是,請記住,一旦您的應用程序脫離停止狀態,即使重新安裝(例如,從您的IDE運行更新版本的應用程序)後,它仍然不在該狀態。也許你之前在AVD上做了一些讓你脫離停止狀態的事情,同樣的事情也沒有發生在設備上。 「我可以通過簡單的意向活動逃脫一個簡單的敬酒信息嗎?」 - 是的。事實上,我的書中的例子往往是這樣做的。 – CommonsWare

+0

謝謝,我明白這一點。我會繼續前進,併爲您的書籍訂閱。我猜平裝本是單獨出售的,嗯? – Donaldta

0

事實證明,將應用程序移動到/ system/app目錄可繞過正常安裝中的「停止狀態」。反正這個意圖是因爲用戶正在爲這個特定的Android設備拼湊一個自定義ROM。問題是,我們一直在測試應用程序,通過安裝它導致「停止狀態」,並阻止它適當地執行。但是,使用正確的文件權限將應用程序移動到/ system/app目錄中,可以使apk按預期工作。

我想這是對大多數第三方開發情況不適用的解決方案,比如通過Google Play分發應用程序。爲此,您需要遵守允許用戶在CommonsWare指出的安裝過程中至少啓動一次意圖的慣例。至於爲什麼它運行在AVD中,回想起來,我懷疑它通過Eclipse的Run> Debug(F11)機制初始安裝它。我猜根據「dumpsys package {package.name}」,使用了一種不同的安裝方法,將軟件包標記爲「stopped = false」。