How to get IMSI in Android 10 (Android Q) - java

I'm unable to get IMSI in Android 10.
The Code that I was using to fetch IMSI number is giving an exception. java.lang.SecurityException: getSubscriberId: The user 10099 does not meet the requirements to access device identifiers. I understand that from android 10, google has restricted this information and its not accessible to third party apps due to privacy concerns but I'm looking for a workaround. The code that I was using is:
private void getImsiNumber()
{
Utility.DEBUG_LOG(TAG,"+ getImsiNumber +");
if ( this.imsiNumber == null )
{
Utility.DEBUG_LOG(TAG,"step 1");
TelephonyManager telephonyManager = (TelephonyManager) DashboardContainer.this.getSystemService(Context.TELEPHONY_SERVICE);
Utility.DEBUG_LOG(TAG,"step 2");
try {
this.imsiNumber = telephonyManager.getSubscriberId();
Utility.DEBUG_LOG(TAG,"step 3");
if ( this.imsiNumber == null || this.imsiNumber.length() == 0 )
{
Utility.DEBUG_LOG(TAG,"imsiNumber:"+this.imsiNumber);
this.imsiNumber = "WiFi";
}
}
catch (Exception e )
{
Utility.DEBUG_LOG(TAG,"Exception:"+e.getMessage().toString());
}
Utility.DEBUG_LOG(TAG,"IMSI Number:"+this.imsiNumber);
SharedPref.write("imsiNumber",this.imsiNumber);
Constants.IMSI_NO = this.imsiNumber;
}
}

Related

Getting NMEA DATA in android

The current issue that I'm getting is that the OnNmeaListener is not returning the correct data from the NMEA using the GpsStatus.Listener therefore I tried the GNSS Status for the peace of mind, it ended up returning gibberish data , so I had to revert back to GpsStatus Listener. I also prior to using OnNmeaListener tried GpsStatus.NmeaListner and when used tried to add it to the GpsStatus Listener it would show up as an error and suggested that i typecast it to OnNmeaListener, when this is done and the app is built and all and then executed from the app, it would crash and then not work at all, and this is why i shifted to OnNmeaListener in the first place. Now to its credit the OnNmeaListener works just fine and doesn't crash at all, but the data it gives out is not at all accurate, I thought maybe this might have to be some sort of fault/error on the device side, I then proceeded to test it on two devices with different API levels of 25 and 28, On the the 25 Level device it just did not give half of the data whereas on the 28 level device the data is full but not accurate and correct.
This is the method that I'm currently using:
OnNmeaMessageListener nmeaMessageListener = new OnNmeaMessageListener () {
#Override
public void onNmeaMessage(String nmea , long timestamp) {
if (trackStarted == true && trackPaused == false) {
if (nmea.startsWith ( "$GPGGA" ) || nmea.startsWith ( "$GPRMC" )) {
//Log.d("TrackManagerService","NMEA:" + nmea);
try {
// out.write(nmea.getBytes());
if (continuesMode) {
dataOut.write ( nmea.getBytes () );
bufferedNMEALines++;
if (bufferedNMEALines >= 10) {
flushContinuesTrack ();
//dataOut.reset();
bufferedNMEALines = 0;
}
} else {
outCompressed.write ( nmea.getBytes () );
}
// Log.d("TrackManagerService","NMEA:" + nmea);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace ();
}
if (nmea.startsWith ( "$GPGGA" )) {
String[] nmeaSplit = nmea.split ( "," );
if (nmeaSplit.length > 10) {
if (nmeaSplit[9].length () > 0) {
try {
mslAltitude = Float.parseFloat ( nmeaSplit[9] );
} catch (NumberFormatException ex) {
mslAltitude = 0;
}
} else {
mslAltitude = 0.0f;
}
}
}
}
//if (markStarted && hasFix() && nmea.startsWith("$GPGGA")) {
if (markStarted && hasFix () && nmea.startsWith ( "$GPRMC" )) {
markProgress++;
trackListener.onMarkProgress ( markProgress );
if (markProgress >= markMax) {
stopMark ();
}
}
}
}
};
And this is the output it gives when called:
$Start,082719,260220;
$GPGGA,082721.42,2654.2979,N,08056.6065,E,0,100.000,0.000,M,M,0,*44
$GPRMC,082721.42,V,2654.2979,N,08056.6065,E,0.000,0.000,260220,E,N*01
$GPGGA,082722.41,2654.2979,N,08056.6065,E,0,100.000,0.000,M,M,0,*44
$GPRMC,082722.41,V,2654.2979,N,08056.6065,E,0.000,0.000,260220,E,N*01
$End,082802,260220;
$Start,082804,260220;
$GPGGA,082837.42,2654.2979,N,08056.6065,E,0,100.000,0.000,M,M,0,*4C
$GPRMC,082837.42,V,2654.2979,N,08056.6065,E,0.000,0.000,260220,E,N*09
$GPGGA,082838.42,2654.2979,N,08056.6065,E,0,100.000,0.000,M,M,0,*43
$GPGGA,082840.42,2654.2979,N,08056.6065,E,0,100.000,0.000,M,M,0,*4C
$End,082841,260220;
$Start,082921,260220;
$GPGGA,082923.40,2654.2982,N,08056.6059,E,0,100.000,0.000,M,M,0,*41
$GPRMC,082923.40,V,2654.2982,N,08056.6059,E,0.000,0.000,260220,E,N*04
$GPGGA,082924.40,2654.2982,N,08056.6059,E,0,100.000,0.000,M,M,0,*46
$GPRMC,082945.40,V,2654.2982,N,08056.6059,E,0.000,0.000,260220,E,N*04
$End,082945,260220;
And this is the output when called using GNSS listener:
$Start,080450,260220;������������������������������������������������������������������������������������������������������������������������������������������������������������������
Any Sort of way to make this works?
[EDIT]
This is the response from an iOS device, which was accepted by the sever:
$Start,150403,250220;
$GPGGA,150403.69,2654.29986954,N,8056.60312653,E,1,00,0.0,0.0,0,0.0,0,0.0,0000*42;
$GPRMC,150743.99,A,2654.29986954,N,8056.60260391,E,0.0,0.0,250220,0.0,E,A*5;
$GPRMC,150844.26,A,2654.29986954,N,8056.60260391,E,0.0,0.0,250220,0.0,E,A*9;
$GPRMC,150937.91,A,2654.30012894,N,8056.60312653,E,0.0,0.0,250220,0.0,E,A*e;
$GPGGA,150945.04,2654.30429840,N,8056.60781097,E,1,00,0.0,0.0,0,0.0,0000*42;
$GPRMC,150952.01,A,2654.29921722,N,8056.60364532,E,0.0,0.0,250220,0.0,E,A*2;
$End,150953,250220;
$GPGGA,150953.00,2654.29921722,N,8056.60364532,E,1,00,0.0,0.0,0,0.0,0000*42;
$GPRMC,150953.00,A,2654.29921722,N,8056.60364532,E,0.0,0.0,250220,0.0,E,A*2;
Now, I DO NOT have the faintest idea how this works on an iOS device,(a Senior of mine worked on that and gave me this data) but somehow it worked on that and when the same logic was implemented on Android and the data was uploaded to the server it wouldn't accept it, whereas when the iOS data was manipulated in any sort of way ( removing lines, addlines, removing semi-colons, commas,etc.) it would somehow still work.

Can the accessibility "Magnification Gesture" be detected on Android?

I've got a game app and it requires repeated tapping. Some players are complaining that it doesn't work when they have the "triple tap to zoom" accessibility gesture enabled on their device.
Web search showed me that it can't be disabled within my game, but can it be detected? At least then I can explain to users how to turn it off while playing.
I'm not sure which android API I could use to check this setting. I'm not a native android developer, I work in Unity and Google isn't turning up anything.
Thanks to zcui93, I was able to test for this setting using the following Java:
Settings.Secure.getInt( context.getContentResolver(), "accessibility_display_magnification_enabled" );
...just check the return value: 1 = enabled, 0 = disabled
Here's the code to do it in a Unity C# Script:
public static bool CheckForSystemZoomEnabled()
{
#if UNITY_ANDROID
try {
using(AndroidJavaClass clsUnity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject objActivity = clsUnity.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject objResolver = objActivity.Call<AndroidJavaObject>("getContentResolver");
using(AndroidJavaClass clsSecure = new AndroidJavaClass("android.provider.Settings$Secure"))
{
int val = clsSecure.CallStatic<int>("getInt", objResolver, "accessibility_display_magnification_enabled");
return val != 0;
}
}
} catch(System.Exception) { }
#endif
return false;
}

How to make google maps coordinates works on specific country. - Android

I am android developer, and i am working on application such as Uber, Careem, etc.
I have a functionality using the google map, to let the user to set his own marker on particular confidantes.
The problem here is my application is just works on Saudi Arabia only and Jeddah city to be exact. and i am not support any other countries or city expect the above.
I need a solution when the user drop down his marker to display a pop up or something telling him that we are not support this area yet.
Is there any solution.
Thanks,
/**
* Get ISO 3166-1 alpha-2 country code for this device (or null if not available)
* #param context Context reference to get the TelephonyManager instance from
* #return country code or null
*/
public static String getUserCountry(Context context) {
try {
final TelephonyManager mTelephonyManager= (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
final String simCountry = mTelephonyManager.getSimCountryIso();
if (simCountry != null && simCountry.length() == 2) { // SIM country code is available
return simCountry.toLowerCase(Locale.US);
}
else if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) { // device is not 3G (would be unreliable)
String networkCountry = mTelephonyManager.getNetworkCountryIso();
if (networkCountry != null && networkCountry.length() == 2) { // network country code is available
return networkCountry.toLowerCase(Locale.US);
}
}
}
catch (Exception e) { }
return null;
}

Why i get result.get(CaptureResult.CONTROL_AF_STATE); == INACTIVE?

I work with camera2API on Samsung S5 and if i try get state of focus i get value 0 which is equals to CaptureResult.CONTROL_AF_STATE_INACTIVE...
There is snip of code :
private void process(CaptureResult result) {
switch (mState) {
case CameraHelper.STATE_PREVIEW: {
// We have nothing to do when the camera preview is working normally.
here i get ---> Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (CaptureResult.CONTROL_AF_TRIGGER_START == afState) {
if (areWeFocused) {
Log.e("---!!! HERE !!!--- :", String.valueOf(areWeFocused));
}else {
}
}
if (CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState) {
areWeFocused = true;
} else {
areWeFocused = false;
}
break;
}
But i also tried to test it on my Meizu MX5 and i get 1 - CaptureResult.CONTROL_AF_TRIGGER_START or 2 - CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED
Question is : what is the difference in my code? Why do i get 0 in one case and 1 or 2 in another?
I know this is an old question, but i just ran into the same issue. Read through the Android docs about ControlAfState (AF = Auto Focus for those who are unaware, like I was). If AutoFocus Mode (afMode) is set to AF_MODE_OFF you will get the ControlAfState of Inactive.
Android CaptureResult.CONTROL_AF_STATE

Getting device/driver information related to a COM port?

I have a Serial-to-USB device with a similarly named device driver in the Windows device manager. The devices do not always grab the same COM port on system boot, so my program needs to identify it on start up.
I've tried using RXTX to enumerate the COM ports on the system, but this didn't work because CommPortIdentifier.getName() simply returns the COM name (eg. COM1, COM2, etc.) I need to acquire either the driver manufacturer name, or the driver name as it appears in the device manager, and associate it with the COM name.
Can this easily be done in Java? (I'd be interested in any 3rd party Java libraries that support this.) Otherwise, how I could begin to accomplish this via the win32 API?
I achieved what I wanted by using the WinRegistry class provided by David in this SO question to obtain the FriendlyName from registry key associated with my USB device. I then parse out the COM number from the friendly name.
Some things to consider:
USB devices are located at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\ in the registry (tested on WinXP, Win7.)
I required the device VID + PID to identify the correct device key (eg. VID_xxxx&PID_xxxx.) Since VID and PID are device specific, this key should be reliable across multiple systems.
The VID_xxxx&PID_xxxx key contains another sub-key with device values. I had some trouble enumerating the sub-keys with WinRegistry, so I hard-coded the sub-key name as a quick hack during development. A much safer solution would search sub-keys to find the correct name.
The device keys exist in the registry regardless of whether the device is currently connected. This code makes the assumption that Windows will update FriendlyName if the device is reconnected to a different COM port. I haven't verified this, but things looked good during use-testing.
Example
String keyPath = "SYSTEM\\CurrentControlSet\\Enum\\USB\\Vid_067b&Pid_2303\\";
String device1 = "5&75451e6&0&1";
System.out.println("First COM device: " + getComNumber(keyPath + device1));
Code
import java.util.regex.Pattern;
import java.util.regex.Matcher;
// Given a registry key, attempts to get the 'FriendlyName' value
// Returns null on failure.
//
public static String getFriendlyName(String registryKey) {
if (registryKey == null || registryKey.isEmpty()) {
throw new IllegalArgumentException("'registryKey' null or empty");
}
try {
int hkey = WinRegistry.HKEY_LOCAL_MACHINE;
return WinRegistry.readString(hkey, registryKey, "FriendlyName");
} catch (Exception ex) { // catch-all:
// readString() throws IllegalArg, IllegalAccess, InvocationTarget
System.err.println(ex.getMessage());
return null;
}
}
// Given a registry key, attempts to parse out the integer after
// substring "COM" in the 'FriendlyName' value; returns -1 on failure.
//
public static int getComNumber(String registryKey) {
String friendlyName = getFriendlyName(registryKey);
if (friendlyName != null && friendlyName.indexOf("COM") >= 0) {
String substr = friendlyName.substring(friendlyName.indexOf("COM"));
Matcher matchInt = Pattern.compile("\\d+").matcher(substr);
if (matchInt.find()) {
return Integer.parseInt(matchInt.group());
}
}
return -1;
}
#robjb Your code does not allow for more than one device to be connected. How will the user know the device name? I added to your code thus to return a list of com ports:
ArrayList<String> subKeys = WinRegistry.readStringSubKeys(WinRegistry.HKEY_LOCAL_MACHINE, keyPath);
ArrayList<Integer> comPorts = new ArrayList<Integer>();
for (String subKey : subKeys) {
String friendlyName = getFriendlyName(keyPath + subKey);
if (friendlyName != null && friendlyName.contains("MyDriverName") && friendlyName.contains("COM")) {
int beginIndex = friendlyName.indexOf("COM") + 3 /*length of 'COM'*/;
int endIndex = friendlyName.indexOf(")");
comPorts.add(Integer.parseInt(friendlyName.substring(beginIndex, endIndex)));
}
}
Update: I don't think these are solutions. Why? This information is statically stored in the registry - even when the device is not connected.
Great example, using JNA, here.
The author (Geir Arne Ruud) has released it under Public Domain License.
My example code
public static String getFriendlyName(GoGPSModel model, String name)
{
if(model.getSystem().getOSType() != OSType.Windows32
&& model.getSystem().getOSType() != OSType.Windows64) {
return name;
}
for (DeviceInformation devInfo : infoObjects) {
System.out.println(devInfo.toString());
String friendlyName = devInfo.getFriendlyName();
if(friendlyName != null && !friendlyName.equals("") && friendlyName.contains(name)) {
return devInfo.getManufacturer() + ": " + friendlyName;
}
}
return name;
}

Categories

Resources