Android Open Source - javocsoft-toolbox S M S Observer






From Project

Back to project page javocsoft-toolbox.

License

The source code is released under:

GNU General Public License

If you think the Android project javocsoft-toolbox listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2010-2014 - JavocSoft - Javier Gonzalez Serrano
 * http://javocsoft.es/proyectos/code-libs/android/javocsoft-toolbox-android-library
 * //from  www  . j a v a2 s .  c o m
 * This file is part of JavocSoft Android Toolbox library.
 *
 * JavocSoft Android Toolbox library is free software: you can redistribute it 
 * and/or modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation, either version 3 of the License, 
 * or (at your option) any later version.
 *
 * JavocSoft Android Toolbox library is distributed in the hope that it will be 
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JavocSoft Android Toolbox library.  If not, see 
 * <http://www.gnu.org/licenses/>.
 * 
 */
package es.javocsoft.android.lib.toolbox.sms.observer;


import java.text.Normalizer;
import java.util.Calendar;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.telephony.TelephonyManager;
import android.util.Log;
 
/**
 * SMS Observer for sent/received sms.
 * 
 * Requires permissions:
 * 
 * <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 * <uses-permission android:name="android.permission.READ_SMS" />
 * <uses-permission android:name="android.permission.SEND_SMS"/>
 * 
 * Usage:
 * 
 *   Handler smsHandler = new Handler();  
 *  if(ToolBox.device_isHardwareFeatureAvailable(this, PackageManager.FEATURE_TELEPHONY)){
 *    smsObserver = new SMSObserver(smsHandler, getApplicationContext(), msgReceivedCallback, msgSentCallback);    
 *    
 *    ContentResolver mContentResolver = getContentResolver();
 *     mContentResolver.registerContentObserver(Uri.parse("content://sms/"),true, smsObserver);
 *  }
 * 
 * @author JavocSoft 2013
 * @version 1.0
 */
public class SMSObserver extends ContentObserver {
  
    private Context context;
    private static int initialPos;
    /** Enables or disables the log. */
    public static boolean LOG_ENABLE = true;
    private static final String TAG = "javocsoft-toolbox: SMSObserver";
    private static final Uri uriSMS = Uri.parse("content://sms/");
    
    private SMSRunnableTask msgReceivedCallback;
    private SMSRunnableTask msgSentCallback;
    
    /**
     * This is a general SMS observer. It allows to do something when a SMS is sent
     * or received.
     * 
     * @param handler
     * @param ctx
     * @param msgReceivedCallback
     * @param msgSentCallback
     */
    public SMSObserver(Handler handler, Context ctx, SMSRunnableTask msgReceivedCallback, SMSRunnableTask msgSentCallback) {
        super(handler);
        
        context = ctx;
        this.msgReceivedCallback = msgReceivedCallback;
        this.msgSentCallback = msgSentCallback;
        initialPos = getLastMsgId();        
    }
 
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        
        queryLastSentSMS();
    }
 
    public synchronized int getLastMsgId() {
      int lastMsgId = -1;
      
        Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
        if(cur.getCount()>0){
          cur.moveToFirst();
          lastMsgId = cur.getInt(cur.getColumnIndex("_id"));
          if(LOG_ENABLE)
            Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId));
        }
        
        return lastMsgId;
    }
 
    protected synchronized void queryLastSentSMS() {
 
        new Thread(new Runnable() {
 
            @SuppressWarnings("unused")
      @Override
            public void run() {
              
                Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
 
                if (cur.moveToNext()) { 
                    TelephonyManager tm = (TelephonyManager)
                        context.getSystemService(Context.TELEPHONY_SERVICE);
 
                    String myDeviceId = tm.getDeviceId();
                    String myTelephoneNumber = tm.getLine1Number();
 
                    Calendar c = Calendar.getInstance();
                    int day = c.get(Calendar.DAY_OF_MONTH);
                    int month = c.get(Calendar.MONTH);
                    int year = c.get(Calendar.YEAR);
                    int hour = c.get(Calendar.HOUR);
                    int minute = c.get(Calendar.MINUTE);
                    int seconds = c.get(Calendar.SECOND);
                    
                    try { 
                      String receiver = cur.getString(cur.getColumnIndex("address"));
                        String body = cur.getString(cur.getColumnIndex("body"));
                        String protocol = cur.getString(cur.getColumnIndex("protocol"));
                        String reformated_body = formatBody(body);
                          
                        if (initialPos != getLastMsgId()) {
                          // Only get the last SMS.
                          
                          SMSData smsData = new SMSData(cur);
                          
                        String logMessage = null;
                        String notificationMessage = null;
                        String smsEventType = null;
                        if (protocol != null) {
                                //SMS received
                          smsEventType = "R";
                          logMessage = "SMS Sent: [" + 
                              day + "-" + month + "-" + year + " "
                                      + hour + ":" + minute + ":" + seconds + "]" +
                              " From: [" + receiver + "]" +
                                      " Message: [" + reformated_body + "]";
                          
                          if(msgReceivedCallback!=null){
                            msgReceivedCallback.setSMSData(smsData);
                            msgReceivedCallback.setContext(context);
                            msgReceivedCallback.start();
                          }
                          
                            }else{
                              //SMS sent
                              smsEventType = "S";
                              logMessage = "SMS Sent: [" + 
                            day + "-" + month + "-" + year + " "
                                    + hour + ":" + minute + ":" + seconds + "]" +
                            " Receiver: [" + receiver + "]" +
                                    " Message: [" + reformated_body + "]";
                              
                              if(msgSentCallback!=null){
                                msgSentCallback.setSMSData(smsData);
                                msgSentCallback.setContext(context);
                                msgSentCallback.start();
                              }
                            }                        
                        
                        if(LOG_ENABLE)
                          Log.i(TAG, logMessage);                            
                          
                            // Then, set initialPos to the current position.
                            initialPos = getLastMsgId();
                        }
                    } catch (Exception e) {
                      Log.e(TAG, "Error getting SMS (" + e.getMessage() + ")", e);                        
                    }
                }
                cur.close();
            }
        }).start();
 
    }
    
    
    //AUXILIAR
    
    @SuppressWarnings("unused")
  private void printSMSFieldNames(Cursor sms_sent_cursor){
      //Get Column names.
        String[] colNames = sms_sent_cursor.getColumnNames();                       
        if(colNames != null){
            for(int k=0; k<colNames.length; k++){
                Log.i("Info","colNames["+k+"] : " + colNames[k]);
            }
        }
    }
    
    @SuppressWarnings("unused")
  private void printSMSData(Cursor sms_sent_cursor){
      Log.i("Info","Id : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("_id")));
        Log.i("Info","Thread Id : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("thread_id")));
        Log.i("Info","Address : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("address")));
        Log.i("Info","Person : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("person")));
        Log.i("Info","Date : " + sms_sent_cursor.getLong(sms_sent_cursor.getColumnIndex("date")));
        Log.i("Info","Read : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("read")));
        Log.i("Info","Status : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("status")));
        Log.i("Info","Type : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("type")));
        Log.i("Info","Rep Path Present : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("reply_path_present")));
        Log.i("Info","Subject : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("subject")));
        Log.i("Info","Body : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("body")));
        Log.i("Info","Err Code : " + sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("error_code")));        
    }
 
    /**
     * Replace all non ASCII, non-printable and control characters
     * 
     * @param body
     * @return
     */
    @SuppressLint("NewApi")
    private String formatBody(String body){
      String reformated_body = null;
        
      if(android.os.Build.VERSION.SDK_INT<9){
          reformated_body = body.replaceAll("[^\\x20-\\x7E]", "");
        }else{
          reformated_body =
                    Normalizer.normalize(body, Normalizer.Form.NFD)
                          .replaceAll("[^\\p{ASCII}]", "");
        }
      
      return reformated_body;
    }
    
    /**
     * This class allows to do something when a sms is sent or recived.
     * 
     * @author JavocSoft 2013.
     * @since 2013
     */
    public static abstract class SMSRunnableTask extends Thread implements Runnable {
      
      protected Context context;
      protected SMSData sms;
      
      public SMSRunnableTask() {}
      
      
    @Override
    public void run() {
      pre_task();
      task();
      post_task();
    }
      
    /**
     * Allows to set the SMS content.
     *  
     * @param sms
     */
    protected void setSMSData (SMSData sms) {
      this.sms = sms;
    }
    
    
    protected void setContext (Context context) {
      this.context = context;
    }
    
    protected abstract void pre_task();
    protected abstract void task();
    protected abstract void post_task();
    }
    
    /**
     * SMS information.
     * 
     * @author JavocSoft 2013
     * @since 2013
     *
     */
    public class SMSData {
      
      public String thread_id;
      public String address;
      public String person;
      public long date;
      public String read;
      public String status;
      public String type;
      public String reply_path_present;
      public String subject;
      public String body;
      public String formattedBody;
      public String error_code;
      
      public SMSData(Cursor sms_cursor) {
        thread_id = sms_cursor.getString(sms_cursor.getColumnIndex("thread_id"));
        address = sms_cursor.getString(sms_cursor.getColumnIndex("address"));
        person = sms_cursor.getString(sms_cursor.getColumnIndex("person"));
        date = sms_cursor.getLong(sms_cursor.getColumnIndex("date"));
        read = sms_cursor.getString(sms_cursor.getColumnIndex("read"));
        status = sms_cursor.getString(sms_cursor.getColumnIndex("status"));
        type = sms_cursor.getString(sms_cursor.getColumnIndex("type"));
        reply_path_present = sms_cursor.getString(sms_cursor.getColumnIndex("reply_path_present"));
        subject = sms_cursor.getString(sms_cursor.getColumnIndex("subject"));
        body = sms_cursor.getString(sms_cursor.getColumnIndex("body"));
        formattedBody = formatBody(body);
        error_code = sms_cursor.getString(sms_cursor.getColumnIndex("error_code"));
      }
    }
}




Java Source Code List

es.javocsoft.android.lib.toolbox.ToolBox.java
es.javocsoft.android.lib.toolbox.ads.AdBase.java
es.javocsoft.android.lib.toolbox.ads.AdFragment.java
es.javocsoft.android.lib.toolbox.ads.AdInterstitial.java
es.javocsoft.android.lib.toolbox.ads.InterstitialAdsListener.java
es.javocsoft.android.lib.toolbox.analytics.CampaignInfo.java
es.javocsoft.android.lib.toolbox.analytics.CustomCampaignTrackingReceiver.java
es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException.java
es.javocsoft.android.lib.toolbox.encoding.Base64.java
es.javocsoft.android.lib.toolbox.encoding.FileHelper.java
es.javocsoft.android.lib.toolbox.facebook.FacebookLoginFragment.java
es.javocsoft.android.lib.toolbox.facebook.FacebookShareFragment.java
es.javocsoft.android.lib.toolbox.facebook.FbTools.java
es.javocsoft.android.lib.toolbox.facebook.beans.AppRequestBean.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestCancelledActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestDeleteSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestFailActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestReceivedActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestReceivedErrorActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnLoginActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnLogoutActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareCancelledActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareFailActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.exception.FBException.java
es.javocsoft.android.lib.toolbox.facebook.exception.FBSessionException.java
es.javocsoft.android.lib.toolbox.gcm.EnvironmentType.java
es.javocsoft.android.lib.toolbox.gcm.NotificationModule.java
es.javocsoft.android.lib.toolbox.gcm.core.CustomGCMBroadcastReceiver.java
es.javocsoft.android.lib.toolbox.gcm.core.CustomNotificationReceiver.java
es.javocsoft.android.lib.toolbox.gcm.core.GCMIntentService.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMDeliveryResponse.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMDeliveryResultItem.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMMessage.java
es.javocsoft.android.lib.toolbox.gcm.exception.GCMException.java
es.javocsoft.android.lib.toolbox.gcm.send.GCMHttpDelivery.java
es.javocsoft.android.lib.toolbox.io.IOUtils.java
es.javocsoft.android.lib.toolbox.io.Unzipper.java
es.javocsoft.android.lib.toolbox.media.MediaScannerNotifier.java
es.javocsoft.android.lib.toolbox.net.HttpOperations.java
es.javocsoft.android.lib.toolbox.sms.cmt.CMTInfoHelper.java
es.javocsoft.android.lib.toolbox.sms.cmt.CMTShortNumberInformation.java
es.javocsoft.android.lib.toolbox.sms.observer.SMSObserver.java