How to get the phone Object in Oreo Aosp Code - android

I want to write Api for getdataroaming method which is already there in Aosp.
Just now I have written code like this.
ContentResolver cr=mPhone.getContext().getContentResolver();
if (Settings.Secure.getInt(cr.getContentResolver(),Settings.Secure.DATA_ROAMING) == 1) {
//Data Roaming Enabled
flag = true;
} else {
// Data Roaming Disabled
flag = false;
}
how to get the phone object in separate java file.
if I used the context.
From where i will get this context?

Related

Dual SIM: auto-switch data to other SIM (system-app)

I'm working on a system app(signed with os signature),
I need to programmatically switch data between 2 SIMs. After spend a lot of time reading Settings app source code of AOSP (here)
I found that when you manually click on switch data in Settings app, this code executes:
(you can find it here)
public static void setMobileDataEnabled(Context context, int subId, boolean enabled,
boolean disableOtherSubscriptions) {
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
.createForSubscriptionId(subId);
final SubscriptionManager subscriptionManager = context.getSystemService(
SubscriptionManager.class);
telephonyManager.setDataEnabled(enabled);
if (disableOtherSubscriptions) {
final List<SubscriptionInfo> subInfoList =
subscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList != null) {
for (SubscriptionInfo subInfo : subInfoList) {
// We never disable mobile data for opportunistic subscriptions.
if (subInfo.getSubscriptionId() != subId && !subInfo.isOpportunistic()) {
context.getSystemService(TelephonyManager.class).createForSubscriptionId(
subInfo.getSubscriptionId()).setDataEnabled(false);
}
}
}
}
}
But when I tried this code, it just turned off the current data without turning on data on other SIM! I can also see in phone Settings app that data had been changed to the other SIM, and it's UI switch is on, but actually there is no network data(It seems like just UI had been changed, but still the default data remain on previous SIM card)
It seems I've missed something. Looking forward for your helps. Thanks!

Biometrics prompt (face authentication) when camera access is blocked (Android 12 - Pixel)

Android 12 came up with a new Privacy Settings to disable access to the Camera and Mic sensors, which is referred as Toggles in the docs.
As it is mentioned in the docs:
the system reminds the user that the device-wide toggle is turned off
However, it seems that it only reminds the user when requesting the Camera permission and not when trying to authenticate the user using biometrics (face authentication on Pixel phones, which guess what!? It uses the camera). [I'm using AndroidX biometrics library]
Is there any way to find out if the Camera access has been blocked by the user without requesting any permission?
I guess the note in the docs didn't take into account that the app might use face authentication:
Note: The toggles mentioned in this section shouldn't require changes to your app's logic, as long as you follow privacy best practices.
Notes:
You can't register a new face in Settings when camera access is blocked. The Settings app does not show any error, just a blank camera feed
I am using Pixel 4 (Android 12)
The feature 'Join Wi-Fi by scanning a QR code' does not work and neither shows a feedback to the user if Camera access is blocked (Pixel 5)
So, I also looking for a solution - a have a biometric library and few reports appear in DM with the same problem - FaceUnlock doesn't work on Pixel 4 when the camera 'muted'
For now, still now fix, but maybe my research can help someone.
1. I checked the new API for PrivacyToggle's.
Android 12 introduces a new SensorPrivacyManager with supportsSensorToggle() method - it returns TRUE in case of device able to 'mute' camera or mic.
val sensorPrivacyManager = applicationContext
.getSystemService(SensorPrivacyManager::class.java)
as SensorPrivacyManager
val supportsMicrophoneToggle = sensorPrivacyManager
.supportsSensorToggle(Sensors.MICROPHONE)
val supportsCameraToggle = sensorPrivacyManager
.supportsSensorToggle(Sensors.CAMERA)
If you look into SensorPrivacyManager, you can find that it provides some more useful methods, so I develop the next code:
fun isCameraAccessible(): Boolean {
return !checkIsPrivacyToggled(SensorPrivacyManager.Sensors.CAMERA)
}
#SuppressLint("PrivateApi")
private fun checkIsPrivacyToggled(sensor: Int): Boolean {
val sensorPrivacyManager: SensorPrivacyManager =
appContext.getSystemService(SensorPrivacyManager::class.java)
if (sensorPrivacyManager.supportsSensorToggle(sensor)) {
val userHandleField = UserHandle::class.java.getDeclaredField("USER_CURRENT")
userHandleField.isAccessible = true
val userHandle = userHandleField.get(null) as Int
val m = SensorPrivacyManager::class.java.getDeclaredMethod(
"isSensorPrivacyEnabled",
Int::class.javaPrimitiveType,
Int::class.javaPrimitiveType
)
m.isAccessible = true
return m.invoke(
sensorPrivacyManager,
sensor,
userHandle
) as Boolean
}
return false
}
Unfortunately, the service rejects this call due to SecurityException - missing android.permission.OBSERVE_SENSOR_PRIVACY, even if we declare it in Manifest.
At least on emulator.
2. We can try to identify a new "sensor-in-use" indicator
fun checkForIndicator(){
findViewById<View>(Window.ID_ANDROID_CONTENT)?.let {
it.setOnApplyWindowInsetsListener { view, windowInsets ->
val indicatorBounds = windowInsets.privacyIndicatorBounds
if(indicatorBounds !=null){
Toast.makeText(view.context, "Camera-in-use detected", Toast.LENGTH_LONG).show()
}
// change your UI to avoid overlapping
windowInsets
}
}
}
I didn't test this code (no real device), but as for me - it's not very useful, because we can check the camera indicator only AFTER we start Biometric Auth flow, when I need to understand is camera accessible BEFORE Biometric Auth started.
3. Because of PrivicyToogle related to QuickSettings, I decide that perhaps exists a way how Tiles determinate current Privacy Toggle state.
But this API use a very interesting solution - it does not use Settings.Global or Settings.Security section, instead, all preferences saved in "system/sensor_privacy.xml" and not accessible for 3rd party apps.
See SensorPrivacyService.java
I believe that exists a way how to find that Camera is blocked, but seems like some deeper research required
UPDATED 28/10/2021
So after some digging in AOSP sources, I found that APP_OP_CAMERA permission reflects the "blocking" state.
Just call if(SensorPrivacyCheck.isCameraBlocked()){ return } - this call also notify the system to show the "Unblock" dialog
Example
Solution:
#TargetApi(Build.VERSION_CODES.S)
#RestrictTo(RestrictTo.Scope.LIBRARY)
object SensorPrivacyCheck {
fun isMicrophoneBlocked(): Boolean {
return Utils.isAtLeastS && checkIsPrivacyToggled(SensorPrivacyManager.Sensors.MICROPHONE)
}
fun isCameraBlocked(): Boolean {
return Utils.isAtLeastS && checkIsPrivacyToggled(SensorPrivacyManager.Sensors.CAMERA)
}
#SuppressLint("PrivateApi", "BlockedPrivateApi")
private fun checkIsPrivacyToggled(sensor: Int): Boolean {
val sensorPrivacyManager: SensorPrivacyManager =
AndroidContext.appContext.getSystemService(SensorPrivacyManager::class.java)
if (sensorPrivacyManager.supportsSensorToggle(sensor)) {
try {
val permissionToOp: String =
AppOpCompatConstants.getAppOpFromPermission(
if (sensor == SensorPrivacyManager.Sensors.CAMERA)
Manifest.permission.CAMERA else Manifest.permission.RECORD_AUDIO
) ?: return false
val noteOp: Int = try {
AppOpsManagerCompat.noteOpNoThrow(
AndroidContext.appContext,
permissionToOp,
Process.myUid(),
AndroidContext.appContext.packageName
)
} catch (ignored: Throwable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
PermissionUtils.appOpPermissionsCheckMiui(
permissionToOp,
Process.myUid(),
AndroidContext.appContext.packageName
) else AppOpsManagerCompat.MODE_IGNORED
}
return noteOp != AppOpsManagerCompat.MODE_ALLOWED
} catch (e: Throwable) {
e.printStackTrace()
}
}
return false
}
}

How to check if the location service is enabled or not in Appcelerator

Can you please help me to check if the location service is enabled or not in Appcelerator.
I am working with Titanium SDk 6.1.2 and Samsung S5 with Marshmellow OS. Even though the GPS is enabled/not in device, But every time it results in false.
Thanks in Advance.
First of all you need to check for Location Permissions for app in Android & then you need to check if location service is enabled in device or not.
Both are different statements.
First one checks for app permission to access location & 2nd is about checking location service is on or off.
Without checking Location Permissions first on Android, you cannot check for location on/off state, else it will always lead to false status.
First of all add this in tiapp.xml in ios -> plist -> dict
<key>NSLocationAlwaysUsageDescription</key>
<string>Determine Current Location</string>
Now here's the cross-compatible code for Android/iOS.
function checkLocationEnabledOrNot(_callback, _args) {
if (Titanium.Geolocation.locationServicesEnabled) {
_callback(_args);
} else {
alert("Turn on location on your device.");
}
}
// pass _callback method you want to call after successful access to location
// you can also pass arguments as 2nd parameter to the function you want to call
function startLocationProcess(_callback, _args) {
Ti.Geolocation.accuracy = Ti.Geolocation.ACCURACY_HIGH;
if (OS_IOS) {
checkLocationEnabledOrNot(_callback, _args);
} else if (OS_ANDROID) {
if (Ti.Geolocation.hasLocationPermissions()) {
checkLocationEnabledOrNot(_callback, _args);
} else {
Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS, function (locationEvent) {
if (locationEvent.success) {
checkLocationEnabledOrNot(_callback, _args);
} else {
alert("Location permissions are required to access locations.");
}
});
}
}
}
Now, on a button click whatever you want to do after location check, you can simply do it like this:
function anotherFunction(name) {
alert(name);
}
$.someButton.addEventListener('click', function (e) {
startLocationProcess(anotherFunction, "Hello D.Ish");
});

Android UserManager: Check if user is owner (admin)

Im developing an app with the latest android version (4.2.1 API-Level 17) for tablets with multiuser capabilities.
I want to restrict certain features (like the access to the app preferences) to the owner of the tablet (that is the user who can add and remove other user accounts)
is there any way i can find out if the current user is the owner?
i read through the UserManager and UserHandle API docs but couldn't find a function that allows me to check for it.
have i missed something or is there another way to do that?
Similar but without reflection:
static boolean isAdminUser(Context context)
{
UserHandle uh = Process.myUserHandle();
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
if(null != um)
{
long userSerialNumber = um.getSerialNumberForUser(uh);
Log.d(TAG, "userSerialNumber = " + userSerialNumber);
return 0 == userSerialNumber;
}
else
return false;
}
You can create an extension property in Kotlin to make it simpler:
val UserManager.isCurrentUserDeviceOwner: Boolean
get() = if (SDK_INT >= 23) isSystemUser
else if (SDK_INT >= 17) getSerialNumberForUser(Process.myUserHandle()) == 0L
else true
Then, using it is as simple as the following:
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
if (userManager.isCurrentUserDeviceOwner) TODO() else TODO()
You can further reduce boilerplate by using global system services definitions that makes userManager and other Android System Services available anywhere in your Kotlin code, with code included in this library I made: https://github.com/LouisCAD/Splitties/tree/master/systemservices
After researching further i found out that the multiuser api is not functional yet, it cant really be used for anything. there is a hack though for checking if the user is the owner using reflections:
public boolean isCurrentUserOwner(Context context)
{
try
{
Method getUserHandle = UserManager.class.getMethod("getUserHandle");
int userHandle = (Integer) getUserHandle.invoke(context.getSystemService(Context.USER_SERVICE));
return userHandle == 0;
}
catch (Exception ex)
{
return false;
}
}
This works for me on the Nexus 7 and Nexus 10 with Android 4.2.1
Its very dirty. so i wouldnt recommend using it unless you are making an app thats device and version specific

Two checks of Content Resolver for Allow Mock Locations providing different results

I have the following code that evaluates to true in the emulator (OS 2.3.3) when "applications > settings > development > allow mock locations" is unchecked. I would expect the method to return false but it returns true.
public static boolean isMockLocationSet(Context context) {
if (Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) {
return false;
}
else {
return true;
}
}
The following change returns false, as expected (BTW what is better .equals or .ContentEquals?):
public static boolean isMockLocationSet(Context context) {
if (Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0")) { //.contentEquals("0")
return false;
}
else {
return true;
}
}
I prefer the first example because it should allow for cases where a null value may exist, assigning a default of 0 and still allowing execution of the logic without failure (in fact, I suspect this case may exist but have not proved it - e.g. a manufacturer implements Android without all the these settings established (i.e. some like Allow Mock Locations would begin their life as null)...waiting until a user check's the setting before writing a 1 (or 0 when unchecked) to the table).
So what is the problem? Well, I get the feeling from bug reports that different devices handle this check differently but not having access to all device types, I am looking for recommendations on how to handle generically / the best. Also, why would the first example not work?
Well I decided to simply use the following check:
public static boolean isMockLocationSet(Context context) {
if (Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).contentEquals("1")) {
return true;
}
else {
return false;
}
}
This method, of course, deals with the null case appropriately--returning false.
I cannot say why the code in the original question does not work...maybe a bug in the SDK.

Categories

Resources