如何从 Android 中的 ServiceManager 获取服务?

How to get a service from ServiceManager in Android?

我对 ServiceManager 注册的服务有疑问,而 SystemServiceRegistry 没有注册。

SystemServiceRegistry

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

也就是说System注册的服务可以从Context中得到他的引用

关注 ServiceManager,我如何在未通过 SystemServiceRegistry 注册的应用程序中访问 ServiceManager 添加的服务?

正如@CommonsWare 正确提到的,您需要在上下文中使用 getSystemService()。 例如。获取定位服务:

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

对于您的自定义服务使用(假设您的服务已在 AndroidManifest.xml 中注册):

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

这个答案确实晚了,但是另一种访问 Hidden class ServiceManager 上的方法的方法是使用反射。由于 class 上的所有方法都是静态的,因此您不需要将对象引用传递给 invoke 方法。您可以简单地传入 class 实例。为了在隐藏的 class 上获得 class 实例,您可以使用更多的反射。 示例:

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 没有暴露的充分理由,但有一些有效的用例可以使用它。如果您不经常调用反射代码,性能影响并不严重,如果您是,您可以缓存这些方法,这样您就不必在每次调用时都执行查找。话虽如此,如果您真的需要访问非 public API 的

,请小心并分析