Advertisement
Guest User

smsreceiver.java

a guest
Nov 30th, 2011
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.96 KB | None | 0 0
  1. package com.texter.messenger;
  2.  
  3. import java.util.List;
  4.  
  5. import android.app.Activity;
  6. import android.app.PendingIntent;
  7. import android.app.PendingIntent.CanceledException;
  8. import android.app.Service;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.content.pm.PackageManager;
  12. import android.content.pm.ResolveInfo;
  13. import android.net.Uri;
  14. import android.os.Bundle;
  15. import android.os.Handler;
  16. import android.os.HandlerThread;
  17. import android.os.IBinder;
  18. import android.os.Looper;
  19. import android.os.Message;
  20. import android.os.PowerManager;
  21. import android.os.Process;
  22. import android.telephony.SmsManager;
  23. import android.telephony.SmsMessage;
  24. import android.telephony.SmsMessage.MessageClass;
  25. import android.telephony.TelephonyManager;
  26. import android.util.Log;
  27.  
  28. import com.texter.common.TexterConstants;
  29. import com.texter.common.TexterNotification;
  30. import com.texter.common.Utils;
  31. import com.texter.data.TexterDB;
  32. import com.texter.data.TexterDB.Schedule;
  33. import com.texter.preferences.TexterPreferenceManager;
  34. import com.texterpro.app.ConversationList;
  35. import com.texterpro.app.R;
  36. import com.texterpro.app.SmsPopupView;
  37.  
  38. public class SmsReceiverService extends Service {
  39.  
  40.     private static final String LOG_TAG = TexterConstants.COMMON_TAG;
  41.  
  42.     private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
  43.     private static final String ACTION_MMS_RECEIVED = "android.provider.Telephony.WAP_PUSH_RECEIVED";
  44.     private static final String ACTION_MESSAGE_RECEIVED = "net.everythingandroid.smspopup.MESSAGE_RECEIVED";
  45.     private static final String MMS_DATA_TYPE = "application/vnd.wap.mms-message";
  46.  
  47.     // http://android.git.kernel.org/?p=platform/packages/apps/Mms.git;a=blob;f=src/com/android/mms/transaction/SmsReceiverService.java
  48.     public static final String MESSAGE_SENT_ACTION = "com.android.mms.transaction.MESSAGE_SENT";
  49.  
  50.     /*
  51.      * This is the number of retries and pause between retries that we will keep
  52.      * checking the system message database for the latest incoming message
  53.      */
  54.     private static final int MESSAGE_RETRY = 8;
  55.     private static final int MESSAGE_RETRY_PAUSE = 1000;
  56.  
  57.     private Context context;
  58.     private ServiceHandler mServiceHandler;
  59.     private Looper mServiceLooper;
  60.     private int mResultCode;
  61.  
  62.     private static final Object mStartingServiceSync = new Object();
  63.     private static PowerManager.WakeLock mStartingService;
  64.  
  65.     private static final int TOAST_HANDLER_MESSAGE_SENT = 0;
  66.     private static final int TOAST_HANDLER_MESSAGE_SEND_LATER = 1;
  67.     private static final int TOAST_HANDLER_MESSAGE_FAILED = 2;
  68.  
  69.     @Override
  70.     public void onCreate() {
  71.         HandlerThread thread = new HandlerThread("Log.LOGTAG",
  72.                 Process.THREAD_PRIORITY_BACKGROUND);
  73.         thread.start();
  74.         context = getApplicationContext();
  75.         mServiceLooper = thread.getLooper();
  76.         mServiceHandler = new ServiceHandler(mServiceLooper);
  77.         Log.v(LOG_TAG, "Oncreate");
  78.     }
  79.  
  80.     @Override
  81.     public void onStart(Intent intent, int startId) {
  82.         Log.v(LOG_TAG, "OnStart");
  83.         mResultCode = intent != null ? intent.getIntExtra("result", 0) : 0;
  84.  
  85.         Message msg = mServiceHandler.obtainMessage();
  86.         msg.arg1 = startId;
  87.         msg.obj = intent;
  88.         mServiceHandler.sendMessage(msg);
  89.     }
  90.  
  91.     @Override
  92.     public void onDestroy() {
  93.         mServiceLooper.quit();
  94.     }
  95.  
  96.     @Override
  97.     public IBinder onBind(Intent intent) {
  98.         return null;
  99.     }
  100.  
  101.     private final class ServiceHandler extends Handler {
  102.         public ServiceHandler(Looper looper) {
  103.             super(looper);
  104.         }
  105.  
  106.         @Override
  107.         public void handleMessage(Message msg) {
  108.             Log.v(LOG_TAG, "handlemessage:");
  109.             Log.v(LOG_TAG, msg.toString());
  110.             int serviceId = msg.arg1;
  111.             Intent intent = (Intent) msg.obj;
  112.             String action = intent.getAction();
  113.             String dataType = intent.getType();
  114.  
  115.             if (ACTION_SMS_RECEIVED.equals(action)) {
  116.                 handleSmsReceived(intent);
  117.             } else if (ACTION_MMS_RECEIVED.equals(action)
  118.                     && MMS_DATA_TYPE.equals(dataType)) {
  119.                 handleMmsReceived(intent);
  120.             } else if (MESSAGE_SENT_ACTION.equals(action)) {
  121.                 handleSmsSent(intent);
  122.             } else if (ACTION_MESSAGE_RECEIVED.equals(action)) {
  123.                 handleMessageReceived(intent);
  124.             }
  125.  
  126.             // NOTE: We MUST not call stopSelf() directly, since we need to
  127.             // make sure the wake lock acquired by AlertReceiver is released.
  128.             finishStartingService(SmsReceiverService.this, serviceId);
  129.         }
  130.     }
  131.  
  132.     /**
  133.      * Handle receiving a SMS message
  134.      */
  135.     private void handleSmsReceived(Intent intent) {
  136.  
  137.         Bundle bundle = intent.getExtras();
  138.         if (bundle != null) {
  139.             SmsMessage[] messages = Utils.getMessagesFromIntent(intent);
  140.             if (messages != null) {
  141.                 notifyMessageReceived(new SmsMmsMessage(context, messages,
  142.                         System.currentTimeMillis()));
  143.             }
  144.         }
  145.     }
  146.  
  147.     private void notifyMessageReceived(SmsMmsMessage message) {
  148.  
  149.         // Class 0 SMS, let the system handle this
  150.         if (message.getMessageType() == SmsMmsMessage.MESSAGE_TYPE_SMS
  151.                 && message.getMessageClass() == MessageClass.CLASS_0) {
  152.             return;
  153.         }
  154.  
  155.         TelephonyManager mTM = (TelephonyManager) context
  156.                 .getSystemService(Context.TELEPHONY_SERVICE);
  157.         boolean callStateIdle = mTM.getCallState() == TelephonyManager.CALL_STATE_IDLE;
  158.  
  159.         /*
  160.          * If popup is enabled for this user -AND- the user is not in a call
  161.          * -AND- -AND- phone is not docked -AND- (screen is locked -OR- (setting
  162.          * is OFF to only show on keyguard -AND- user is not in messaging app:
  163.          * then show the popup activity, otherwise check if notifications are on
  164.          * and just use the standard notification))
  165.          */
  166.  
  167.         boolean isApp = TexterPreferenceManager.getInstance(this)
  168.                 .isAppEnabled();
  169.         boolean showPop = TexterPreferenceManager.getInstance(this)
  170.                 .isPopupEnabled();
  171.         boolean showNotify = TexterPreferenceManager.getInstance(this)
  172.                 .isNotifyEnabled();
  173.  
  174.         // Log.v(LOG_TAG," App = "+ isApp );
  175.         // Log.v(LOG_TAG," pop = "+showPop );
  176.         // Log.v(LOG_TAG," notify = "+showNotify );
  177.  
  178.         // if conversationList is visible then do not show pop
  179.         if (!ConversationList.isVisible()) {
  180.             if (isApp && callStateIdle && showPop) {
  181.                 // Log.v(LOG_TAG," showing popup = " );
  182.                 if (!SmsPopupView.isPopupVisible())
  183.                     context.startActivity(message.getPopupIntent());
  184.             }
  185.         }
  186.  
  187.         if (isApp && showNotify) {
  188.             TexterNotification.ShowMessageNotification(this, message);
  189.         }
  190.  
  191.     }
  192.  
  193.     /**
  194.      * Handle receiving a MMS message
  195.      */
  196.     private void handleMmsReceived(Intent intent) {
  197.  
  198.     }
  199.  
  200.     /**
  201.      * Handle receiving an arbitrary message (potentially coming from a 3rd
  202.      * party app)
  203.      */
  204.     private void handleMessageReceived(Intent intent) {
  205.  
  206.         Bundle bundle = intent.getExtras();
  207.         if (bundle != null) {
  208.         }
  209.     }
  210.  
  211.     /*
  212.      * Handler to deal with showing Toast messages for message sent status
  213.      */
  214.     public Handler mToastHandler = new Handler() {
  215.         @Override
  216.         public void handleMessage(Message msg) {
  217.  
  218.             if (msg != null) {
  219.                 switch (msg.what) {
  220.                 case TOAST_HANDLER_MESSAGE_SENT:
  221.                     // TexterNotification.showToast(SmsReceiverService.this,R.string.quickreply_sent_toast);
  222.                     break;
  223.                 case TOAST_HANDLER_MESSAGE_SEND_LATER:
  224.                     TexterNotification.showToast(SmsReceiverService.this,
  225.                             R.string.quickreply_failed_send_later);
  226.                     break;
  227.                 case TOAST_HANDLER_MESSAGE_FAILED:
  228.                     TexterNotification.showToast(SmsReceiverService.this,
  229.                             R.string.quickreply_failed);
  230.                     break;
  231.                 }
  232.             }
  233.         }
  234.     };
  235.  
  236.     /*
  237.      * Handle the result of a sms being sent
  238.      */
  239.     private void handleSmsSent(Intent intent) {
  240.  
  241.         Log.v(LOG_TAG, "HandleSMSSent called");
  242.         PackageManager pm = getPackageManager();
  243.         Intent sysIntent = null;
  244.         Intent tempIntent;
  245.         List<ResolveInfo> receiverList;
  246.         boolean forwardToSystemApp = true;
  247.  
  248.         // Search for system messaging app that will receive our
  249.         // "message sent complete" type intent
  250.         tempIntent = intent.setClassName(
  251.                 SmsMessageSender.MESSAGING_PACKAGE_NAME,
  252.                 SmsMessageSender.MESSAGING_RECEIVER_CLASS_NAME);
  253.  
  254.         tempIntent.setAction(SmsReceiverService.MESSAGE_SENT_ACTION);
  255.  
  256.         receiverList = pm.queryBroadcastReceivers(tempIntent, 0);
  257.  
  258.         if (receiverList.size() > 0) {
  259.             sysIntent = tempIntent;
  260.         }
  261.  
  262.         Bundle b = intent.getExtras();
  263.         long rowid = 0;
  264.  
  265.         rowid = b == null ? 0 : b.getLong("ROWID");
  266.  
  267.         /*
  268.          * No system messaging app was found to forward this intent to,
  269.          * therefore we will need to do the final piece of this ourselves which
  270.          * is basically moving the message to the correct folder depending on
  271.          * the result.
  272.          */
  273.         // TexterNotification.showToast(SmsReceiverService.this,
  274.         // "before moving folder");
  275.         if (sysIntent == null) {
  276.  
  277.             forwardToSystemApp = false;
  278.             Uri uri = intent.getData();
  279.             Log.v(LOG_TAG, "id = " + rowid);
  280.             if (mResultCode == Activity.RESULT_OK) {
  281.                 SmsMessageSender.moveMessageToFolder(this, uri,
  282.                         SmsMessageSender.MESSAGE_TYPE_SENT);
  283.             } else if ((mResultCode == SmsManager.RESULT_ERROR_RADIO_OFF)
  284.                     || (mResultCode == SmsManager.RESULT_ERROR_NO_SERVICE)) {
  285.                 SmsMessageSender.moveMessageToFolder(this, uri,
  286.                         SmsMessageSender.MESSAGE_TYPE_QUEUED);
  287.             } else {
  288.                 SmsMessageSender.moveMessageToFolder(this, uri,
  289.                         SmsMessageSender.MESSAGE_TYPE_FAILED);
  290.             }
  291.         }
  292.  
  293.         // Check the result and notify the user using a toast
  294.         if (mResultCode == Activity.RESULT_OK) {
  295.             mToastHandler.sendEmptyMessage(TOAST_HANDLER_MESSAGE_SENT);
  296.             TexterDB.getInstance().updateStatus(rowid,
  297.                     Schedule.STATUS_SCHEDULED_SENT, 0);
  298.         } else if ((mResultCode == SmsManager.RESULT_ERROR_RADIO_OFF)
  299.                 || (mResultCode == SmsManager.RESULT_ERROR_NO_SERVICE)) {
  300.             TexterDB.getInstance().updateStatus(rowid,
  301.                     Schedule.STATUS_NOT_SENT, -1);
  302.         } else {
  303.             mToastHandler.sendEmptyMessage(TOAST_HANDLER_MESSAGE_FAILED);
  304.             TexterDB.getInstance().updateStatus(rowid,
  305.                     Schedule.STATUS_NOT_SENT, mResultCode);
  306.         }
  307.  
  308.         if (forwardToSystemApp) {
  309.             try {
  310.                 PendingIntent.getBroadcast(this, 0, sysIntent, 0).send(
  311.                         mResultCode);
  312.             } catch (CanceledException e) {
  313.                 e.printStackTrace();
  314.             }
  315.         }
  316.     }
  317.  
  318.     /**
  319.      * Start the service to process the current event notifications, acquiring
  320.      * the wake lock before returning to ensure that the service will run.
  321.      */
  322.     public static void beginStartingService(Context context, Intent intent) {
  323.         synchronized (mStartingServiceSync) {
  324.             if (mStartingService == null) {
  325.                 PowerManager pm = (PowerManager) context
  326.                         .getSystemService(Context.POWER_SERVICE);
  327.                 mStartingService = pm.newWakeLock(
  328.                         PowerManager.PARTIAL_WAKE_LOCK,
  329.                         "Texter.SmsReceiverService");
  330.                 mStartingService.setReferenceCounted(false);
  331.             }
  332.             mStartingService.acquire();
  333.             context.startService(intent);
  334.             Log.v(LOG_TAG, "service started");
  335.         }
  336.     }
  337.  
  338.     /**
  339.      * Called back by the service when it has finished processing notifications,
  340.      * releasing the wake lock if the service is now stopping.
  341.      */
  342.     public static void finishStartingService(Service service, int startId) {
  343.         synchronized (mStartingServiceSync) {
  344.             if (mStartingService != null) {
  345.                 if (service.stopSelfResult(startId)) {
  346.                     mStartingService.release();
  347.                 }
  348.             }
  349.         }
  350.     }
  351.  
  352. }
  353.  
  354.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement