Android系统如何屏蔽应用发送的短信记录

应用偷偷在后台发送短信,并让用户无法感知,这种做法虽然"鸡贼”,但是从技术角度上来说,值得我们探究一番。项目有需求的可以借鉴如下方法,业余者可以围观此种“鸡贼”方式是如何耗掉您一毛钱的短信费用,却让你毫无知觉的。下面开始介绍MTK平台、展讯平台上如何过滤。

MTK平台上如何过滤掉应用发送的短信记录?
是否插入数据库是由MMS应用来负责的。MTK平台上位于framework下的SmsApplication.java类,我们可以通过以下方式屏蔽:

 /**  
     * Returns whether need to write the SMS message to SMS database for this package.
     * <p>
     * Caller must pass in the correct user context if calling from a singleton service.
     */
    public static boolean shouldWriteMessageForPackage(String packageName, Context context) {
    //Start:判断包名,返回false屏蔽短信.例如com.ape....就是我的包名
        if ((packageName != null) && (packageName.equals("com.ape.saletracker") || packageName.equals("com.ape.saletrackerPK") || packageName.equals("com.ape.saletrackerBD"))) {
            Log.d(LOG_TAG, "don't save msg for sts");
            return false;
        }
    //End:判断包名,返回false屏蔽短信
        if (SmsManager.getDefault().getAutoPersisting()) {
            return true;
        }
        return !isDefaultSmsApplication(context, packageName);
    }

注:其实通过上述方法的注释“ Returns whether need to write the SMS message to SMS database for this package.” 我们也可以知道,此方法是判断是否将该应用发送短信的记录写入数据库中。

展讯平台上如何过滤掉应用发送的短信记录?

展讯平台Android P上类似的需要在上述SmsApplication.java中添加过滤的包名之外,还存在一点点小小的bug,需要通过如下方式修复一下,才能正常的过滤包名。在展讯P项目上,按照上述方式添加之后,通过log我发现能过滤短信是概率性的,说明包名的获取还存在缺陷。bug修复位于SMSDispatcher.java中:
1)修改点1:
 /**
     * Send an SMS
     * @param tracker will contain:
     * -smsc the SMSC to send the message through, or NULL for the
     *  default SMSC
     * -pdu the raw PDU to send
     * -sentIntent if not NULL this <code>Intent</code> is
     *  broadcast when the message is successfully sent, or failed.
     *  The result code will be <code>Activity.RESULT_OK<code> for success,
     *  or one of these errors:
     *  <code>RESULT_ERROR_GENERIC_FAILURE</code>
     *  <code>RESULT_ERROR_RADIO_OFF</code>
     *  <code>RESULT_ERROR_NULL_PDU</code>
     *  <code>RESULT_ERROR_NO_SERVICE</code>.
     *  The per-application based SMS control checks sentIntent. If sentIntent
     *  is NULL the caller will be checked against all unknown applications,
     *  which cause smaller number of SMS to be sent in checking period.
     * -deliveryIntent if not NULL this <code>Intent</code> is
     *  broadcast when the message is delivered to the recipient.  The
     *  raw pdu of the status report is in the extended data ("pdu").
     * -param destAddr the destination phone number (for short code confirmation)
     */
    @VisibleForTesting
    public void sendRawPdu(SmsTracker tracker) {
        HashMap map = tracker.getData();
        byte pdu[] = (byte[]) map.get(MAP_KEY_PDU);

        if (mSmsSendDisabled) {
            Rlog.e(TAG, "Device does not support sending sms.");
            tracker.onFailed(mContext, RESULT_ERROR_NO_SERVICE, 0/*errorCode*/);
            return;
        }
      if(checktheOperatorIsThailand()){
      if((judgeTrueSIM2(mPhone,mContext)==NOT_IN_THAILAND)||(judgeTrueSIM2(mPhone,mContext)==NOT_TRUE_SIM_IN_THAILAND)){
            Log.w(TAG,"the number does not support sending sms");
            tracker.onFailed(mContext, RESULT_ERROR_GENERIC_FAILURE, 0/*errorCode*/);
           return;
        }
       }
        if (pdu == null) {
            Rlog.e(TAG, "Empty PDU");
            tracker.onFailed(mContext, RESULT_ERROR_NULL_PDU, 0/*errorCode*/);
            return;
        }

        // Get calling app package name via UID from Binder call
        PackageManager pm = mContext.getPackageManager();
        String[] packageNames = pm.getPackagesForUid(Binder.getCallingUid());

        if (packageNames == null || packageNames.length == 0) {
            // Refuse to send SMS if we can't get the calling package name.
            Rlog.e(TAG, "Can't get calling app package name: refusing to send SMS");
            tracker.onFailed(mContext, RESULT_ERROR_GENERIC_FAILURE, 0/*errorCode*/);
            return;
        }
        
	    // Start:过滤短信添加代码1
	String packageName = getPackageNameByProcessId(packageNames);
        if (packageName != null) {
            packageNames[0] = packageName;
        }
        Rlog.d(TAG, "sendRawPdu show the package name by process id: " + packageNames[0]);
        // End:过滤短信添加代码1
         
        // Get package info via packagemanager
        PackageInfo appInfo;
        try {
            // XXX this is lossy- apps can share a UID
            appInfo = pm.getPackageInfoAsUser(
                    packageNames[0], PackageManager.GET_SIGNATURES, tracker.mUserId);
        } catch (PackageManager.NameNotFoundException e) {
            Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS");
            tracker.onFailed(mContext, RESULT_ERROR_GENERIC_FAILURE, 0/*errorCode*/);
            return;
        }
        // checkDestination() returns true if the destination is not a premium short code or the
        // sending app is approved to send to short codes. Otherwise, a message is sent to our
        // handler with the SmsTracker to request user confirmation before sending.
        if (checkDestination(tracker)) {
            // check for excessive outgoing SMS usage by this app
            if (!mSmsDispatchersController.getUsageMonitor().check(
                    appInfo.packageName, SINGLE_PART_SMS)) {
                sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, tracker));
                return;
            }

            sendSms(tracker);
        }
        if (PhoneNumberUtils.isLocalEmergencyNumber(mContext, tracker.mDestAddress)) {
            new AsyncEmergencyContactNotifier(mContext).execute();
        }
    }

2)修改点2,重新定义方法getPackageNameByProcessId(),这个方法返回的包名,即是在SmsApplication.java中传入的包名,保持一致,既不会出现概率性可以过滤短信的bug.
private String getPackageNameByProcessId(String[] packageNames) {
        String packageName = null;

        if (packageNames.length == 1) {
            packageName = packageNames[0];
        } else if (packageNames.length > 1) {
            int callingPid = Binder.getCallingPid();
            Iterator index = null;

            ActivityManager am = (ActivityManager) mContext.getSystemService(
                    Context.ACTIVITY_SERVICE);
            List processList = am.getRunningAppProcesses();
            if (processList != null)
            {
                index = processList.iterator();
                while (index.hasNext()) {
                    ActivityManager.RunningAppProcessInfo processInfo =
                            (ActivityManager.RunningAppProcessInfo) (index.next());
                    if (callingPid == processInfo.pid) {
                        if(processInfo.processName != null && processInfo.processName.equals("system")){
                            packageName = packageNames[0];
                        }else{
                            packageName = processInfo.processName;
                        }
                        break;
                    }
                }
            }
        }
        return packageName;
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值