0
我有一個應用程序是發送短信給每個來電。 BroadcastReceiver在前臺服務中註冊。由於某些原因,傳入呼叫的廣播接收器未被觸發。如果用戶銷燬並啓動服務,該應用會運行一段時間。在某些時候來電接收器未被觸發。傳入呼叫BroadcastReceiver不會被解僱一段時間後
下面是服務類:
public class SendSmsService extends Service {
private static Logger LOGGER = LoggerFactory.getLogger(SendSmsService.class);
private static final String SMS_SENT = "com.sms.sendsms.SMS_SENT";
private static final String SMS_DELIVERED = "com.sms.sendsms.SMS_DELIVERED";
private static final int MAX_SMS_MESSAGE_LENGTH = 160;
private static final int SMS_PORT = 16001;
private int mLastState = -1;
private static String recipientNumber;
private int smsNumber=1;
private NotificationManager mNotificationManager;
private User user;
private SharedPreferences sharedPref;
private AlarmManager alarmManager;
private TelephonyManager telephony;
private PendingIntent keepAlivePendingIntent;
private SharedPreferences prefs;
@Override
public void onCreate() {
super.onCreate();
LOGGER.info("Service is onCreate");
mNotificationManager
= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
sharedPref = getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE);
prefs = PreferenceManager.getDefaultSharedPreferences(SendSmsService.this);
LOGGER.info("registering incomingCallReceiver receiver");
LOGGER.info("registering receiver: SMS_SEND");
registerReceiver(sendSmsReceiver, new IntentFilter(SMS_SENT));
registerReceiver(incomingCallReceiver, new IntentFilter(
TelephonyManager.ACTION_PHONE_STATE_CHANGED));
alarmManager = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
telephony = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
Intent intent = new Intent(this, KeepAliveAlarmReceiver.class);
keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), AlarmManager.INTERVAL_HALF_DAY,
keepAlivePendingIntent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LOGGER.info("Service is onStartCommand");
sharedPref.edit().putBoolean(getString(R.string.is_service_running), true).apply();
user = ApplicationLoader.getApplication(SendSmsService.this)
.getDaoSession()
.getUserDao()
.queryBuilder()
.unique();
int iconId = R.drawable.icon;
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(SendSmsService.this)
.setContentTitle(getResources().getText(R.string.app_name))
.setSmallIcon(iconId)
.setWhen(System.currentTimeMillis());
Intent nIntent = getPackageManager().
getLaunchIntentForPackage(ContextConstants.PACKAGE_NAME);
PendingIntent pendingIntent = PendingIntent.getActivity(SendSmsService.this, 0, nIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(pendingIntent);
startForeground(NotificationConstants.LAUNCHER_SERVICE_NOTE_ID,
notificationBuilder.build());
return START_STICKY;
}
private BroadcastReceiver sendSmsReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
LOGGER.info("sendSmsReceiver is received");
String message;
switch (getResultCode()) {
case Activity.RESULT_OK:
message = context.getResources().getString(R.string.msg_sent) + " " + recipientNumber;
SmsLog smsLog = new SmsLog();
String dateString = (String) DateFormat.format("dd/MM/yyyy h:mm a", new java.util.Date());
smsLog.setSentDate(dateString);
smsLog.setSentNumber(recipientNumber);
ApplicationLoader.getApplication(SendSmsService.this)
.getDaoSession()
.getSmsLogDao()
.insert(smsLog);
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
message = context.getResources().getString(R.string.error_msg);
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
message = context.getResources().getString(R.string.no_service);
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
message = context.getResources().getString(R.string.error_pdu);
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
message = context.getResources().getString(R.string.radio_off);
break;
default: {
message = context.getResources().getString(R.string.unknown_error_sent_msg);
break;
}
}
showSmsSendNotification(message);
LOGGER.info("sendSmsReceiver message = " + message);
}
};
@Override
public void onDestroy() {
super.onDestroy();
LOGGER.info("Service is onDestroy");
sharedPref.edit().putBoolean(getString(R.string.is_service_running), false).apply();
telephony.listen(phoneListener, PhoneStateListener.LISTEN_NONE);
unregisterReceiver(incomingCallReceiver);
unregisterReceiver(sendSmsReceiver);
alarmManager.cancel(keepAlivePendingIntent);
mNotificationManager.cancel(NotificationConstants.SEND_SMS_MSG);
mNotificationManager.cancel(NotificationConstants.LAUNCHER_SERVICE_NOTE_ID);
LOGGER.info("Unregistered all receiver and stopped successfully.");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private BroadcastReceiver incomingCallReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
LOGGER.info("IncomingCallReceiver is received.");
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
};
private PhoneStateListener phoneListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
LOGGER.info("phoneListener state : " + state);
if (state == mLastState) {
return;
}
if (state == TelephonyManager.CALL_STATE_RINGING) {
mLastState = state;
sendSms(incomingNumber, user.getMessageBody(), false);
}
/*after finishing call state android returns CALL_STATE_IDLE*/
if (state == TelephonyManager.CALL_STATE_IDLE) {
LOGGER.info("incomingCall finished state = " + state);
mLastState = -1;
}
}
};
private void showSmsSendNotification(String message) {
boolean isEnabledNty = sharedPref.getBoolean(getResources().getString(R.string.is_enable_notifying), true);
LOGGER.info("Enable notification = " + isEnabledNty);
if (isEnabledNty) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(SendSmsService.this)
.setContentTitle(getResources().getText(R.string.app_name))
.setContentText(message)
.setSmallIcon(R.drawable.icon)
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_ALL);
Notification notification = notificationBuilder.build();
notification.defaults = Notification.DEFAULT_ALL;
notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
mNotificationManager.notify(NotificationConstants.SEND_SMS_MSG, notification);
}
}
private void sendSms(String phoneNumber,String messageText, boolean isBinary) {
LOGGER.info("Sending sms to phoneNumber = " + phoneNumber);
if (phoneNumber == null || phoneNumber.isEmpty()) {
LOGGER.info("Failed: Couldn't sent message to number = " + phoneNumber);
mLastState = -1;
return;
}
if (ApplicationLoader.getApplication(this)
.getDaoSession()
.getBlackListDao()
.queryBuilder()
.where(BlackListDao.Properties.Number.eq(phoneNumber)).buildCount().count() != 0) {
LOGGER.info("Failed: Number in blockList = " + phoneNumber);
mLastState = -1;
return;
}
if (messageText == null || messageText.isEmpty()) {
LOGGER.info("Error: Sending msg content empty or null message = " + messageText);
mLastState = -1;
return;
}
List<SmsLog> smsList = ApplicationLoader.getApplication(this)
.getDaoSession()
.getSmsLogDao()
.queryBuilder()
.where(SmsLogDao.Properties.SentNumber.eq(phoneNumber))
.build()
.list();
int smsListSize = smsList.size();
if (smsListSize > 0) {
Resources res = getResources();
String period = prefs.getString("send_sms_period", res.getString(R.string.everytime));
String everytime = res.getString(R.string.everytime);
String onceADay = res.getString(R.string.once_day);
String onceAWeek = res.getString(R.string.once_week);
String onceAMonth = res.getString(R.string.once_month);
long settingsPeriod = 0;
if (period.equals(everytime)) {
settingsPeriod = ContextConstants.EVERYTIME_PERIOD;
} else if (period.equals(onceADay)) {
settingsPeriod = ContextConstants.ONE_DAY_PERIOD;
} else if (period.equals(onceAWeek)) {
settingsPeriod = ContextConstants.WEEK_DAY_PERIOD;
} else {
settingsPeriod = ContextConstants.MONTH_DAY_PERIOD;
}
try {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy h:mm a");
Date date = format.parse(smsList.get(smsListSize - 1).getSentDate());
Calendar thatDay = Calendar.getInstance();
thatDay.setTime(date);
if (settingsPeriod != ContextConstants.EVERYTIME_PERIOD &&
!DateUtil.isMoreThanSelectedDays(thatDay, settingsPeriod)) {
LOGGER.info("SEND SMS PERIOD = " + settingsPeriod + " LAST SENT SMS date = " + date.toString());
return;
}
} catch (ParseException e) {
e.printStackTrace();
}
} else {
LOGGER.info("It is the first time to send sms size = " + smsList.size());
}
LOGGER.info("Sending probable success ");
recipientNumber = phoneNumber;
SmsManager smsManager = SmsManager.getDefault();
PendingIntent piSend = PendingIntent.getBroadcast(this, 0, new Intent(SMS_SENT), 0);
PendingIntent piDelivered = PendingIntent.getBroadcast(this, 0, new Intent(SMS_DELIVERED), 0);
messageText = messageText+" "+smsNumber;
smsNumber++;
ArrayList<String> parts = smsManager.divideMessage(messageText);
int partsCount = parts.size();
ArrayList<PendingIntent> sentIntents = new ArrayList<>(partsCount);
ArrayList<PendingIntent> deliveryIntents = new ArrayList<>(partsCount);
for (int i = 0; i < partsCount; i++) {
sentIntents.add(i, piSend);
deliveryIntents.add(i, piDelivered);
}
smsManager.sendMultipartTextMessage(phoneNumber, null, parts, sentIntents, deliveryIntents);
}
}
我花了四天。我無法找到這個錯誤並且瘋了。我將衷心感謝您的幫助。
服務處於前臺,接收方在服務中註冊。如果你提到的原因是真的,那麼在應用程序的onDestroy方法被調用時,它是如何工作幾個小時的。 –
應用程序的onDestroy或服務的onDestroy –
應用程序的onDestory –