This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

smsreceiver.java

By: a guest on Nov 30th, 2011  |  syntax: Java  |  size: 10.96 KB  |  views: 41  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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.  
clone this paste RAW Paste Data