This question already has answers here:
MSISDN : Is it a SIM Card Data? Why all The Provided Function (from Blackberry and Android) to fetch MSISDN not reliable?
(3 answers)
Closed 5 years ago.
Using Telephony Manager returns null value for Mobile number, I want to get Mobile Number directly in to the app without asking user.
You can use the TelephonyManager to do this:
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String number = tm.getLine1Number();
The getLine1Number() will return null if the number is "unavailable", but it does not say when the number might be unavailable.
You'll need to give your application permission to make this query by adding the following to your Manifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Try the given below method for generating country code
private void getCountryCode() {
int code = 0;
TelephonyManager telephonyManager = (TelephonyManager) getActivity().
getSystemService(Context.TELEPHONY_SERVICE);
String CountryISO = telephonyManager.getSimCountryIso().toString().toUpperCase();
;
//String NetworkCountryIso = telephonyManager.getNetworkCountryIso().toString();
String number = telephonyManager.getLine1Number();
code = getCountryCodeForRegion(CountryISO);
Log.i("CountryISO", "CountryISO " + CountryISO);
Log.i("code", "code " + code);
Log.i("number ", "number " + number);
}
Gets CountryCode from regionCode
public int getCountryCodeForRegion(String regionCode) {
int result = -1;
try {
Class c = Class.forName("com.android.i18n.phonenumbers.PhoneNumberUtil");
Method getInstance = c.getDeclaredMethod("getInstance");
Method getCountryCodeForRegion = c.getDeclaredMethod("getCountryCodeForRegion", String.class);
Object instance = getInstance.invoke(null);
Integer code = (Integer) getCountryCodeForRegion.invoke(instance, regionCode);
result = code;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
return result;
}
}
Don't forget to add permission in AndroidManifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Related
Now with android 10 updated permission and security, we cannot access the user's devices device id and IMEI number but I want some unique id of the device so that we can track the user.
The requirement is we want to have/restrict one login from one phone
Android 10 Restricted developer to Access IMEI number.
You can have a alternate solution by get Software ID. You can use software id as a unique id. Please find below code as i use in Application.
public static String getDeviceId(Context context) {
String deviceId;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
} else {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
}
}
return deviceId;
}
Android introduced a new id to identify a device uniquely, which is called Advertisement_Id. You can get this Id from the below code implementation in you Application class onCreate method.
/** Retrieve the Android Advertising Id
*
* The device must be KitKat (4.4)+
* This method must be invoked from a background thread.
*
* */
public static synchronized String getAdId (Context context) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
return null;
}
AdvertisingIdClient.Info idInfo = null;
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String advertId = null;
try{
advertId = idInfo.getId();
}catch (NullPointerException e){
e.printStackTrace();
}
return advertId;
}
For Kotlin
fun getAdId() {
//Background Task
AsyncTask.execute {
var adInfo: AdvertisingIdClient.Info? = null
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(applicationContext)
if(adInfo!=null){
val id = adInfo!!.getId()
val isLAT = adInfo!!.isLimitAdTrackingEnabled()
PersistData.setStringData(applicationContext, AppConstant.advertId, id)
val advertId = PersistData.getStringData(applicationContext, AppConstant.advertId)
}
} catch (e: IOException) {
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
} catch (e: GooglePlayServicesAvailabilityException) {
// Encountered a recoverable error connecting to Google Play services.
} catch (e: GooglePlayServicesNotAvailableException) {
// Google Play services is not available entirely.
}
}
}
As Serial number and IMEI number has been deprecated for Android 10 and onwards ,
So we can find the android id for unique identifier with READ_PRIVILEGED_PHONE_STATE.
for More information please follow below link.
https://developer.android.com/training/articles/user-data-ids
getDeviceId() has been deprecated since API level 26.
"READ_PRIVILEGE_PHONE_STATE" is only accessible by The best practices suggest that you should "Avoid using hardware identifiers." for unique identifiers. You can use an instance id from firebase e.g FirebaseInstanceId.getInstance().getId();
public static String getDeviceId(Context context) {
String deviceId;
if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
} else {
deviceId =FirebaseInstanceId.getInstance().getId();
}
return deviceId;
}
Use FirebaseInstanceId.getInstance().getId(); for Api level above Android 10
This works for me //import android.provider.Settings
val mId = Settings.Secure.getString(this.contentResolver, Settings.Secure.ANDROID_ID)
When I click phone call button, how to choose skype, viber, sim1 or sim2, ect. Now, it is called by sim2. I want to choose. I search on Google, no found my problem.
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + "123456789"));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
Permissions in Manifest
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Reset App preferences before starting intent
Settings->Apps/Application Manager -> Default/Downloaded Apps -> Click on overflow icon (i.e. three dots icon on top right of the screen) -> Reset App Preferences.
Your code looks fine.
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + "123456789"));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
You need to create a sim chooser dialog and set sim 1 and sim 2 options and set simNumber variable according to the choosen sim number(0 for sim1 and 1 for sim2)
Here is the code that I have implemented for calling from specific sim i.e. SIM 1 or SIM 2.
code:
private final static String simSlotName[] = {
"extra_asus_dial_use_dualsim",
"com.android.phone.extra.slot",
"slot",
"simslot",
"sim_slot",
"subscription",
"Subscription",
"phone",
"com.android.phone.DialingMode",
"simSlot",
"slot_id",
"simId",
"simnum",
"phone_type",
"slotId",
"slotIdx"
};
int simNumber = 0 or 1; //0 for sim1 and 1 for sim2
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"
+ phoneNumber));
callIntent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//Add slots here since different device needs different key so put all together
for (String s : simSlotName)
intent.putExtra(s, simNumber);
//This will only work on API 22 or up
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
intent.putExtra("android.telecom.extra.PHONE_ACCOUNT_HANDLE", (Parcelable) SimSlotHelper.getAccountHandles(context).get(simNumber))
context.startActivity(intent);
Here is a class for sim slot helper which will get phone account handle list by using telecom manager for both sims
code:
public class SimSlotHelper {
public static List getAccountHandles(Context context) {
Class c;
Method m;
TelecomManager telecomManager;
List<PhoneAccountHandle> accountHandles;
TelephonyManager telephony;
telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
c = Class.forName("android.telecom.TelecomManager");
Method m1 = c.getMethod("from", Context.class);
telecomManager = (TelecomManager) m1.invoke(null, context);
m = c.getMethod("getCallCapablePhoneAccounts");
accountHandles = (List<PhoneAccountHandle>) m.invoke(telecomManager);
return accountHandles;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
Try using .ACTION_DIAL instead of .ACTION_CALL . This opens a Dialog chooser with apps installed in the device with capability of calling.
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + "123456789"));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I'm trying to get text from server and then check it a to know what actions to take with the text adopted. The problem is that when I try to check if the received text for example is "Exited" the query always return the value "false" when the received text is really "Exited".
Here is the code :
class Get_Message_From_Server implements Runnable
{
public void run()
{
InputStream iStream = null;
try
{
iStream = Duplex_Socket_Acceptor.getInputStream();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
//Create byte array of size image
byte[] Reading_Buffer = null;
try
{
Reading_Buffer = new byte [Duplex_Socket_Acceptor.getReceiveBufferSize()];
//New_Buffer = new byte [100];
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] Byte_Char_1 = new byte[1];
int Byte_String_Lenght = 0;
//read size
try
{
iStream.read(Reading_Buffer);
String Reading_Buffer_Stream_Lenghtor = new String(Reading_Buffer);
//System.out.println("full : " + Reading_Buffer_Stream_Lenghtor);
Byte_String_Lenght = Reading_Buffer_Stream_Lenghtor.indexOf(new String(Byte_Char_1));
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
//Convert to String
Meassage = new String(Reading_Buffer);
Meassage = Meassage.substring(0, Byte_String_Lenght);//The text that received
Message_Getted = 1;
}
}
The query :
if(Message_1 != "Exited")//the message query
{
System.out.println("Continued 253");
continue;
}
Its always return the value - false
its important to know that the message is in Utf - 8 encoding
so how i can to fix the issue ?
If you compare strings by using oparators, Java will not look at the contents of the string but at the reference in memory. To compare String content in Java, you should use the following:
String Message_1; // Hopefully has a value sent by the server
if(Message_1.equals("Exited")) {
// Do stuff when exited
} else {
// Do stuff when not exited
}
String is a variable - and variables should start with lower Case letter - Please read Java Code conventions. Also to check if your message contains string you thing it should just do System.out.println(Message_1); and if the message contains what you expect you compare string doing
if(Message_1.equals("Exited")) {
System.out.println("Yes they are equal");
} else {
System.out.println("No they are not");
}
If this will print "No they are not" that simply means that your variable Message_1 is not what you think it is.. As simple as that. There is no such a thing as .equals method does not work. Its your variable that doesn't ;)
I need help. I just want to make application that reads battery capacity, like read in mAh/mA. Anyone can help me please?
I've read another thread about this, but I was confused because I need an integer from battery capacity. For example, my android has a battery with capacity 2500 mAh
and I need that integer of capacity(2500) where I want to include that number in my calculation.
Thanks for the help.
This is code that I want to change, I am just confused where it must be changed.
public void getBatteryCapacity() {
Object mPowerProfile_ = null;
final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";
try {
mPowerProfile_ = Class.forName(POWER_PROFILE_CLASS)
.getConstructor(Context.class).newInstance(this);
} catch (Exception e) {
e.printStackTrace();
}
try {
double batteryCapacity = (Double) Class
.forName(POWER_PROFILE_CLASS)
.getMethod("getAveragePower", java.lang.String.class)
.invoke(mPowerProfile_, "battery.capacity");
Toast.makeText(MainActivity.this, batteryCapacity + " mah",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
Yes, your code gives total mAh capacity. You can change that function to return the value like this:
public Double getBatteryCapacity() {
// Power profile class instance
Object mPowerProfile_ = null;
// Reset variable for battery capacity
double batteryCapacity = 0;
// Power profile class name
final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile";
try {
// Get power profile class and create instance. We have to do this
// dynamically because android.internal package is not part of public API
mPowerProfile_ = Class.forName(POWER_PROFILE_CLASS)
.getConstructor(Context.class).newInstance(this);
} catch (Exception e) {
// Class not found?
e.printStackTrace();
}
try {
// Invoke PowerProfile method "getAveragePower" with param "battery.capacity"
batteryCapacity = (Double) Class
.forName(POWER_PROFILE_CLASS)
.getMethod("getAveragePower", java.lang.String.class)
.invoke(mPowerProfile_, "battery.capacity");
} catch (Exception e) {
// Something went wrong
e.printStackTrace();
}
return batteryCapacity;
}
The getAveragePower function returns the average current
in mA consumed by the subsystem. In this case subsystem string is battery.capacity which returns the battery capacity.
See class code here:
https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/com/android/internal/os/PowerProfile.java
And if you really want that value as int, just change it like this:
int bc = getBatteryCapacity().intValue();
I need to cancel the missed calls notification for a certain number. I've seen the NotificationMgr class on com.android.phone but i'm unable to call it trough reflection. Is there any other way?
The code below will cancel the missed call notification.
To get the method work correctly, you must gain MODIFY_PHONE_STATE permission in AndroidManifest.xml like
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"></uses-permission>
in your AndroidManifest.xml
String Log_Tag = "log";
try
{
Class serviceManagerClass = Class.forName("android.os.ServiceManager");
Method getServiceMethod = serviceManagerClass.getMethod("getService", String.class);
Object phoneService = getServiceMethod.invoke(null, "phone");
Class ITelephonyClass = Class.forName("com.android.internal.telephony.ITelephony");
Class ITelephonyStubClass = null;
for(Class clazz : ITelephonyClass.getDeclaredClasses())
{
if (clazz.getSimpleName().equals("Stub"))
{
ITelephonyStubClass = clazz;
break;
}
}
if (ITelephonyStubClass != null)
{
Class IBinderClass = Class.forName("android.os.IBinder");
Method asInterfaceMethod = ITelephonyStubClass.getDeclaredMethod("asInterface",
IBinderClass);
Object iTelephony = asInterfaceMethod.invoke(null, phoneService);
if (iTelephony != null)
{
Method cancelMissedCallsNotificationMethod = iTelephony.getClass().getMethod(
"cancelMissedCallsNotification");
cancelMissedCallsNotificationMethod.invoke(iTelephony);
}
else
{
Log.w(LOG_TAG, "Telephony service is null, can't call "
+ "cancelMissedCallsNotification");
}
}
else
{
Log.d(LOG_TAG, "Unable to locate ITelephony.Stub class!");
}
} catch (ClassNotFoundException ex)
{
Log.e(LOG_TAG,
"Failed to clear missed calls notification due to ClassNotFoundException!", ex);
} catch (InvocationTargetException ex)
{
Log.e(LOG_TAG,
"Failed to clear missed calls notification due to InvocationTargetException!",
ex);
} catch (NoSuchMethodException ex)
{
Log.e(LOG_TAG,
"Failed to clear missed calls notification due to NoSuchMethodException!", ex);
} catch (Throwable ex)
{
Log.e(LOG_TAG, "Failed to clear missed calls notification due to Throwable!", ex);
}
The original link is
http://sites.google.com/site/t2k269group/development-diary/reset-missed-calls-notification
If some know how to use the reflection to access class in com.android.phone, please tell me.
You cannot affect anyone other application's Notifications, let alone one for missed calls.