1. 이게 뭔가?
문자 받은내용 캐치하는거 원래는 permission으로 권한 얻어서 하면 됬었는데 이제는 SMS Retriever API 써서 해야한다.
2. Gradle
implementation 'com.google.android.gms:play-services:12.0.1'
implementation 'com.google.android.gms:play-services-auth:12.0.1'
3. MainActivity.java
public class MainActivity extends AppCompatActivity implements Button.OnClickListener, SmsReceiver.OTPReceiveListener {
Button phone_selector_btn;
TextView otp_tv;
SmsReceiver smsReceiver;
Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
smsReceiver = new SmsReceiver();
initLayout();
//11자리 해쉬코드값 구하기
Util.getAppSignatures(this);
}
/** mRetrieverClient 선언/실행
*/
@Override
protected void onResume() {
super.onResume();
SmsRetrieverClient client = SmsRetriever.getClient(this /* context */);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
IntentFilter intentFilter = new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION);
registerReceiver(smsReceiver, intentFilter);
Log.d("SSS", "onSuccess");
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("SSS", "onFailure" + e.toString());
}
});
}
/** mRetrieverClient 종료
*/
@Override
protected void onStop() {
super.onStop();
try {
this.unregisterReceiver(smsReceiver);
}catch (Exception e){
}
}
@Override
public void onOTPReceived(String msg) {
otp_tv.setText("OTP Number : " + msg);
}
@Override
public void onOTPTimeOut() {
otp_tv.setText("Timeout");
}
private void initLayout(){
//Button
phone_selector_btn = findViewById(R.id.btn_phone_selector);
phone_selector_btn.setOnClickListener(this);
//TextView
otp_tv = findViewById(R.id.otp_tv);
}
}
4. SmsReceiver.java
<receiver
android:name=".SmsReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);;
switch(status.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
//여기서 받음
Log.d("SSS", "서버로부터 받은 Message: " + message);
break;
case CommonStatusCodes.TIMEOUT:
//시간초과
Log.d("SSS", "onReceive - CommonStatusCodes.SUCCESS");
break;
}
}
}
//인터페이스
public interface OTPReceiveListener {
void onOTPReceived(String msg);
void onOTPTimeOut();
}
}
5. Hash코드 구하는 코드(Util.java)
public class Util {
public static final String TAG = Util.class.getSimpleName();
private static final String HASH_TYPE = "SHA-256";
public static final int NUM_HASHED_BYTES = 9;
public static final int NUM_BASE64_CHAR = 11;
/**
* get App Signatures
*/
public static ArrayList<String> getAppSignatures(Context context) {
ArrayList<String> appCodes = new ArrayList<>();
try {
// Get all package signatures for the current package
String packageName = context.getPackageName();
PackageManager packageManager = context.getPackageManager();
Signature[] signatures = packageManager.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES).signatures;
// For each signature create a compatible hash
for (Signature signature : signatures) {
String hash = getHash(packageName, signature.toCharsString());
if (hash != null) {
appCodes.add(String.format("%s", hash));
}
Log.d(TAG, String.format("이 값을 SMS 뒤에 써서 보내주면 됩니다 : %s", hash));
}
} catch (PackageManager.NameNotFoundException e) {
Log.d(TAG, "Unable to find package to obtain hash. : " + e.toString());
}
return appCodes;
}
private static String getHash(String packageName, String signature) {
String appInfo = packageName + " " + signature;
try {
MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
// minSdkVersion이 19이상이면 체크 안해도 됨
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
}
byte[] hashSignature = messageDigest.digest();
// truncated into NUM_HASHED_BYTES
hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES);
// encode into Base64
String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);
Log.d(TAG, String.format("\nPackage : %s\nHash : %s", packageName, base64Hash));
return base64Hash;
} catch (NoSuchAlgorithmException e) {
Log.d(TAG, "hash:NoSuchAlgorithm : " + e.toString());
}
return null;
}
}
6. 문자양식
<#> XXX 앱의 인증번호는 [123456] 입니다.
FA+9qCX9VSu
<#>으로 시작해야 하고, 마지막에 해쉬코드 11자리가 들어가야한다.
예제코드: https://github.com/lipnus/SMS_Retriever_API_example
참고: https://captainwonjong.github.io/2018-09-10/SMS-Retriever-API/
'Android > Android 일반' 카테고리의 다른 글
서비스 예제(kotlin) (1) | 2019.02.15 |
---|---|
SMS Retriever API - 2 (0) | 2019.01.20 |
Hash Code 구하는 코드 (0) | 2019.01.20 |
http 접근 허용 (0) | 2018.11.30 |
에뮬레이터에서 localhost로 접속 (0) | 2018.11.24 |