Android/Android 일반

SMS Retriever API - 1

lipnus 2019. 1. 20. 21:56
반응형


1. 이게 뭔가?

문자 받은내용 캐치하는거 원래는 permission으로 권한 얻어서 하면 됬었는데 이제는 SMS Retriever API 써서 해야한다.



2. Gradle

implementation 'com.google.android.gms:play-services:12.0.1'
Google Play Service필요

필요한 것만 등록해도 된다
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