В этом приложении я хочу записать информацию о входящих SMS (с определенного номера) в файл, даже если программа не «активна» от пользователя. Что ж, после некоторых исследований я обнаружил, что эти ссылки BroadcastReceiver SMS_Received не работают на новых устройствах (я использую Xiaomi Redmi Note 4) и Как заставить Android запускать приложение при получении определенного sms, в котором говорится, что "BroadcastReceiver может быть запущен из ОС, если это указано в файле манифеста". Что ж, я пробовал эти решения, но ни одно из них не работает на моем устройстве. Они работают как положено, когда приложение открыто, но когда оно закрывается, ничего не происходит (я также пытался перезагрузить свое устройство). * Параллельно есть еще несколько вопросов, на которые отмечен правильный ответ - создать сервис.
Код для BroadcastReceiver:
public class NewSMSReceived : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (Android.Provider.Telephony.Sms.Intents.SmsReceivedAction.Equals(intent.Action))
{
Toast.MakeText(context, "BroadcastReceiver is activated...", ToastLength.Long).Show();
var info_Intent = intent.Extras;
if (info_Intent != null)
{
Java.Lang.Object[] pdus = (Java.Lang.Object[])info_Intent.Get("pdus");
var msg = SmsMessage.CreateFromPdu((byte[])pdus[0]);
var msg_from = msg.DisplayOriginatingAddress;
var CellNumfilePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath.ToString(), "\\MyApp\\CellNum.txt");
if (msg_from == ("xxxx" + File.ReadAllText(CellNumfilePath)))
{
Toast.MakeText(Application.Context, "New message from XXXXX", ToastLength.Long).Show();
var msg_txt_date = msg.MessageBody + "\t" + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss");
var DataStorfilePath = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath.ToString(), "\\MyApp\\ObtainedData.txt");
File.AppendAllText(DataStorfilePath, msg_txt_date + Environment.NewLine);
}
}
}
}
}
Файл манифеста:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="myApp.AndroidApp" android:installLocation="auto">
<uses-sdk android:minSdkVersion="22" android:targetSdkVersion="25" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.BROADCAST_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<receiver android:name=".NewSMSReceived"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_SMS"
>
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
Метод, используемый для запроса разрешений во время выполнения
private void CheckMandatoryPermissions()
{
string SMSpermission = Manifest.Permission.ReadSms;
string[] NeededPermissions =
{
Manifest.Permission.ReadSms,
Manifest.Permission.ReceiveSms,
Manifest.Permission.SendSms,
Manifest.Permission.WriteSms,
Manifest.Permission.BroadcastSms,
Manifest.Permission.ReadExternalStorage,
Manifest.Permission.WriteExternalStorage,
Manifest.Permission.ReadSms,
Manifest.Permission.ReceiveBootCompleted
};
bool needed_conditions = CheckSelfPermission(SMSpermission) != (int)Permission.Granted || CheckSelfPermission(Manifest.Permission.ReceiveSms) != (int)Permission.Granted;
if (needed_conditions)
{
//Explain to the user why we need to access SMS and storage
var messageView = FindViewById<TextView>(Resource.Id.ZipCodeSearchLabel);
string messageInfo = "XXXXX";
Snackbar ReasonMessage = Snackbar.Make((View)messageView, messageInfo, Snackbar.LengthIndefinite);
View snackbarView = ReasonMessage.View;
TextView snacktext = (TextView)snackbarView.FindViewById<TextView>(Resource.Id.snackbar_text);
snacktext.SetMaxLines(4);
//snackbarView.SetMinimumHeight(300);
ReasonMessage.SetAction("OK", v => RequestPermissions(NeededPermissions, 0)).Show();
return;
}
}
Я также пытался указать получателя не из манифеста, а из класса и всегда с одним и тем же результатом. Я не думаю, что проблема связана с разрешениями, потому что я могу «поймать» новую смс во время работы приложения. Какие-либо предложения? заранее спасибо
permission
в элементе<receiver>
должно бытьandroid.permission.BROADCAST_SMS
, а неRECEIVE
. Кроме того, если вы используете Marshmallow или более позднюю версию, вам может потребоваться запросить все разрешения для SMS во время выполнения, но, похоже, вы справились с этим, если это необходимо. - person Mike M.   schedule 31.10.2018NewSMSReceived
находится в вашем основном исходном каталоге? То есть правильный ли атрибутname
в<receiver>
? Пробовали ли вы что-то кромеToast
s для проверки приемника? Например, журнал печатает в самом верхуOnReceive()
, просто чтобы проверить, работает ли он вообще? Кроме того, само ваше приложение не может иметь разрешениеBROADCAST_SMS
, поэтому вы можете удалить соответствующий элемент<uses-permission>
в манифесте и элементNeededPermissions
. - person Mike M.   schedule 31.10.2018OnReceive()
и проверить свои журналы на случай, если что-то не получится там до записи файла. Что касаетсяname
, AFAICT из других примеров, это должно быть хорошо, но я не очень хорошо знаком с Xamarin. Вы можете посмотреть этот ответ для получения информации о том, как обрабатывать это в обоих направлениях в Xamarin. Кроме того, пожалуйста, обратите внимание на этот параметр/разрешение, о котором я упоминал. У меня было несколько вопросов по SMS, решенных здесь, когда я обнаружил, что проблема в этом. - person Mike M.   schedule 31.10.2018<receiver>
заработает. Я предполагал, что вы уже делаете это, потому что вам нужно запрашивать разрешения во время выполнения. Была ли эта проблема и в Xiaomi? Или это все еще не работает, если вы полностью закроете приложение? - person Mike M.   schedule 31.10.2018