2017-01-11 2 views
1

ServiceManager에서 등록한 서비스가 의심 스럽지만 SystemServiceRegistry에서 등록하지 않는 것이 좋습니다. 시스템에 의해 등록 된 서비스를 의미 SystemServiceRegistry안드로이드에서 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. 
    } 
} 

거의 숨겨진 또는 개인 메소드에 액세스하기 위해 필요한 모든 (개인 방법이기는하지만, 당신은 방법의 접근을 수정해야합니다). 안드로이드에서 리플렉션이 좋지 않다는 것을 알고 있습니다. 일반적으로 일부 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)); –