Wifi Hotspot creation fails in oreo - java

I'm working on a simple system app in Oreo AOSP to turn ON wifi Hotspot with predefined SSID and preshared key.
As my APP is built as a system app so i don't need reflection.
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean result = false;
WifiManager mwifiManager;
mwifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
try {
Method method = mwifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration netconfig = (WifiConfiguration) method.invoke(mwifiManager);
netconfig.SSID = "DummyApp";
netconfig.preSharedKey = "1234567890";
netconfig.allowedKeyManagement.set(4);
mwifiManager.setWifiEnabled(false);
method = mwifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
result = (boolean) method.invoke(mwifiManager, netconfig, true);
if (!result) {
Toast.makeText(this, "Hotspot creation failed", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Wifi Enabled", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
finish();
}
#Override
protected void onResume() {
super.onResume();
}
}
AndroidManifest.xml
android:protectionLevel="signature|privileged"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- for wifi -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
Wifi Should turn ON but getting following result:
Toast Message: Hotspot creation failed
Logcat: WifiManager: PACKAGE_NAME attempted call to setWifiApEnabled: enabled = true
update1: How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)
I have tried above changes. It will turn on Hotspot locally but no custom SSID and password.
update2: After getting input from #Mr.AF.
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
......code snip.........
netconfig.allowedKeyManagement.set(4);
Method Method = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
HOTSPOT Creation FAiled

To turn ON Portable HotSpot in Android Nougat and below following code works.
Method method = mwifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration netconfig = (WifiConfiguration) method.invoke(mwifiManager);
method = mwifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
result = (boolean) method.invoke(mwifiManager, netconfig, true);
Above API is deprecated in Oreo.
Following is a #system hidden API in oreo, If the android application is built as a system app then only below API code can be accessed. In my case, I can use the below API.
ConnectivityManager oncm = (ConnectivityManager)ontext.getSystemService(Context.CONNECTIVITY_SERVICE);
oncm.startTethering(ConnectivityManager.TETHERING_WIFI, true, new ConnectivityManager.OnStartTetheringCallback() {
#Override
public void onTetheringStarted() {
super.onTetheringStarted();
Log.i(TAG, "Hotspot is successfully opened");
}
#Override
public void onTetheringFailed() {
super.onTetheringFailed();
Log.e(TAG, "Hotspot failed to open");
}
});

You don't need to use reflection for versions>=Oreo. After android's public exposed API startLocalOnlyHotspot. I've explained this answer in detail on this question on Stackoveflow.

Related

How to get BLE devices' names list by android app?

Hello I am making a bluetooth connecting android app.
I followed the instruction from developer.android.com
while I am testing my app, I look forward to it works properly, but it didn't.
I tried to get detected BLE devices names, but don't know the reason why it doesn't show me the devices name...
Arduino nano 33 IOT is adverstising bluetooth next to my android phone, and I am trying to detect it and get the Adrduino's BLE device name and address.
here is my MainActivity.java
public class MainActivity extends AppCompatActivity {
//View Contents Elements
public Button btnActivateBluetooth;
public Button btnSearchBluetooth;
public Button btnSendData;
public ListView lvSearchedDevice;
public ListView lvLog;
public TextView tvStatus;
public EditText etData;
//etc values
public ArrayAdapter<String> logAdapter;
private final int REQUEST_ENABLE_BT = 1;
private boolean mScanning = true;
//bluetooth values
public BluetoothAdapter btAdapter;
public BluetoothManager btManager;
private Handler handler;
#SuppressLint("MissingPermission")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//View Elements
btnSearchBluetooth = (Button) findViewById(R.id.btnSearchBluetooth);
btnSendData = (Button) findViewById(R.id.btnSendData);
lvSearchedDevice = (ListView) findViewById(R.id.lvSearchedDevice);
lvLog = (ListView) findViewById(R.id.log);
tvStatus = (TextView) findViewById(R.id.tvStatus);
etData = (EditText) findViewById(R.id.etData);
//etc
logAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
lvLog.setAdapter(logAdapter);
handler = new Handler();
// Initializes Bluetooth adapter.
btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
// displays a dialog requesting user permission to enable Bluetooth.
if (btAdapter == null || !btAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
btnSearchBluetooth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
scanLeDevice(true);
}
});
}
//Scan devices
#SuppressLint("MissingPermission")
private void scanLeDevice(final boolean enable){
if(enable){
handler.postDelayed(new Runnable() {
#SuppressLint("MissingPermission")
#Override
public void run() {
btAdapter.stopLeScan(leScanCallback);
}
},5000);
btAdapter.startLeScan(leScanCallback);
}
else
{
btAdapter.stopLeScan(leScanCallback);
}
}
//Callback method
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#SuppressLint("MissingPermission")
#Override
public void run() {
Toast.makeText(MainActivity.this, device.getName(), Toast.LENGTH_SHORT).show();
}
});
}
};
}
and this is my Arduino nano 33 IOT's code.
#include <ArduinoBLE.h>
BLEService Toothbrush("00001101-0000-1000-8000-00805F9B34FB");
BLEStringCharacteristic ToothbrushChar("00001101-0000-1000-8000-00805F9B34FB",BLEWrite|BLERead | BLENotify, 10);
void setup() {
Serial.begin(9600);
if(!BLE.begin()){
Serial.println("Starting BLE failed.");
while(1);
}
BLE.setLocalName("HayanToothbrush");
BLE.setAdvertisedService(Toothbrush);
Toothbrush.addCharacteristic(ToothbrushChar);
BLE.addService(Toothbrush);
BLE.advertise();
Serial.println("Bluetooth device active, wating for connections...");
}
void loop() {
BLEDevice central = BLE.central();
if(central) {
Serial.print("Connected to central : ");
Serial.println(central.address());
while(central.connected()){
}
Serial.print("Disconnected from central:");
Serial.println(central.address());
}
}
I add permissions in the Mainfest as below.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.bluetooth0523">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Bluetooth0523"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
But it still doesn't find me scanned device name.
I think it's on LeScanCallBack problem.
When running startLeScan, It seems not running callback method.
in addition, I am running this app on SDK_VERSION_30
and Arduino nano IOT 33 is discoverable If I use the Bluetooth function that my phone has, not my application, it will be displayed in the scan result list.
I want to get scan result on my own app.
but don't know where is the problem.
Permissions must be declared and requested depending on Android version. Main differences are:
Target Android 12 or higher
BLUETOOTH_SCAN
Target Android 11 or lower
ACCESS_FINE_LOCATION
See Bluetooth permissions for details.

Android wifi state permission

My app is communicating with another device by wifi.
I tried to ask all permissions at app's start, but is never asked about wifi.
By the way, every time I need to change wifi, user must give permission.
How can I ask for change wifi state permission once and never bother user again?
Sample of code that I used to change wifi is below
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = String.format("\"%s\"", ssid);
if (!key.equals(""))
wifiConfig.preSharedKey = String.format("\"%s\"", key);
final int netId = wifiManager.addNetwork(wifiConfig);
Log.d("Network ID", Integer.toString(netId));
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
The permission my phone is asked about below
It is Russian. Translation is "Would you give this app a permission to turn on/turn off WIFI?".
I tested it on another phone, and it keeps happening. Both phones is xiaomi and have their own android version MIUI.
Add this code snippet in AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
And use this code:
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(false); // activate/deactivate wifi
You only need to declare it in AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Android > 6.0 user prompted runtime permission is NOT required for CHANGE_WIFI_STATE, because it is one of the safe ones.
If something is still goes wrong, please provide code sample which you are using.
UPD:
Tested your code on Samsung J5 with Android 6.0 and everithing works fine.
Also you are using deprecated methods. You need to use something like this for >= Android.O
In manifest:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
And code:
WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
builder.setSsid("SSID");
builder.setWpa2Passphrase("PASSWORD");
WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
NetworkRequest.Builder networkRequestBuilder1 = new NetworkRequest.Builder();
networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier);
NetworkRequest nr = networkRequestBuilder1.build();
final ConnectivityManager cm = (ConnectivityManager)
getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager.NetworkCallback networkCallback = new
ConnectivityManager.NetworkCallback() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onAvailable(Network network) {
super.onAvailable(network);
Log.d("TEST", "onAvailable:" + network);
cm.bindProcessToNetwork(network);
}
};
cm.requestNetwork(nr, networkCallback);

ConnectivityManager can't requestNetwork/bindProcessToNetwork in Oreo

After developing a working system in 6.0 (S6) I'm testing the same code in 8.0 (S9) and I've noticed that ConnectivityManager.requestNetwork() is no longer doing anything.
Here is the function I'm using:
public static void enableWifi() {
ConnectivityManager connectivityManager = (ConnectivityManager)
mContext.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder request = new NetworkRequest.Builder();
request.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
request.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
connectivityManager.requestNetwork(
request.build(),
new ConnectivityManager.NetworkCallback() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onAvailable(Network network) {
connectivityManager.bindProcessToNetwork(network);
Log.i(TAG, "bindProcessToNetwork called");
}
},
30000
);
}
after calling this function, I check to see whether the connection has been switched to Wifi for 20 seconds:
wifiManager.setWifiEnabled(true);
enableWifi();
long start_time = System.currentTimeMillis();
while (!MainActivity.getNetworkClass(mContext).contains("WIFI")) {
if (System.currentTimeMillis() - start_time > 20000) {
Log.i(TAG, "connection timed out");
}
}
After the timeout I'm still on the 4G network, wifi is never truly enabled. All logs shown above are called, yet the network state never changes to Wifi.
The manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Edit:
After much frustration I was able to establish a connection once using this setup, but not again since. I am not sure where to even begin troubleshooting this and assume it's a bug in 8.0 until I find otherwise.

Geofence registration was successful, but geofence does not call onHandleIntent

I register geofence this way:
GeofencingClient client = LocationServices.getGeofencingClient(context);
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofence(new Geofence.Builder()
.setRequestId(buildRequestId(objectId))
.setCircularRegion(location.getLatitude(), location.getLongitude(), 500)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
client.addGeofences(builder.build(), PendingIntent.getService(context, objectId,
new Intent(context, HomeGeofenceService.class).putExtra(KEY_OBJECT_ID, objectId), PendingIntent.FLAG_UPDATE_CURRENT)).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
ObjectManager.getInstance(objectId).setLocationNotifEnabled(false);
ObjectManager.save();
int statusCode = -1;
if (e instanceof ApiException)
statusCode = ((ApiException) e).getStatusCode();
context.sendBroadcast(new Intent(UiConstants.ACTION_GEOFENCE_ERROR).putExtra(KEY_CODE, statusCode));
}
});
Service in manifest:
<service android:name=".services.HomeGeofenceService"/>
play services version: implementation 'com.google.android.gms:play-services-location:15.0.1'
Service:
public class HomeGeofenceService extends IntentService {
public HomeGeofenceService() {
super(HomeGeofenceService.class.getSimpleName());
}
protected void onHandleIntent(Intent intent) { /***some code**/ }
}
List of permissions:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
targetSdkVersion 27
This code was working fine in our app from April 19th. Can this issue be connected to the fact that we're in russian region? With all IP bans. Or maybe there is some other issue here?

IOException Unable to resolve host,No address associated with hostname

I am working on Sony Remote camera which is connected using WiFi.I need to click a picture using a camera and then upload it to my FTP server which is in another activity.for than I need to disconnect my camera wifi and connect to the another wifi network or mobile data.when I connect to the another wifi/mobile data and going to upload the picture on FTP server I got this error.
IOException Unable to resolve host No address associated with hostname
When a close application and start again, And then directly upload pictures without connecting/disconnection camera than it works fine.
someone, please tell me how can I solve this, because I checked each and every solution on stack overflow and not one solution work for me.
I added bellow permissions
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
Connection to a network is not inmediate.
Also, if the desired network has no internet connection, in recent versions of Android it will not connect (if the connection is made by a user, a popup shows a confirmation to connnect).
I solved both problems using Android APIs (2 versions, one for API<21 and the other for API>=21).
Try this code (I'm using AndroidAnnotations for dependency injection, but is not required):
public class WifiHelper extends BroadcastReceiver {
#RootContext
Context context;
#SystemService
ConnectivityManager connectivityManager;
#SystemService
WifiManager wifiManager;
// For API>=21
private WifiHelperNetworkCallback wnc;
// For API<21
private boolean isBroadcastRegistered;
private String desiredSSID;
private Runnable callback;
public void enableNetwork(String ssid, int networkId, Runnable callback) {
desiredSSID = ssid;
wifiManager.enableNetwork(networkId, true);
configureNetworkRequest();
}
private void networkAvailable() {
// this method will be called when the network is available
callback.run();
}
private void configureNetworkRequest() {
if (android.os.Build.VERSION.SDK_INT >= 21) {
configureNetworkRequestAPI21();
} else {
configureNetworkRequestLegacy();
}
}
#TargetApi(21)
private void configureNetworkRequestAPI21() {
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
if (wnc == null) wnc = new WifiHelperNetworkCallback(this, connectivityManager);
connectivityManager.requestNetwork(request, wnc);
}
private void configureNetworkRequestLegacy() {
unregisterReceiver();
connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, null);
IntentFilter intent = new IntentFilter();
intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intent.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
context.registerReceiver(this, intent);
isBroadcastRegistered = true;
}
#TargetApi(21)
private void disableNetworkRequest() {
if (android.os.Build.VERSION.SDK_INT >= 21) {
if (wnc != null) connectivityManager.unregisterNetworkCallback(wnc);
ConnectivityManager.setProcessDefaultNetwork(null);
} else {
unregisterReceiver();
}
}
private void unregisterReceiver() {
if (isBroadcastRegistered) {
context.unregisterReceiver(this);
isBroadcastRegistered = false;
}
}
// API<21
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo networkInfo =
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if(networkInfo.isConnected()) {
// Wifi is connected
if (desiredSSID.equals(getCurrentSSID())) {
// Callback and unregister
networkAvailable();
unregisterReceiver();
}
}
}
}
public String getCurrentSSID() {
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if (wifiInfo != null && wifiInfo.getSupplicantState()== SupplicantState.COMPLETED) {
return ssidWithoutQuotes(wifiInfo.getSSID());
}
else return null;
}
protected static String ssidWithoutQuotes(String ssid) {
if (ssid == null) return null;
else if (ssid.startsWith("\"") && ssid.endsWith("\"")) {
return ssid.substring(1, ssid.length() - 1);
} else {
return ssid;
}
}
protected String getDesiredSSID() {
return desiredSSID;
}
#TargetApi(21)
public static class WifiHelperNetworkCallback extends ConnectivityManager.NetworkCallback {
public final String LOG_TAG = WifiHelper.class.getSimpleName();
private ConnectivityManager connectivityManager;
private WifiHelper wifiHelper;
public WifiHelperNetworkCallback(WifiHelper wifiHelper, ConnectivityManager connectivityManager) {
this.wifiHelper = wifiHelper;
this.connectivityManager = connectivityManager;
}
public void onAvailable(Network network) {
// Do something once the network is available
NetworkInfo info = connectivityManager.getNetworkInfo(network);;
Log.i(LOG_TAG, "networkcallback!! " + info.getExtraInfo());
String desiredSSID = wifiHelper.getDesiredSSID();
if (desiredSSID != null && desiredSSID.equals(ssidWithoutQuotes(info.getExtraInfo()))) {
ConnectivityManager.setProcessDefaultNetwork(network);
wifiHelper.networkAvailable();
}
}
}
}
You will need this permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" android:maxSdkVersion="18"/>

Categories