2017-01-11 30 views
1

ServiceManagerによって登録されたサービスで、SystemServiceRegistryによって登録されていないことが懸念されます。システムによって登録されたサービスは、コンテキストからの彼の参照を取得できることを意味しSystemServiceRegistryAndroidでServiceManagerからサービスを取得するには?

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

のコメントで

ServiceManagerについては、SystemServiceRegistryによって登録されていないアプリケーションでServiceManagerによって追加されたサービスにどうやってアクセスできますか?

+3

「ServiceManager」も「SystemServiceRegistry」もAndroid SDKの一部ではありません。コメントが示すように、 'Context'で' getSystemService() 'を使ってシステムサービスを取得します。 – CommonsWare

+0

はい、システムによって登録されておらず、ServiceManagerによって追加されたサービスを探しています。コンテキストは私のためにそれを解決することはできません。 – Andriel

+0

'getSystemService(" service_name ")'への 'try/catch'呼び出しを呼び出し、呼び出しがシステムサービスへのハンドルを返すかどうかを確認してください!= null ... _"システムによって登録されておらず、ServiceManagerによって追加されたサービス"_ AFAIKサービスを追加することは、ServiceManagerに登録することと同じです。 – Onik

答えて

2

をこの答えは本当に後半が、上のメソッドにアクセスする別の方法です隠しクラスServiceManagerはリフレクションを使用しています。クラスのすべてのメソッドは静的なので、invokeメソッドに渡すためにオブジェクト参照は必要ありません。あなたは単にクラスインスタンスを渡すことができます。隠しクラスでクラスインスタンスを取得するには、もう少しリフレクションを使用できます。 例:

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(新しいインテント(this、YourServiceClass.class)); –

関連する問題