签名(OTP 验证)activity 粉碎
Sinch(OTP verification) activity crashing
正在尝试实施 sinch,但 activity 正在崩溃。我正在使用 Retrofit 和 Picasso。我可以和他们一起使用 Sinch 吗?我还使用了 sinch 教程中给出的其他两个 类。这是我的代码
MainActivity.java
public class Register extends AppCompatActivity {
public static final String SMS = "sms";
public static final String FLASHCALL = "flashcall";
public static final String INTENT_PHONENUMBER = "phonenumber";
public static final String INTENT_METHOD = "method";
private EditText mPhoneNumber;
private Button mSmsButton;
private Button mFlashCallButton;
private String mCountryIso;
private TextWatcher mNumberTextWatcher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPhoneNumber = (EditText) findViewById(R.id.phoneNumber);
mSmsButton = (Button) findViewById(R.id.smsVerificationButton);
mFlashCallButton = (Button) findViewById(R.id.callVerificationButton);
mCountryIso = PhoneNumberUtils.getDefaultCountryIso(this);
final String defaultCountryName = new Locale("", mCountryIso).getDisplayName();
final CountrySpinner spinner = (CountrySpinner) findViewById(R.id.spinner);
spinner.init(defaultCountryName);
spinner.addCountryIsoSelectedListener(new CountrySpinner.CountryIsoSelectedListener() {
@Override
public void onCountryIsoSelected(String selectedIso) {
if (selectedIso != null) {
mCountryIso = selectedIso;
resetNumberTextWatcher(mCountryIso);
// force update:
mNumberTextWatcher.afterTextChanged(mPhoneNumber.getText());
}
}
});
resetNumberTextWatcher(mCountryIso);
tryAndPrefillPhoneNumber();
}
private void tryAndPrefillPhoneNumber() {
if (checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
TelephonyManager manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mPhoneNumber.setText(manager.getLine1Number());
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 0);
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
tryAndPrefillPhoneNumber();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0])) {
Toast.makeText(this, "This application needs permission to read your phone number to automatically "
+ "pre-fill it", Toast.LENGTH_LONG).show();
}
}
}
private void openActivity(String phoneNumber, String method) {
Intent verification = new Intent(this, VerificationActivity.class);
verification.putExtra(INTENT_PHONENUMBER, phoneNumber);
verification.putExtra(INTENT_METHOD, method);
startActivity(verification);
}
private void setButtonsEnabled(boolean enabled) {
mSmsButton.setEnabled(enabled);
mFlashCallButton.setEnabled(enabled);
}
public void onButtonClicked(View view) {
if (view == mSmsButton) {
openActivity(getE164Number(), SMS);
} else if (view == mFlashCallButton) {
openActivity(getE164Number(), FLASHCALL);
}
}
private void resetNumberTextWatcher(String countryIso) {
if (mNumberTextWatcher != null) {
mPhoneNumber.removeTextChangedListener(mNumberTextWatcher);
}
mNumberTextWatcher = new PhoneNumberFormattingTextWatcher(countryIso) {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
super.onTextChanged(s, start, before, count);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
super.beforeTextChanged(s, start, count, after);
}
@Override
public synchronized void afterTextChanged(Editable s) {
super.afterTextChanged(s);
if (isPossiblePhoneNumber()) {
setButtonsEnabled(true);
mPhoneNumber.setTextColor(Color.BLACK);
} else {
setButtonsEnabled(false);
mPhoneNumber.setTextColor(Color.RED);
}
}
};
mPhoneNumber.addTextChangedListener(mNumberTextWatcher);
}
private boolean isPossiblePhoneNumber() {
return PhoneNumberUtils.isPossibleNumber(mPhoneNumber.getText().toString(), mCountryIso);
}
private String getE164Number() {
return PhoneNumberUtils.formatNumberToE164(mPhoneNumber.getText().toString(), mCountryIso);
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/startbg"
android:padding="0dip"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/numberInputLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical"
android:paddingLeft="40dp"
android:paddingRight="40dp">
<com.sinch.verification.sample.CountrySpinner
android:id="@+id/spinner"
android:layout_width="255dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:text="@string/enterphonenumber"
android:textAllCaps="true"
android:textColor="@color/sinch_purple"
android:textSize="18sp" />
<EditText
android:id="@+id/phoneNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@drawable/inputbox"
android:inputType="phone"
android:padding="10dp"
android:textColor="@color/sinch_purple"
android:textSize="32sp">
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="vertical"
android:paddingEnd="40dp"
android:paddingStart="40dp">
<Button
android:id="@+id/smsVerificationButton"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="10dp"
android:background="@drawable/button_purple_generic"
android:minHeight="56dp"
android:minWidth="132dp"
android:onClick="onButtonClicked"
android:text="SMS Verification"
android:textAllCaps="true"
android:textColor="#ffffff"
android:textSize="20sp" />
<Button
android:id="@+id/callVerificationButton"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp"
android:background="@drawable/button_purple_generic"
android:minHeight="56dp"
android:minWidth="132dp"
android:onClick="onButtonClicked"
android:text="Flash call Verification"
android:textAllCaps="true"
android:textColor="#ffffff"
android:textSize="20sp" />
</LinearLayout>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/numberInputLayout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:text="@string/selectcountry"
android:textAllCaps="true"
android:textColor="@color/sinch_purple"
android:textSize="18sp" />
CountrySpinner
public class CountrySpinner extends Spinner {
private Map<String, String> mCountries = new TreeMap<String, String>();
private List<CountryIsoSelectedListener> mListeners = new ArrayList<CountryIsoSelectedListener>();
public interface CountryIsoSelectedListener {
void onCountryIsoSelected(String iso);
}
public CountrySpinner(Context context) {
super(context);
}
public CountrySpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void init(String defaultCountry) {
initCountries();
List<String> countryList = new ArrayList<String>();
countryList.addAll(mCountries.keySet());
countryList.remove(defaultCountry);
countryList.add(0, defaultCountry);
ArrayAdapter adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, countryList);
setAdapter(adapter);
setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
final String selectedCountry = (String) adapterView.getItemAtPosition(position);
notifyListeners(selectedCountry);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
public void addCountryIsoSelectedListener(CountryIsoSelectedListener listener) {
mListeners.add(listener);
}
public void removeCountryIsoSelectedListener(CountryIsoSelectedListener listener) {
mListeners.remove(listener);
}
private void initCountries() {
String[] isoCountryCodes = Locale.getISOCountries();
for (String iso : isoCountryCodes) {
String country = new Locale("", iso).getDisplayCountry();
mCountries.put(country, iso);
}
}
private void notifyListeners(String selectedCountry) {
final String selectedIso = mCountries.get(selectedCountry);
for (CountryIsoSelectedListener listener : mListeners) {
listener.onCountryIsoSelected(selectedIso);
}
}
}
Logcat
7305-7305/earn.free.cashback.snapcash E/AndroidRuntime: FATAL EXCEPTION:main
Process: earn.free.cashback.snapcash, PID: 7305
java.lang.RuntimeException: Unable to start activity ComponentInfo{earn.free.cashback.snapcash/earn.free.cashback.snapcash.Register}: java.lang.NullPointerException: Attempt to invoke virtual method 'void earn.free.cashback.snapcash.CountrySpinner.init(java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void earn.free.cashback.snapcash.CountrySpinner.init(java.lang.String)' on a null object reference
at earn.free.cashback.snapcash.Register.onCreate(Register.java:49)
at android.app.Activity.performCreate(Activity.java:6245)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
我做错了什么?
您正在尝试在 onCreate()
中初始化微调器,但尚未创建视图。尝试在 onStart()
或 onResume()
.
中进行
正在尝试实施 sinch,但 activity 正在崩溃。我正在使用 Retrofit 和 Picasso。我可以和他们一起使用 Sinch 吗?我还使用了 sinch 教程中给出的其他两个 类。这是我的代码
MainActivity.java
public class Register extends AppCompatActivity {
public static final String SMS = "sms";
public static final String FLASHCALL = "flashcall";
public static final String INTENT_PHONENUMBER = "phonenumber";
public static final String INTENT_METHOD = "method";
private EditText mPhoneNumber;
private Button mSmsButton;
private Button mFlashCallButton;
private String mCountryIso;
private TextWatcher mNumberTextWatcher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPhoneNumber = (EditText) findViewById(R.id.phoneNumber);
mSmsButton = (Button) findViewById(R.id.smsVerificationButton);
mFlashCallButton = (Button) findViewById(R.id.callVerificationButton);
mCountryIso = PhoneNumberUtils.getDefaultCountryIso(this);
final String defaultCountryName = new Locale("", mCountryIso).getDisplayName();
final CountrySpinner spinner = (CountrySpinner) findViewById(R.id.spinner);
spinner.init(defaultCountryName);
spinner.addCountryIsoSelectedListener(new CountrySpinner.CountryIsoSelectedListener() {
@Override
public void onCountryIsoSelected(String selectedIso) {
if (selectedIso != null) {
mCountryIso = selectedIso;
resetNumberTextWatcher(mCountryIso);
// force update:
mNumberTextWatcher.afterTextChanged(mPhoneNumber.getText());
}
}
});
resetNumberTextWatcher(mCountryIso);
tryAndPrefillPhoneNumber();
}
private void tryAndPrefillPhoneNumber() {
if (checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
TelephonyManager manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mPhoneNumber.setText(manager.getLine1Number());
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 0);
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
tryAndPrefillPhoneNumber();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0])) {
Toast.makeText(this, "This application needs permission to read your phone number to automatically "
+ "pre-fill it", Toast.LENGTH_LONG).show();
}
}
}
private void openActivity(String phoneNumber, String method) {
Intent verification = new Intent(this, VerificationActivity.class);
verification.putExtra(INTENT_PHONENUMBER, phoneNumber);
verification.putExtra(INTENT_METHOD, method);
startActivity(verification);
}
private void setButtonsEnabled(boolean enabled) {
mSmsButton.setEnabled(enabled);
mFlashCallButton.setEnabled(enabled);
}
public void onButtonClicked(View view) {
if (view == mSmsButton) {
openActivity(getE164Number(), SMS);
} else if (view == mFlashCallButton) {
openActivity(getE164Number(), FLASHCALL);
}
}
private void resetNumberTextWatcher(String countryIso) {
if (mNumberTextWatcher != null) {
mPhoneNumber.removeTextChangedListener(mNumberTextWatcher);
}
mNumberTextWatcher = new PhoneNumberFormattingTextWatcher(countryIso) {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
super.onTextChanged(s, start, before, count);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
super.beforeTextChanged(s, start, count, after);
}
@Override
public synchronized void afterTextChanged(Editable s) {
super.afterTextChanged(s);
if (isPossiblePhoneNumber()) {
setButtonsEnabled(true);
mPhoneNumber.setTextColor(Color.BLACK);
} else {
setButtonsEnabled(false);
mPhoneNumber.setTextColor(Color.RED);
}
}
};
mPhoneNumber.addTextChangedListener(mNumberTextWatcher);
}
private boolean isPossiblePhoneNumber() {
return PhoneNumberUtils.isPossibleNumber(mPhoneNumber.getText().toString(), mCountryIso);
}
private String getE164Number() {
return PhoneNumberUtils.formatNumberToE164(mPhoneNumber.getText().toString(), mCountryIso);
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/startbg"
android:padding="0dip"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/numberInputLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical"
android:paddingLeft="40dp"
android:paddingRight="40dp">
<com.sinch.verification.sample.CountrySpinner
android:id="@+id/spinner"
android:layout_width="255dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:text="@string/enterphonenumber"
android:textAllCaps="true"
android:textColor="@color/sinch_purple"
android:textSize="18sp" />
<EditText
android:id="@+id/phoneNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@drawable/inputbox"
android:inputType="phone"
android:padding="10dp"
android:textColor="@color/sinch_purple"
android:textSize="32sp">
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="vertical"
android:paddingEnd="40dp"
android:paddingStart="40dp">
<Button
android:id="@+id/smsVerificationButton"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="10dp"
android:background="@drawable/button_purple_generic"
android:minHeight="56dp"
android:minWidth="132dp"
android:onClick="onButtonClicked"
android:text="SMS Verification"
android:textAllCaps="true"
android:textColor="#ffffff"
android:textSize="20sp" />
<Button
android:id="@+id/callVerificationButton"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp"
android:background="@drawable/button_purple_generic"
android:minHeight="56dp"
android:minWidth="132dp"
android:onClick="onButtonClicked"
android:text="Flash call Verification"
android:textAllCaps="true"
android:textColor="#ffffff"
android:textSize="20sp" />
</LinearLayout>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/numberInputLayout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:text="@string/selectcountry"
android:textAllCaps="true"
android:textColor="@color/sinch_purple"
android:textSize="18sp" />
CountrySpinner
public class CountrySpinner extends Spinner {
private Map<String, String> mCountries = new TreeMap<String, String>();
private List<CountryIsoSelectedListener> mListeners = new ArrayList<CountryIsoSelectedListener>();
public interface CountryIsoSelectedListener {
void onCountryIsoSelected(String iso);
}
public CountrySpinner(Context context) {
super(context);
}
public CountrySpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void init(String defaultCountry) {
initCountries();
List<String> countryList = new ArrayList<String>();
countryList.addAll(mCountries.keySet());
countryList.remove(defaultCountry);
countryList.add(0, defaultCountry);
ArrayAdapter adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, countryList);
setAdapter(adapter);
setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
final String selectedCountry = (String) adapterView.getItemAtPosition(position);
notifyListeners(selectedCountry);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
public void addCountryIsoSelectedListener(CountryIsoSelectedListener listener) {
mListeners.add(listener);
}
public void removeCountryIsoSelectedListener(CountryIsoSelectedListener listener) {
mListeners.remove(listener);
}
private void initCountries() {
String[] isoCountryCodes = Locale.getISOCountries();
for (String iso : isoCountryCodes) {
String country = new Locale("", iso).getDisplayCountry();
mCountries.put(country, iso);
}
}
private void notifyListeners(String selectedCountry) {
final String selectedIso = mCountries.get(selectedCountry);
for (CountryIsoSelectedListener listener : mListeners) {
listener.onCountryIsoSelected(selectedIso);
}
}
}
Logcat
7305-7305/earn.free.cashback.snapcash E/AndroidRuntime: FATAL EXCEPTION:main
Process: earn.free.cashback.snapcash, PID: 7305
java.lang.RuntimeException: Unable to start activity ComponentInfo{earn.free.cashback.snapcash/earn.free.cashback.snapcash.Register}: java.lang.NullPointerException: Attempt to invoke virtual method 'void earn.free.cashback.snapcash.CountrySpinner.init(java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void earn.free.cashback.snapcash.CountrySpinner.init(java.lang.String)' on a null object reference
at earn.free.cashback.snapcash.Register.onCreate(Register.java:49)
at android.app.Activity.performCreate(Activity.java:6245)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
我做错了什么?
您正在尝试在 onCreate()
中初始化微调器,但尚未创建视图。尝试在 onStart()
或 onResume()
.