2017-01-11 48 views
1

我懷疑有關服務管理器註冊的服務,而不是由SystemServiceRegistry註冊。如何從Android中的ServiceManager獲取服務?

SystemServiceRegistry

/** 
* Manages all of the system services that can be returned by {@link Context#getSystemService}. 
* Used by {@link ContextImpl}. 
*/ 

這意味着通過系統中註冊的服務的意見可以讓他從上下文參考。

關注ServiceManager,如何訪問由ServiceManager添加的服務在未由SystemServiceRegistry註冊的應用程序中?

+3

「ServiceManager」和「SystemServiceRegistry」都不是Android SDK的一部分。如註釋所示,使用'Context'上的'getSystemService()'來檢索系統服務。 – CommonsWare

+0

是的,但我正在查找未由系統註冊並由ServiceManager添加的服務。上下文無法爲我解決它。 – Andriel

+0

對'getSystemService(「service_name」)'try/catch'調用並檢查該調用是否返回系統服務的句柄!= null ... _「服務未由系統註冊並且由ServiceManager添加「_ AFAIK添加服務與在」ServiceManager「中註冊服務相同。 – Onik

回答

2

這個答案真的是遲,但另一種方式來訪問的方法隱藏的類ServiceManager正在使用反射。由於類中的所有方法都是靜態的,因此不需要傳入調用方法的對象引用。你可以簡單地傳入類實例。爲了獲得隱藏類的類實例,可以使用更多的反射。 例子:

Class localClass = Class.forName("android.os.ServiceManager"); 
Method getService = localClass.getMethod("getService", new Class[] {String.class}); 
if(getService != null) { 
    Object result = getService.invoke(localClass, new Object[]{Context.AUDIO_SERVICE}); 
    if(result != null) { 
     IBinder binder = (IBinder) result; 
     // DO WHAT EVER YOU WANT AT THIS POINT, YOU WILL 
     // NEED TO CAST THE BINDER TO THE PROPER TYPE OF THE SERVICE YOU USE. 
    } 
} 

這是幾乎所有你需要做的訪問隱藏的或私有的方法(雖然私有方法,你需要修改方法的訪問)。 我知道反射在Android中是不好的,它們通常是很好的原因,爲什麼一些API沒有公開,但是有一些有效的用例可以使用它。如果您沒有大量調用反射代碼,則性能並不可怕,如果是這樣,您可以緩存這些方法,以便不必在每次調用時執行查找。據說,要小心並分析你是否真的需要訪問非公開的API。

+0

你能完成將該活頁夾轉換爲AudioManager的例子嗎? –

0

正如@CommonsWare所提到的,您需要在上下文中使用getSystemService()。 例如。用於獲取位置服務:

LocationManager mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 

爲您定製服務的使用(假設你的服務在AndroidManifest.xml中註冊):

startService(new Intent(this, YourServiceClass.class)); 
+0

請檢查我上面的評論,上下文引用只有系統註冊的服務不是來自ServiceManager的服務。 – Andriel

+0

爲您的定製服務使用: startService(new Intent(this,YourServiceClass.class)); –

相關問題