Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.texter.messenger;
- import java.util.List;
- import android.app.Activity;
- import android.app.PendingIntent;
- import android.app.PendingIntent.CanceledException;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
- import android.content.pm.PackageManager;
- import android.content.pm.ResolveInfo;
- import android.net.Uri;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.os.IBinder;
- import android.os.Looper;
- import android.os.Message;
- import android.os.PowerManager;
- import android.os.Process;
- import android.telephony.SmsManager;
- import android.telephony.SmsMessage;
- import android.telephony.SmsMessage.MessageClass;
- import android.telephony.TelephonyManager;
- import android.util.Log;
- import com.texter.common.TexterConstants;
- import com.texter.common.TexterNotification;
- import com.texter.common.Utils;
- import com.texter.data.TexterDB;
- import com.texter.data.TexterDB.Schedule;
- import com.texter.preferences.TexterPreferenceManager;
- import com.texterpro.app.ConversationList;
- import com.texterpro.app.R;
- import com.texterpro.app.SmsPopupView;
- public class SmsReceiverService extends Service {
- private static final String LOG_TAG = TexterConstants.COMMON_TAG;
- private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
- private static final String ACTION_MMS_RECEIVED = "android.provider.Telephony.WAP_PUSH_RECEIVED";
- private static final String ACTION_MESSAGE_RECEIVED = "net.everythingandroid.smspopup.MESSAGE_RECEIVED";
- private static final String MMS_DATA_TYPE = "application/vnd.wap.mms-message";
- // http://android.git.kernel.org/?p=platform/packages/apps/Mms.git;a=blob;f=src/com/android/mms/transaction/SmsReceiverService.java
- public static final String MESSAGE_SENT_ACTION = "com.android.mms.transaction.MESSAGE_SENT";
- /*
- * This is the number of retries and pause between retries that we will keep
- * checking the system message database for the latest incoming message
- */
- private static final int MESSAGE_RETRY = 8;
- private static final int MESSAGE_RETRY_PAUSE = 1000;
- private Context context;
- private ServiceHandler mServiceHandler;
- private Looper mServiceLooper;
- private int mResultCode;
- private static final Object mStartingServiceSync = new Object();
- private static PowerManager.WakeLock mStartingService;
- private static final int TOAST_HANDLER_MESSAGE_SENT = 0;
- private static final int TOAST_HANDLER_MESSAGE_SEND_LATER = 1;
- private static final int TOAST_HANDLER_MESSAGE_FAILED = 2;
- @Override
- public void onCreate() {
- HandlerThread thread = new HandlerThread("Log.LOGTAG",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
- context = getApplicationContext();
- mServiceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(mServiceLooper);
- Log.v(LOG_TAG, "Oncreate");
- }
- @Override
- public void onStart(Intent intent, int startId) {
- Log.v(LOG_TAG, "OnStart");
- mResultCode = intent != null ? intent.getIntExtra("result", 0) : 0;
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- msg.obj = intent;
- mServiceHandler.sendMessage(msg);
- }
- @Override
- public void onDestroy() {
- mServiceLooper.quit();
- }
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- Log.v(LOG_TAG, "handlemessage:");
- Log.v(LOG_TAG, msg.toString());
- int serviceId = msg.arg1;
- Intent intent = (Intent) msg.obj;
- String action = intent.getAction();
- String dataType = intent.getType();
- if (ACTION_SMS_RECEIVED.equals(action)) {
- handleSmsReceived(intent);
- } else if (ACTION_MMS_RECEIVED.equals(action)
- && MMS_DATA_TYPE.equals(dataType)) {
- handleMmsReceived(intent);
- } else if (MESSAGE_SENT_ACTION.equals(action)) {
- handleSmsSent(intent);
- } else if (ACTION_MESSAGE_RECEIVED.equals(action)) {
- handleMessageReceived(intent);
- }
- // NOTE: We MUST not call stopSelf() directly, since we need to
- // make sure the wake lock acquired by AlertReceiver is released.
- finishStartingService(SmsReceiverService.this, serviceId);
- }
- }
- /**
- * Handle receiving a SMS message
- */
- private void handleSmsReceived(Intent intent) {
- Bundle bundle = intent.getExtras();
- if (bundle != null) {
- SmsMessage[] messages = Utils.getMessagesFromIntent(intent);
- if (messages != null) {
- notifyMessageReceived(new SmsMmsMessage(context, messages,
- System.currentTimeMillis()));
- }
- }
- }
- private void notifyMessageReceived(SmsMmsMessage message) {
- // Class 0 SMS, let the system handle this
- if (message.getMessageType() == SmsMmsMessage.MESSAGE_TYPE_SMS
- && message.getMessageClass() == MessageClass.CLASS_0) {
- return;
- }
- TelephonyManager mTM = (TelephonyManager) context
- .getSystemService(Context.TELEPHONY_SERVICE);
- boolean callStateIdle = mTM.getCallState() == TelephonyManager.CALL_STATE_IDLE;
- /*
- * If popup is enabled for this user -AND- the user is not in a call
- * -AND- -AND- phone is not docked -AND- (screen is locked -OR- (setting
- * is OFF to only show on keyguard -AND- user is not in messaging app:
- * then show the popup activity, otherwise check if notifications are on
- * and just use the standard notification))
- */
- boolean isApp = TexterPreferenceManager.getInstance(this)
- .isAppEnabled();
- boolean showPop = TexterPreferenceManager.getInstance(this)
- .isPopupEnabled();
- boolean showNotify = TexterPreferenceManager.getInstance(this)
- .isNotifyEnabled();
- // Log.v(LOG_TAG," App = "+ isApp );
- // Log.v(LOG_TAG," pop = "+showPop );
- // Log.v(LOG_TAG," notify = "+showNotify );
- // if conversationList is visible then do not show pop
- if (!ConversationList.isVisible()) {
- if (isApp && callStateIdle && showPop) {
- // Log.v(LOG_TAG," showing popup = " );
- if (!SmsPopupView.isPopupVisible())
- context.startActivity(message.getPopupIntent());
- }
- }
- if (isApp && showNotify) {
- TexterNotification.ShowMessageNotification(this, message);
- }
- }
- /**
- * Handle receiving a MMS message
- */
- private void handleMmsReceived(Intent intent) {
- }
- /**
- * Handle receiving an arbitrary message (potentially coming from a 3rd
- * party app)
- */
- private void handleMessageReceived(Intent intent) {
- Bundle bundle = intent.getExtras();
- if (bundle != null) {
- }
- }
- /*
- * Handler to deal with showing Toast messages for message sent status
- */
- public Handler mToastHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg != null) {
- switch (msg.what) {
- case TOAST_HANDLER_MESSAGE_SENT:
- // TexterNotification.showToast(SmsReceiverService.this,R.string.quickreply_sent_toast);
- break;
- case TOAST_HANDLER_MESSAGE_SEND_LATER:
- TexterNotification.showToast(SmsReceiverService.this,
- R.string.quickreply_failed_send_later);
- break;
- case TOAST_HANDLER_MESSAGE_FAILED:
- TexterNotification.showToast(SmsReceiverService.this,
- R.string.quickreply_failed);
- break;
- }
- }
- }
- };
- /*
- * Handle the result of a sms being sent
- */
- private void handleSmsSent(Intent intent) {
- Log.v(LOG_TAG, "HandleSMSSent called");
- PackageManager pm = getPackageManager();
- Intent sysIntent = null;
- Intent tempIntent;
- List<ResolveInfo> receiverList;
- boolean forwardToSystemApp = true;
- // Search for system messaging app that will receive our
- // "message sent complete" type intent
- tempIntent = intent.setClassName(
- SmsMessageSender.MESSAGING_PACKAGE_NAME,
- SmsMessageSender.MESSAGING_RECEIVER_CLASS_NAME);
- tempIntent.setAction(SmsReceiverService.MESSAGE_SENT_ACTION);
- receiverList = pm.queryBroadcastReceivers(tempIntent, 0);
- if (receiverList.size() > 0) {
- sysIntent = tempIntent;
- }
- Bundle b = intent.getExtras();
- long rowid = 0;
- rowid = b == null ? 0 : b.getLong("ROWID");
- /*
- * No system messaging app was found to forward this intent to,
- * therefore we will need to do the final piece of this ourselves which
- * is basically moving the message to the correct folder depending on
- * the result.
- */
- // TexterNotification.showToast(SmsReceiverService.this,
- // "before moving folder");
- if (sysIntent == null) {
- forwardToSystemApp = false;
- Uri uri = intent.getData();
- Log.v(LOG_TAG, "id = " + rowid);
- if (mResultCode == Activity.RESULT_OK) {
- SmsMessageSender.moveMessageToFolder(this, uri,
- SmsMessageSender.MESSAGE_TYPE_SENT);
- } else if ((mResultCode == SmsManager.RESULT_ERROR_RADIO_OFF)
- || (mResultCode == SmsManager.RESULT_ERROR_NO_SERVICE)) {
- SmsMessageSender.moveMessageToFolder(this, uri,
- SmsMessageSender.MESSAGE_TYPE_QUEUED);
- } else {
- SmsMessageSender.moveMessageToFolder(this, uri,
- SmsMessageSender.MESSAGE_TYPE_FAILED);
- }
- }
- // Check the result and notify the user using a toast
- if (mResultCode == Activity.RESULT_OK) {
- mToastHandler.sendEmptyMessage(TOAST_HANDLER_MESSAGE_SENT);
- TexterDB.getInstance().updateStatus(rowid,
- Schedule.STATUS_SCHEDULED_SENT, 0);
- } else if ((mResultCode == SmsManager.RESULT_ERROR_RADIO_OFF)
- || (mResultCode == SmsManager.RESULT_ERROR_NO_SERVICE)) {
- TexterDB.getInstance().updateStatus(rowid,
- Schedule.STATUS_NOT_SENT, -1);
- } else {
- mToastHandler.sendEmptyMessage(TOAST_HANDLER_MESSAGE_FAILED);
- TexterDB.getInstance().updateStatus(rowid,
- Schedule.STATUS_NOT_SENT, mResultCode);
- }
- if (forwardToSystemApp) {
- try {
- PendingIntent.getBroadcast(this, 0, sysIntent, 0).send(
- mResultCode);
- } catch (CanceledException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * Start the service to process the current event notifications, acquiring
- * the wake lock before returning to ensure that the service will run.
- */
- public static void beginStartingService(Context context, Intent intent) {
- synchronized (mStartingServiceSync) {
- if (mStartingService == null) {
- PowerManager pm = (PowerManager) context
- .getSystemService(Context.POWER_SERVICE);
- mStartingService = pm.newWakeLock(
- PowerManager.PARTIAL_WAKE_LOCK,
- "Texter.SmsReceiverService");
- mStartingService.setReferenceCounted(false);
- }
- mStartingService.acquire();
- context.startService(intent);
- Log.v(LOG_TAG, "service started");
- }
- }
- /**
- * Called back by the service when it has finished processing notifications,
- * releasing the wake lock if the service is now stopping.
- */
- public static void finishStartingService(Service service, int startId) {
- synchronized (mStartingServiceSync) {
- if (mStartingService != null) {
- if (service.stopSelfResult(startId)) {
- mStartingService.release();
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement