Android:短信检索 API 不会从意图获取消息



我尝试在我的 android 应用程序中实现新的短信检索 Api,但我无法正确读取消息,收到消息时调用我的服务,但我无法从意图的附加内容中获取消息的内容。这是我服务的示例代码:

/**
* BroadcastReceiver to wait for SMS messages. This can be registered either
* in the AndroidManifest or at runtime.  Should filter Intents on
* SmsRetriever.SMS_RETRIEVED_ACTION.
*/
public class SmsVerificationReceiver 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:
// Get SMS message contents
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
Timber.d(message);
Toast.makeText(context, "Message is: "+ message, Toast.LENGTH_LONG).show();
// Extract one-time code from the message and complete verification
// by sending the code back to your server.
break;
case CommonStatusCodes.TIMEOUT:
// Waiting for SMS timed out (5 minutes)
// Handle the error ...
break;
}
}
}
}

此外,这里是我如何获取应用程序签名的 11 位令牌的代码示例,

/**
* This is a helper class to generate your message hash to be included in your SMS message.
*
* Without the correct hash, your app won't recieve the message callback. This only needs to be
* generated once per app and stored. Then you can remove this helper class from your code.
*/
public class AppSignatureHelper extends ContextWrapper {
public static final String TAG = AppSignatureHelper.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;
public AppSignatureHelper(Context context) {
super(context);
}
/**
* Get all the app signatures for the current package
* @return
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public ArrayList<String> getAppSignatures() {
ArrayList<String> appCodes = new ArrayList<>();
try {
// Get all package signatures for the current package
String packageName = getPackageName();
PackageManager packageManager = getPackageManager();
Signature[] signatures = packageManager.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES).signatures;
// For each signature create a compatible hash
for (Signature signature : signatures) {
String hash = hash(packageName, signature.toCharsString());
if (hash != null) {
appCodes.add(String.format("%s", hash));
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to find package to obtain hash.", e);
}
Toast.makeText(this, "App code is: " + appCodes.toString(), Toast.LENGTH_LONG).show();
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("App has Key", appCodes.toString());
clipboard.setPrimaryClip(clip);
return appCodes;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private  String hash(String packageName, String signature) {
String appInfo = packageName + " " + signature;
try {
MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
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);
Toast.makeText(this, "PKG IS is: " + base64Hash, Toast.LENGTH_LONG).show();
Log.d(TAG, String.format("pkg: %s -- hash: %s", packageName, base64Hash));
return base64Hash;
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "hash:NoSuchAlgorithm", e);
}
return null;
}
}

在服务中,这条线

String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);

始终返回 null。

另外,这是我发送的SMS示例(小于140字节(

[#] his this is your code: 1234 APP_11_DIGIT_SIGNATURE

确保注册了正确的 API。

使用短信检索器 API 进行自动短信验证需要您按如下方式注册:

// Get an instance of SmsRetrieverClient, used to start listening for a matching
// SMS message.
SmsRetrieverClient client = SmsRetriever.getClient(this /* context */);
// Starts SmsRetriever, which waits for ONE matching SMS message until timeout
// (5 minutes). The matching SMS message will be sent via a Broadcast Intent with
// action SmsRetriever#SMS_RETRIEVED_ACTION.
Task<Void> task = client.startSmsRetriever();

而不是:

Task<Void> task = client.startSmsUserConsent(null);

使用 SMSRetrieve API,只有这样才能工作

context?.let { it ->
SmsRetriever.getClient(it).also {
// We can add user phone number or leave it blank
it.startSmsUserConsent(null)
.addOnSuccessListener { Log.d(TAG, "LISTENING_SUCCESS") }
.addOnFailureListener { Log.d(TAG, "LISTENING_FAILURE") }
}
} 

而不是

Task<Void> task = client.startSmsRetriever();

最新更新