I my application I have written following code in order to extract phone number. When I run it in emulator, everything is fine but when I run it on a real device, application crashes. what is your suggestion? I have added <uses-permission android:name="android.permission.READ_PHONE_STATE"/> in manifest file.
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView phoneNumber = (TextView)findViewById(R.id.tvPhoneNumber);
phoneNumber.setText(getMy10DigitPhoneNumber());
}
private String getMyPhoneNumber(){
TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
return mTelephonyMgr.getLine1Number();
}
private String getMy10DigitPhoneNumber(){
String s = getMyPhoneNumber();
return s.substring(2);
}
}
getLine1Number() will return the phone number string if available and null if not available. So you should check for Null Pointer.
private String getMy10DigitPhoneNumber() {
String s = getMyPhoneNumber();
if(s == null) return "";
else return s.substring(2);
}
Also check the length of the string returned by getLine1Number(). In my phone, i got a ""string. In this case, substring() will throw IndexOutOfBoundsException. So check for length of s also before calling substring().
Related
In my android app, I take the input from the edit text when the login button is clicked and pass it to my presenter. The presenter then validates it using the LoginValidator utility class, depending on the result it either continues with the normal login flow or sends a message to the activity notifying that the email or/and password is/are invalid.
In the test class for the LoginValidator I do the following:
public class LoginValidatorTest {
private static final String INVALID_EMAIL = "ewksd";
private static final String VALID_EMAIL = "tom.finet#gmail.com";
private static final String INVALID_PASSWORD = "sjadsaA";
private static final String VALID_PASSWORD = "Asdfgh1d";
#Test
public void shouldValidateInvalidEmail() {
Assert.assertEquals(LoginValidator.validateEmail(INVALID_EMAIL), false);
}
#Test
public void shouldValidateValidEmail() {
Assert.assertEquals(LoginValidator.validateEmail(VALID_EMAIL), true);
}
#Test
public void shouldValidateInvalidPassword() {
Assert.assertEquals(LoginValidator.validatePassword(INVALID_PASSWORD), false);
}
#Test
public void shouldValidateValidPassword() {
Assert.assertEquals(LoginValidator.validatePassword(VALID_PASSWORD), true);
}
}
Here is the LoginValidator class which the test calls:
public class LoginValidator {
/**
* #param email the email to be validated
* #return true if the email is valid
*/
public static boolean validateEmail(String email) {
return email != null && Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
/**
*
* #param password the password to be validated
* #return true if the password is valid
*/
public static boolean validatePassword(String password) {
if (password == null)
return false;
else if (password.length() < 6)
return false;
else if (!password.contains("^[0-9]"))
return false;
else if (!password.contains("[A-Z]+"))
return false;
return true;
}
}
When the tests are running these are the results:
How do I fix my code to make all the tests pass?
UPDATE:
Here is what the regex for the password validation looks like:
From further analysis, I have concluded that the code Patterns.EMAIL_ADDRESS is null and hence when calling .matcher(email) on it causes a NullPointerException. Why the hell is Patterns.EMAIL_ADDRESS returning null?
Try using Mockito and mock LoginValidator as follows :
// If you want to create an instance
LoginValidator loginValidator = mock(LoginValidator.class);
// If you need to access static methods from that class
mock(LoginValidator.class);
Not sure about the mail check but you have an error in your password check.
Assuming that you want just check if the password contains a number you should change it from:
public static boolean validatePassword(String password) {
if (password == null)
return false;
else if (password.length() < 6)
return false;
else if (!password.matches(".*[0-9]+.*"))
return false;
else if (!password.matches(".*[A-Z]+.*"))
return false;
return true;
}
The capital also was incorrect as contains does not accept regex. One of the options would be to use matches.
public static boolean validatePassword(String pwd) {
return pwd != null && pwd.matches("((?=.*\\d)(?=.*[A-Z]).{6,})");
}
"((?=.*\\d)(?=.*[A-Z]).{6,})" is the regex for at least one number, at least one cap, and at least 6 characters.
Had this this problem, it's caused by Patterns.EMAIL_ADDRESS.matcher, this is an Android method so you can neither use it in a unit test (it's always null) nor mock it. You can't mock it because Mockito does not mock android classes. A solution would be making your own regex for emails.
When I try to use telephony manager to retrieve the phone number from an Activity class, I am able to do it successfully. But I will be using the phone number in multiple places of the app, therefore I shifted the phone number to be a static field in my application class.
public class FourApplication extends Application {
static String phonenumber ;
#Override
public void onCreate() {
super.onCreate();
ParseObject.registerSubclass(Post.class);
// Add your initialization code here
Parse.initialize(this, "**********", "*********");
ParseACL defaultACL = new ParseACL();
// If you would like all objects to be private by default, remove this
// line.
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
phonenumber = getPhoneNumber();
}
public String getPhoneNumber()
{
TelephonyManager tMgr =(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number(); ;
Log.i("mPhoneNumber : ", mPhoneNumber);
return mPhoneNumber;
}
}
What is the mistake I am making here? I read through a few Context related questions and threads, Not able to figure out what's going wrong in my code as I am noob here.
Edit : My question is, When I move the telephony manager part to the application class, it doesn't return a phone number. Why is that?
#55597
Please use the following piece of code.You got your problem
TelephonyManager tMgr =(TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
You are not passing the correct context of Activity for TelephonyManager, So that its return null.
I want to access the TELEPHONY_SERVICE system service in the Application class, but my app crashes when I run it.
public class SimpleDhtApplication extends Application {
TelephonyManager tel = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String portStr = tel.getLine1Number().substring(tel.getLine1Number().length() -4);
final String myPort = String.valueOf((Integer.parseInt(portStr) * 2));
}
I think I am not accessing the context correctly, can somebody help!
Override the onCreate method of the Application class first. Within the onCreate, put the code you have so it would look like:
public class SimpleDhtApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
TelephonyManager tel = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String portStr = tel.getLine1Number().substring(tel.getLine1Number().length() -4);
final String myPort = String.valueOf((Integer.parseInt(portStr) * 2));
}
}
Update: Watch out for tel.getLine1Number(); it may return null as explained here.
This question already has answers here:
The method getSystemService(String) is undefined for the type Listen
(3 answers)
Closed 9 years ago.
In my Android app I wanna generate the device ID. At first I just generate the device ID inside an activity as below. It worked fine.
TelephonyManager tManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
return uid;
Then I wanna create a device object and try to do the above in it as a method,
public String generateDeviceId() {
// DeviceId = deviceId;
TelephonyManager tManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
return uid;
}
It gives an syntax error and say
The method getSystemService(String) is undefined for the type Device
So how can I fix this. I wanna create a device class and create device object and do my stuff. Is it possible. I imported the below,
import android.content.Context;
import android.telephony.TelephonyManager;
So is it possible. Can someone help me to do my work. Thanks.
getSystemService(String) needs a context. So you need to pass context to the constructor of Non Activity class and use it there.
new Device(ActivityName.this);
Then
Context mContext;
public Device(Context context)
{
mContext = context;
}
Then
TelephonyManager tManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
http://developer.android.com/reference/android/content/Context.html#getSystemService(java.lang.String)
Try changing this method in your Device class
public String generateDeviceId(Context context) {
// DeviceId = deviceId;
TelephonyManager tManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
return uid;
}
and While calling from your Activity , just pass the current activity reference this
deviceObject.generateDeviceId(this);
When you try to access getSystemService outside of the android activity class then you must need the context.
TelephonyManager tm =
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
and this are complete method
public String generateDeviceId(Context context) {
// DeviceId = deviceId;
TelephonyManager tManager = (TelephonyManager)context. getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
return uid;
}
Thanks
I got this error in my logcat
TelephonyManager : Hidden constructor called more than once per process!
And my PhoneListener is not working
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.e("state", "idle");
break;
case TelephonyManager.DATA_CONNECTED:
Log.e("state", "connected");
break;
}
};
};
telManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
telManager.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
It won't print out my log.
From the source code i got this:
/** Provides access to information about the telephony services on the device. Applications can use the methods in this class to determine telephony services and states, as well as to access some types of subscriber information. Applications can also register a listener to receive notification of telephony state changes.
You do not instantiate this class directly; instead, you retrieve a reference to an instance through {#link android.content.Context#getSystemService Context.getSystemService(Context.TELEPHONY_SERVICE)}. *
Note that access to some telephony information is permission-protected. Your application cannot access the protected * information unless it has the appropriate permissions declared in its manifest file. Where permissions apply, they are noted in the the methods through which you access the protected information. **/
public class TelephonyManager {
private static final String TAG = "TelephonyManager";
private static Context sContext;
private static ITelephonyRegistry sRegistry;
/** #hide */
public TelephonyManager(Context context) {
context = context.getApplicationContext();
if (sContext == null) {
sContext = context;
sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
} else if (sContext != context) {
Log.e(TAG, "Hidden constructor called more than once per process!");
Log.e(TAG, "Original: " + sContext.getPackageName() + ", new: " +
context.getPackageName());
}
}
Are you creating multiple instance of TelephonyManger from different context? If so then the Error Log will show as the context is static.