How to get default sim card number android programmatically - android

To send sms programmatically I am using,
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(toNumber, null, text, PendingIntent.getBroadcast(
this, 0, new Intent(SMS_SENT_ACTION), 0), null);
I have coded for api >=22 like,
SubscriptionManager subscriptionManager=(SubscriptionManager)getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subscriptionInfoList=subscriptionManager.getActiveSubscriptionInfoList();
if(subscriptionInfoList!=null && subscriptionInfoList.size()>0){
for(SubscriptionInfo info:subscriptionInfoList){
String mobileNo=info.getNumber();
}
}
using subscription manager I am not getting sim 2 card number using info.getNumber();. It returns empty for Samsung j5 device.
Another important thing is, using SubscriptionManager I am getting line 1 number correctly but empty for line 2. But at the same time when I am trying to send sms using SmsManager.getDefault() it sends sms from line 2. In that device line 2 sim card is set as default.
But based on operators available in a dual sim device toNumber (the number to send sms) will be changed. Because of this I need to know operator name or sim card number of default sim of the device set by user to the number SmsManager.getDefault(). How can I get it know?

This is how you should get it (link here):
Get the SmsManager associated with the default subscription id. The
instance will always be associated with the default subscription id,
even if the default subscription id changes.
Note: For devices that support multiple active subscriptions at a
time, SmsManager will track the subscription set by the user as the
default SMS subscription. If the user has not set a default,
SmsManager may start an activity to kick off a subscription
disambiguation dialog. Most operations will not complete until the
user has chosen the subscription that will be associated with the
operation. If the user cancels the dialog without choosing a
subscription, one of the following will happen, depending on the
target SDK version of the application. For compatibility purposes, if
the target SDK level is <= 28, telephony will still send the SMS over
the first available subscription. If the target SDK level is > 28, the
operation will fail to complete.
Note: If this method is used to perform an operation on a device that
has multiple active subscriptions, the user has not set a default SMS
subscription, and the operation is being performed while the
application is not in the foreground, the SMS disambiguation dialog
will not be shown. The result of the operation will conclude as if the
user cancelled the disambiguation dialog and the operation will finish
as outlined above, depending on the target SDK version of the calling
application. It is safer to use getSmsManagerForSubscriptionId(int) if
the application will perform the operation while in the background
because this can cause unpredictable results, such as the operation
being sent over the wrong subscription or failing completely,
depending on the user's default SMS subscription setting.
So, the code would be:
val subscriptionManager = applicationContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
val defaultSubscriptionId = SmsManager.getDefaultSmsSubscriptionId()
val smsManager = SmsManager.getSmsManagerForSubscriptionId(defaultSubscriptionId)?:SmsManager.getDefault()
var defaultSubscriptionInfo: SubscriptionInfo? = subscriptionManager.getActiveSubscriptionInfo(defaultSubscriptionId)

To sum everything up, it seems there may be a bug in the Samsung J5 implementation of the dual SIM on Android 23 (resulting in a blank phone number in the SIM settings).

Related

Not getting user dialed number in Android 9.0 Even i have declared both Read call log and REad Phone State permission at Runtime as well

In my app I am trying to intercept all outgoing calls starting with 00 string. I used Telephony Manager for the same to get outgoing number and then intercept it. All code was working properly before Android 9.0. But in Android Pie once i made call then my app crashed because i am not getting User Dialed number in Receiver.
"Without the READ_CALL_LOG permission, however, the phone number field
that's provided in PHONE_STATE_CHANGED broadcasts and through
PhoneStateListener is empty."
So you have to ensure the user grants permission for reading phone number before you try to access any dialed number.
Also you have to keep a check and a backup plan in case user refuses permission. Your app should handle such case well so as to avoid any null pointers.

Best way to link a FCM token to a device?

I'm making a server that sends messages using FCM to clients depending on what happens (temperature and/or humidity change, a door is opened, etc.).
But if the token can change, how can I keep track of the device to send messages to the correct one (w/o using a login system)?
I was thinking to link the token to the sim iccid in a database, is this correct?
Use device's advertising id. It won't change unless the user manually changes it. Please check the thread How to get Advertising ID in android
Update 05/18/2017:
Starting Android O, ANDROID_ID will now be different per app per user in the device.
Original Answer:
If you're looking for a long lasting (possibly permanent) ID that you can use, I guess you can make use of ANDROID_ID:
String ANDROID_ID
A 64-bit number (as a hex string) that is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device. The value may change if a factory reset is performed on the device.
Note: When a device has multiple users (available on certain devices running Android 4.2 or higher), each user appears as a completely separate device, so the ANDROID_ID value is unique to each user.
Constant Value: "android_id"
However, there are still some factors that you should consider depending on your use-case. I recommend going through the Best Practices for Unique Identifiers documentation.
FCM wise, it is usually associated with a user, hence it is commonly paired with the user details.

How to check if user already logged in some other device android?

Hi I have requirement where i need to check if user already logged in some other device.
Sceario 1: If user logged in, I am making service call to change from 0 to 1. If user log out, i am making service call to 0. This works perfectly.
But problem is if user uninstall app after sign in, without log out, how to manage this scenario? As it changed to 1 and in this case
Scenario 2: I got suggestion that, if user un-install the app without log out or you're not log-in in app till 1 day you should change user's status to logout.but in this case, if user log in one device and uninstall app immediately within few hours(say may be because of low ram), once again user install app means, in this case the above scenario fails too.
I used device id from gcm to use, but device id also not an uinque one, if uninstalled app in same device and logged in, device id too will vary.
Please suggest me how to resolve this issue.
Thanks.
To check if user uninstalled the app and again installed and logged in, you can user unique id of android device which is :
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
for more details see here
scenario 1 is the simplest, but a bit edited :
instead of just make a "ping" to your service on login / logout (that may cause some problem if you miss logout for any reason, as uninstall app, network issue, etc), simpler is to have timed ping (let's say every 30 sec, your app send a ping)
on server side, at ping receipt, start a timer and keep some safety margin for latency. let's say, if no other ping came in 45 sec, you log out automatically
you can adjust duration or underlying mechanism but main idea is there
You can use unique device id that is associated with the device i.e. IMEI number.
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String deviceId = telephonyManager.getDeviceId();
This device id is not reset and remains the same for a device.
for more details see here

Why do we need a UserHandle in many API declarations

In Android Open Source Project, a lot of core API declarations have an integer parameter userId in the end. I traced back and figured out the integer comes from a class called "UserHandle.java". There is a simple comments saying this class represents a user on the device. It still confuses me. Why do we need such a class? What's the difference between different values of the class, such as "USER_OWNER", "USER_CURRENT", "USER_CURRENT_OR_SELF"?
Thanks in advance!!!
Ever since Jelly Bean, Android platform has supported multiple users. This means that multiple users may be able to use one device, yet not be able to access other user's files or communicate with another user's app.
The first user on the device is user 0. The rest start their numbering from 10,11,... (In JB the numbering was 1,2...).
USER_OWNER is user 0.
He has some extra privileges over the other users (mostly access certain settings that others can't or uninstall an app for all users).
Multiple users on one device requires that only one user can be active in a specific point in time, this user is referred to as USER_CURRENT (since Kitkat().
In general one user's application can't send a broadcast message or an Intent to other user's apps.
Only apps with system permissions can do that (for example when the battery is running low, an intent will be sent to all).
Whenever you send an Intent from your app, the system service verifies whether this is a valid Intent i.e. if its supposed to reach all users then it's not.
This means that even if you were to use a certain api with the wrong userId (for example you force userId=0 even though this is user 10), then your call will receive a SecurityException.
To avoid such exceptions, there is also the option to send an Intent with USER_CURRENT_OR_SELF.
This means you're trying to send to the current user, but if he's not allowed to receive the Intent, let the same user who sent the Intent receive it.

Verifying the phone number

In my application first thing the user should do is the registration. For that i need the phone no. So the user will give their 10 digit number. Now i need to verfy the user inputed the same number which holds by the phone. How to do that ? i tried .getLine1Number() but it is returing nothing.
After pressing the register button i am calling a url which will send a verification code to the phone number was inputed by the user. Till that i am showing a alert dialog. After receiving the message only i am dismissing the dialoge box.
So the problem happens when the user give a valid number which may not their number.
PS: I need to get the response through message only.
Only few service providers provide phone number via getLine1Number() method. Instead you can get a unique number for each sim using getSimSerialNumber() method.
Did you set permissions in Manifest READ_PHONE_STATE ?
Method still can return null
Returns the phone number string for line 1, for example, the MSISDN for a GSM phone. Return null if it is unavailable.

Categories

Resources