Comprender el comando a través de adb shell y a través del código – Android

Estoy tratando de dar permiso BATTERSTATS a una aplicación. Cuando ejecuto el comando desde una PC, funciona bien:

 adb shell pm grant com.example.sample.myapplication android.permission.BATTERY_STATS 

Pero el mismo comando de pm grant no funciona cuando se ejecuta desde la aplicación de Android:

 java.lang.Process process = Runtime.getRuntime().exec("pm grant com.example.sample.myapplication android.permission.BATTERY_STATS"); 

¿Requiere un permiso de root para otorgar este permiso? Si es así, ¿por qué no es necesario enrutar el dispositivo para ejecutarlo a través de adb shell ?

Soy nuevo en Android. Explique con más claridad qué está sucediendo en el interior y cómo proceder.

El comando que ejecuta con adb shell se ejecuta con privilegios de usuario de shell(UID=2000) . El comando que ejecuta desde su código java se ejecuta con los privilegios UID su aplicación. Por lo tanto, la diferencia.