Android introduced @SystemApi in its SDK source code recently. Seems like same in effect as the @hide annotation before, since they also got stripped from SDK jar classes.
@SystemApi
, @PrivateApi
and @hide
According to this commit, @SystemApi
is a rename of the old @PrivateApi
. APIs marked @hide
are not necessarily @SystemApi
, but @SystemApi
requires @hide
.
For more information about @hide
javadoc annotation, this post gives a good answer.
Based on my own experiments, one (non-system application) can still access @hide
APIs and fields using Java reflection like (from this post):
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiConfiguration config = new WifiConfiguration();
config.SSID = "AccessPointSSID";
Method method = manager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method.invoke(manager, config, true);
But trying to access @SystemApi
things using Java reflection is impossible (following code will trigger invocationTargetException):
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
Method method = manager.getClass().getMethod("getPrivilegedConfiguredNetworks");
List<WifiConfiguration> configs = (List<WifiConfiguration>)method.invoke(manager);
In the WifiManager java code, the setWifiApEnabled
and getPrivilegedConfiguredNetworks
APIs are defined as:
/**
* Start AccessPoint mode with the specified
* configuration. If the radio is already running in
* AP mode, update the new configuration
* Note that starting in access point mode disables station
* mode operation
* @param wifiConfig SSID, security and channel details as
* part of WifiConfiguration
* @return {@code true} if the operation succeeds, {@code false} otherwise
*
* @hide Dont open up yet
*/
public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
try {
mService.setWifiApEnabled(wifiConfig, enabled);
return true;
} catch (RemoteException e) {
return false;
}
}
and
/** @hide */
@SystemApi
public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
try {
return mService.getPrivilegedConfiguredNetworks();
} catch (RemoteException e) {
return null;
}
}
Methods annotated with @SystemApi are a subset of ones with @hide. It's apparently an indicator for internal teams (perhaps also partners) that these methods are actual APIs, although not for public developers.
As a result, @SystemApi methods will be more stable than @hide ones, which could be changed at any time in the future without any compatibility consideration, and also any OEM is allowed to change them at their own will.
If you are trying to invoke internal APIs via reflection, always prefer @SystemApi methods for better future compatibility.