Android系统 短彩信基本流程

android入门-MMS-短彩信发送/接收流程【图】 短信发送流程: ConversationList --> (createNewMessage/OpenThread) -->  ComposeMessageActivity(confirmSendmessageIfNeeded) --> (send )--> WorkingMessage (preSendSmsWorker) --> (sendSmsWorker) --> SmsMessa 阅读详情

Android2.1消息应用(Messaging)源码学习笔记(转载)

我想首先应该从AndroidManifest.xml 文件开始,该文件是Android应用(APK)的打包清单,其中提供了关于这个应用程序的基本信息,如名称(application/@label),图标( application/@icon ),等常量信息,但该文件最重要的功能仍然是:向Android系统声明应用程序所包含的组件,包括Activity、Service、Receiver和ContentProvider,另外还会请求 系统 授予相关权限。

 

<application>是重要的标记,通常我们都是在此设置应用程序的名称和图标,而在Messaging这个应用中,它扩展了默认的android.app.Application类,在com.android.mms.MmsApp类中覆写了onCreate()方法进行系统初始化、覆写onTerminate() 方法做相关清理工作。最重要的是<application>标记设置了(任务吸引力) taskAffinity=“android.task.mms”、allowTaskReparenting ="true" 这是两个与 Task有关的属性,那么何为任务(Task)呢?

 

A pplication就是一个.apk文件,由若干个组件(可能会包括 Activity、Service、Receiver 或者ContentProvider )构成,它是一个物理上的独立存在。而Task则是指用户借助Application提供的功能完成某件事情,例如:发送一条信息给老朋友。通常一个Task操作所涉及的内容不会超过 A pplication边界 ,但在Android中却不是这样,Android允许一个Task操作 横跨多个Apllication。还以向老朋友发送信息为例,在该任务中,至少需要一个用来输入目标电话号码和消息内容的用户界面——即Android中的Activity组件(这是 Messaging应用中的内容 ),如果进一步要求目标号码是从联系人列表(或通话列表)中选择,而非手工输入,那么就涉及到跨 Apllication调用‘联系人应用’中的列表组件 了 (也是一个 Activity ) 。因此以上两个属性前者设置了 Activity的吸引力(Affinity)值,后者使得 Activity可以在不同的Task中自有切换。

 

 

Messaging中的Receiver

R eceiver广播 接收器用于响应系统中的各种广播事件并执行相关业务代码的组件,常用于完成如:启动service、显示Activity等 任务 。在Messagin应用中一共有7个 R eceiver:

1、.transaction.SmsReceiver : 短消息 广播 接收器,它负责处理与收到短消息相关的广播事件。触发该接收器运行的intent有两个:

A.android.intent.action.BOOT_COMPLETED--->Android系统启动完成时会发出该广播,即SmsReceiver会在系统启动完成时接收到调用;

B.com.android.mms.transaction.MESSAGE_SENT --->定义在 SmsReceiverService.java中的常量,被用在SmsMessageSender.sendMessage方法中——即短消息发送后 触发的广播事件;

完全和预想的一样,在 SmsReceiver中会启动 SmsReceiverService,启动代码在beginStartingService方法里。值得注意的是它同时还做了“屏幕唤醒锁定 (WakeLock)” 操作,最终在service启动完成后,通过回调用finishStartingService方法,解除了屏幕唤醒锁定。

SmsReceiver.java中有编译错误,因为无法访问android.provider.Telephony.Sms.Intents。其实 Intents 所在位置是:myeclair/frameworks/base/core/java/android/provider/Telephony.java,它被标记为@hide。

 

2、 . transaction.PrivilegedSmsReceiver :该接收器是SmsReceiver的子类,唯一的区别在于该Receiver被申明有permission为android.permission.BROADCAST_SMS。

 

 

3、.transaction.MmsSystemEventReceiver :Mms系统事件接收器,它负责 在收到新消息时 向通知区域(即标题栏)显示小图标,和 重新发送在发件箱中的MM。触发该接收器运行的两个Intent是:

A. android.intent.action.BOOT_COMPLETED ---> :与SmsReceiver中的情况相同;

B.android.intent.action.CONTENT_CHANGED ---> :连接方式改变时系统会发出该广播,即在连接方式变化,例如从gprs-->wifi时该接收器将被调用 ;

在MmsSystemEventReceiver类中,程序一旦获得数据连接时就会启动TransactionService服务;当连接方式改变时还会调用PduCache.purge()方法清理缓存;还有当系统刚刚启动时 会同步通知区域的图标、未读消息个数等信息。

MmsSystemEventReceiver.java中有编译错误,因为它无法访问以下类:

1、com.google.android.mms.util.PduCache:位置-myeclair/frameworks/base/core/java/com/google/android/mms/util/PduCache.java,该类未包含在默认的android.jar文件中,需要重新编译;

2、android.provider.Telephony.Mms: 位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

3、com.android.internal.telephony.TelephonyIntents:位置-myeclair/frameworks/base/telephony/java/com/android/internal/telephony/TelephonyIntents.java,该类是一个常量类是未被开放的API。

4、com.android.internal.telephony.Phone: 位置- myeclair/frameworks/base/telephony/java/com/android/internal/telephony/Phone.java, 该类被标记为 @hide 。

 

4、.transaction.PushReceiver : WAP_PUSH 事件的广播接收器,该事件发生时 代表手机收到了一条新的WAP PUSH message。该接收器被调用后,首先唤醒手机屏幕5秒钟,然后在一个后台线程中处理push-data,将消息数据插入到数据库中,必要时启动TransactionService服务以更新通知信息 。触发该接收器运行的 Intent是:

(intent.action=android.provider.Telephony.WAP_PUSH_RECEIVED, data=application/vnd.wap.mms-message),其中Action.Name定义在android.provider.Telephony类中。值得注意的是该Receiver有申明权限:android.permission.BROADCAST_WAP_PUSH,这意味着发出该广播时必须携带该授权,否则本 Receiver将不会被触发执行。

PushReceiver.java中有编译错误,因为它无法访问以下类:

1、android.provider.Telephony : 位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

2、com.google.android.mms.*: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/*,这些类未包括在公开的API中。

 

5、. transaction.MessageStatusReceiver :消息状态改变时的广播接收器,消息状态改变是指消息的投递状态(即:是否成功送达、是否被目标用户阅读等)的变化,触发该接收器的Intent是:com.android.mms.transaction.MessageStatusReceiver. MESSAGE_STATUS_RECEIVED,该值是申明在MessageStatusReceiver.java文件中的常量。该广播事件是在SmsMessageSender.sendMessage()方法中被发出的,收到广播事件后,Receiver的会做两件事情:a-取得pdu数据包 更新消息状态(在updateMessageStatus方法中);b-更新通知区域的新消息指示信息 (在MessagingNotification.updateNewMessageIndicator()方法中)。

MessageStatusReceiver.java中有编译错误,因为它无法访问以下类:

1、android.provider.Telephony : 位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

2、com.google.android.mms.util.SqliteWrapper: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/ util/SqliteWrapper.java,该类未包括在公开的API中。

 

6、.transaction.SimFullReceiver :Sim卡短信存储空间满的事件通知,当系统发现Sim卡中存储短信的空间耗尽时会发出该广播事件。该接收器完成的工作是在通知区域显示相关信息,点击通知信息后,可以进入管理Sim卡中短消息的Activity界面 。

SimFullReceiver.java中有编译错误,因为它无法访问 android.provider.Telephony 类,所在位置-myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。


7、.transaction.SmsRejectedReceiver :短消息被拒绝时的事件接收器,当手机的存储空间不足时会拒绝接收新的短消息,当该事件发生时SmsRejectedReceiver被调用,它会检查确认是否是存储空间不足,然后在通知区域显示相关通知信息。

SmsRejectedReceiver.java中有编译错误,因为它无法访问 android.provider.Telephony 类,所在位置-myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。


 

Messaging中的Activity

Activity是用来构建UI(用户界面 )的组件,用户操作界面代表了应用程序提供的基本功能,是应用程序和用户之间的交互接口。在Messaging应用中有以下的Activity:

1、.ui.ConversationList ,对话列表界面,这是进入应用程序的主界面。它有两个配置属性值得我们特别注意,a.android:configChanges="orientation|keyboardHidden":在Android系统中,当程序所运行的环境(如:屏幕方向、键盘状态、字体等级,等等 )发生变化后 会导致Activity被重新启动(以适应环境变化 ),然而 Activity也可以宣称自己来应付某些变化(而不是一股脑地全让系统重启自己), configChanges 属性 正是用于 指定自己愿意 应付 的变化情况。此处该属性有两个值, orientation代表屏幕方向发生改变,keyboardHidden表示键盘可访问状态发生变化(即键盘弹出/收起 ),这意味着当屏幕方向和键盘可用状态 发生变化时, Activity不会被重新启动,而是调用其onConfigurationChanged方法,通常是在该方法中对自己做出调整,以适应变化;b.launchMode="singleTop":该属性指示了Activity的加载模式,这与Activity在不同Task之间的重用有关,该属性共有4个可用选项standard, singleTop,singleTask,singleInstance,它们将与Intent中的FLAG_ACTIVITY_* 标记 常量 协同产生相关作用。

ConversationList类中定义了程序中涉及到的选项菜单、会话(Conversation)项上的上下文菜单等UI元素。另外该类中的runOneTimeStorageLimitCheckForLegacyMessages方法用于检测存储空间限制。

SmsRejectedReceiver .java中有编译错误,因为它无法访问以下类:

1.android.provider.Telephony 类,所在位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

2. com.google.android.mms.*: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/*,这些类未包括在公开的API中。


2、.ui.ComposeMessageActivity ,创建新消息的用户界面,通过选项菜单menu_compose_new会调用到该界面。这是个很庞大的类,内部实现也很复杂,等仔细看了再写补充吧。

ComposeMessageActivity .java中有编译错误,因为它无法访问以下类:

1.com.android.internal.widget.ContactHeaderWidget类,所在位置-myeclair/frameworks/base/core/java/com/android/internal/widget/ContactHeaderWidget.java,该类被标记为 @hide 。

2.com.android.internal.telephony.* 类,所在位置- myeclair/frameworks/ base/telephony/java/com/android/internal/telephony/*,这些类未包括在公开的API中 。

3. com.google.android.mms.*: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/*,这些类未包括在公开的API中 。

 

3、 .ui.ForwardMessageActivity ,用于转发消息的Activity,这是ComposeMessageActivity的别名,用于把一条现有消息的内容带到创建消息的界面上;

 

4、.ui.DeliveryReportActivity ,投递报告 Activity, 用于报告消息的投递状态,它采用对话框风格的主题(android:theme="@android:style/Theme.Dialog")。

DeliveryReportActivity .java中有编译错误,因为它无法访问以下类:

1. com.google.android.mms.*: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/*,这些类未包括在公开的API中 。

2. android.provider.Telephony 类,所在位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

 

5、.ui.WarnOfStorageLimitsActivity ,存储空间限制警告,用于告知用户 关于存储空间限制的设置信息。

WarnOfStorageLimitsActivity .java中有编译错误,因为它无法访问以下类:

1. com.android.internal.app.AlertActivity类, 位置- myeclair/frameworks/base/core/java/com/android/internal/app/AlertActivity.java,该类未包括在公开的API中 。

2. com.android.internal.app.AlertController类, 位置- myeclair/frameworks/base/core/java/com/android/internal/app/AlertController.java,该类未包括在公开的API中 。

 

6.ui.ConfirmRateLimitActivity ,发送多条彩信时向用户提示确认的界面,它包括了自动 应答操作——即用户 超过一段时间 未作出响应时自动取消发送。

 

7、.ui.ClassZeroActivity ,ClassZero是一种特殊的短消息类型,它会直接显示在用户屏幕上并等待用户操作。ClassZeroActivity正是用来显示此类型的短信消息 ,并运行用户将信息保存起来 。

ClassZeroActivity .java中有编译错误,因为它无法访问以下类:

1. android.provider.Telephony 类,所在位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

2. com.google.android.mms.util.SqliteWrapper: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/ util/SqliteWrapper.java ,该类未包括在公开的API中。

 

8、.ui.MessagingPreferenceActivity ,这是Messaging应用的系统配置界面,其中有针对SMS、MMS、存储限制等配置属性,以及管理存储在 SIM卡中 的短信消息。该Activity启动时会检查当前是否有SIM,以及是否支持MMS来动态调整配置项列表。

MessagingPreferenceActivity .java中有编译错误,因为它无法访问TelephonyManager.getDefault()方法,可以考虑使用Context.getSystemService(Context.TELEPHONY_SERVICE)方法来得到类实例。

 

9、.ui.ManageSimMessages ,用于管理Sim卡中短消息的界面,它以列表的形式显示了存储在SIM卡中的短消息,并允许用户将信息转存到手机内存中,或者删除消息。

ManageSimMessages .java中有编译错误,因为它无法访问以下类:

1. android.provider.Telephony 类,所在位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

2. com.google.android.mms.util.SqliteWrapper: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/ util/SqliteWrapper.java ,该类未包括在公开的API中。

 

10、.ui.SearchActivity ,用于信息搜索的操作界面。Android通过系统服务Context. SEARCH_SERVICE(即SearchManager类)提供了强大的信息搜索功能。在该应用中通过对联系人(或者电话号码)、主题等信息的匹配来搜索信息,并将结果显示在一个列表中。

SearchActivity .java中有编译错误,因为它无法访问以下类:

1. android.provider.Telephony 类,所在位置- myeclair/frameworks/base/core/java/android/provider/Telephony.java,该类被标记为 @hide 。

 

11、.ui.SlideshowEditActivity , 所谓Slide是指MM中的一页内容 即一帧,通常被称为幻灯片。 SlideshowEditActivity是彩信中所有内容(即多个Slide)的列表,用户可以选定列表项进入Slide播放/修改界面。

SlideshowEditActivity .java中有编译错误,因为它无法访问以下类:

1. com.google.android.mms.*: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/*,这些类未包括在公开的API中 。

 

 

12、.ui.SlideshowActivity , 用于播放Slide幻灯片的界面,它会在全屏状态下显示幻灯片的内容。

SlideshowActivity .java中有编译错误,因为它无法访问以下类:

1. com.google.android.mms.*: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/*,这些类未包括在公开的API中 。

 

13、.ui.SlideEditorActivity ,用于编辑Slide幻灯片内容的操作界面,它提供了:添加、移除 文本/图片/音乐,以及Slide等功能。

SlideEditorActivity .java中有编译错误,因为它无法访问以下类:

1. com.google.android.mms.*: 位置- myeclair/frameworks/base/core/java/com/google/android/mms/*,这些类未包括在公开的API中 。

 

14、.ui.EditSlideDurationActivity ,用于修改Slide幻灯片持续显示时间 的操作界面 ,默认持续显示时间是5秒。

EditSlideDurationActivity .java编译无错误。

 

Messaging中的Service

应用中共有两个service:.transaction.TransactionService 和 .transaction.SmsReceiverService,前者负责处理与彩信(MMS)相关的网络业务,后者是短消息(SMS)的接收器,两者都会响应来自通讯网络的通知并收取信息。它们只用于本应用内部(因为其未声明任何intent-filter),上文介绍的广播接收器中有显式启动它们的代码。以下我们将分别分析两个Service的基本实现。

 

1、.transaction.SmsReceiverService ,它被创建时首先 初始化了新的工作线程(HandlerThread对象)用来在后台完成相关动作,紧接着在onStartCommand方法里会将具体的任务通过消息(即调用service的Intent)发送给工作线程进行处理。根据Intent.Action的名称,工作线程会处理4中情况:

A.系统启动完成后BOOT_COMPLETED:把发件箱(outbox)中的消息移动到发送队列(QueuedBox),然后开始发送队列中的消息,最后调用updateNewMessageIndicator方法更新状态栏消息指示图标;

B.处理Sms接收handleSmsReceived:从Intent中取得消息对象,直接显示给用户(Class0类型)或者保持到数据库中。

C.处理Sms发送handleSmsSent:从待发送消息队列中取得消息,并按次序逐个发送;

D.处理通讯网络状态改变handleServiceStateChanged:用户从无信号状态进入有信息号状态后,继续执行发送任务的情况;

 

2、.transaction.TransactionService , 是处理与彩信相关业务的服务组件,根据代码中的注释可以了解到: 收发彩信时可以是移动数据网络(mobile data network)或Wi-Fi网络。当没有可用的移动数据网络连接时,会尝试通过Wi-Fi网络发送/接收MMS信息(如果有 Wi-Fi 网络的话)。

它 同样在onCreate方法里首先创建了后台工作线程,通过NetworkConnectivityListener类( 一个被@hide的类 )监听通讯网络链接状态的变化,并根据不同的链接状态作出相应的反应。

紧接着就是onStartCommand方法了,它首先会检测当前的网络连接状态,然后分别完成以下几件事情:

A.针对收发彩信的业务,它将intent.getExtras()包装成一个DTO—— TransactionBundle,再通过launchTransaction()方法将具体工作交给后台工作线程去处理。

B.如果 intent.getExtras()为Null时,它会尝试从数据库中扫描是否有(上次系统结束时)未完成的操作,如果有则遍历所有操作项,逐个调用launchTransaction()方法,以完成操作;

 

 

重点还是在后台工作线程的处理逻辑上,在代码中表现为handleMessage方法,它共处理以下几种不同类型的业务消息:

 

Ⅰ.EVENT_CONTINUE_MMS_CONNECTIVITY ,与彩信系统建立网络连接,它首 先会检查当前是否有待处理的业务,然后通过调用beginMmsConnectivity方法来创建于彩信系统的网络连接,如果网络连接被正确建立,那么它会通过一个30秒间隔的计时器来维持连接的持续存在;

 

Ⅱ.EVENT_DATA_STATE_CHANGED ,网络连接状态发生改变分支,这一分支是通过对NetworkConnectivityListener对象的监听而获得回调。在该分支中首先确认了网络连接的有效性,(代码在此处仅允许ConnectivityManager.TYPE_MOBILE_MMS类型那么wi-fi连接属于该类型? ),然后创建 TransactionSettings对象,并调用processPendingTransaction方法处理具体的彩信业务;

 

Ⅲ.EVENT_TRANSACTION_REQUEST ,这是对具体彩信业务的处理分支,它首 先创建了承载业务参数的TransactionSettings对象,该对象包含有彩信中心服务地址(mmscUrl)、代理服务器地址和端口等用于建立 网络连接的参数,然后根据不同的业务类型,分别进行处理。当前仅明确处理了以下4中业务:

1、NOTIFICATION_TRANSACTION,通过一条Push数据,通知手机端收到有新信息;

2、RETRIEVE_TRANSACTION,收取彩信;

3、SEND_TRANSACTION,发送彩信;

4、READREC_TRANSACTION,彩信阅读报告;

用于处理具体业务的关键代码在processTransaction方法中,它首先检查业务是否已存在于处理队列中(mProcessing & mPending),然后调用beginMmsConnectivity()方法确认网络连接有效性,并点亮终端屏幕,然后将业务对象条件到处理队列中并向业务附加观察者,最后调用业务自身process()方法完成网络通信。注意:业务的process方法被调用又会触发观察者(即当前service) 的update方法被调用,这使得刚才被处理掉的业务从队列中被移除,并且开始处理下一条业务;


Ⅴ.EVENT_HANDLE_NEXT_PENDING_TRANSACTION ,这是一个多条彩信业务能够 被 连续 处理的关键分支,首先在当前service中有mProcessing数组列表用于缓存连续的彩信业务,每条彩信业务是一个可被观察的对象(注:观察者模式 ), 当前service是唯一观察者,其会感知到一条业务已处理结束,并触发下一条业务处理的开始;

 

所有彩信业务处理完成后, 会调用 service中的endMmsConnectivity()方法,结束与彩信中心的网络连接,并撤销屏幕点亮。

【问题分析】界面点击无响应,非ANR【Android 14】 用户操作出的点击Message界面无任何响应的问题,但是也不发生ANR。 阅读详情

相关推荐

Android7.0 Messaging源码分析(1) - 基础知识篇

关于 Messaging 有以下概念要了解:   SMS   短信息服务(英语:Short Message Service,缩写为SMS),中国大陆称短信,香港称短讯, 台湾、新加坡称简讯,是移动电话服务的一种。有时也称为信息、短信息、文字信息,此服务亦有许多英语的俗称如“SMSes、text messages、messages或甚至于texts和txts”。短信服务最早是在GSM系统手机上引入

wenping的专栏 4075

Android 9.0 GMS 桌面Launcher3 布局修改

先看下CDD文件的要求 集成了GMS给的partner_gms包后,发现Hotseat的排列并没直接像文档上要求的那样。 少了chrome,我就去launcher3中打开配置dw_phone_hotseat.xml,添加修改 <!--在第五个位置添加chrome--> <favorite container="-101" scree...

木叶风的博客 2851

MTK方案上基于Android N拦截黑名单中的短/彩信的方法

--- 作者 zuhui.zhang 安卓7.0原生系统增加了在framework层拦截黑名单来电和短信,但不会将数据保存到数据库,因此无法查看到被拦截的来电和短信。在安卓7.0之前,黑名单的短信默认是不会拦截的,为了实现黑名单短信拦截功能,需要对短信数据库表中的字段新增特殊的值,以便标记黑名单短信。以下具体说明下笔者对于MTK方案里的短信应用中拦截短彩信的实现方法。 一、拦截黑名

maetelibom的博客 2873

Android2.1消息应用(Messaging)源码学习笔记

Android2.1消息应用(Messaging)源码学习笔记   我想首先应该从AndroidManifest.xml 文件开始,该文件是Android应用(APK)的打包清单,其中提供了关于这个应用程序的基本信息,如名称(application/@label),图标( application/@icon ),等常量信息,但该文件最重要的功能仍然是:向And...

长安新都市业主家园 287

Android入门-MMS-短信/彩信发送流程+代码分析

WorkingMessage获取将要发送的短信: 首先刷新收信人,然后创建SmsMessageSender类并调用sendMessage()发送短信。 private void sendSmsWorker(String msgText, String semiSepRecipients, long threadId, int simId) { String[] dests =

MrDemigod的专栏 3848

解决Android项目中的重复依赖问题及实用经验

在开发Android应用程序时,我们通常使用各种依赖库来加快开发过程并提供额外的功能。然而,有时候我们可能会遇到重复依赖的问题,这可能导致编译错误、构建失败或应用程序崩溃。本文将介绍如何查找和解决Android项目中的重复依赖问题,并分享一些实用经验和技巧。

TechBlitzZ的博客 1167

短息接收--android短彩信的接收流程深入分析(framework)

短彩信的接收流程 涉及的文件 com.android.internal.telephony/Ril.java com.android.internal.telephony/SMSDispatcher com.android.internal.telephony/CommandsInterface com.android.internal.telephony/GsmSMSDispatcher c

ceko_wu的专栏 1万+

Android平台自定义彩信发送机制

在移动通信的世界里,彩信(MMS)发送是一种重要的富媒体信息交流方式。彩信不仅能发送文本信息,还可以发送图片、音频和视频等多种格式的媒体文件。对于Android应用开发者来说,了解彩信的发送机制对于构建丰富的应用体验至关重要。本章将简要介绍彩信发送的基础知识,帮助开发者掌握彩信传输的基本流程和重要性。后续章节将详细阐述如何在Android平台上实现彩信发送,包括获取SmsManager实例、构建彩信内容、设置彩信头部信息、发送彩信、处理发送结果以及后台彩信发送的技术实现等。

weixin_34618526的博客 995

彩信发送流程 --- 之一

6,彩信发送流程 发送彩信可以调用MmsManager.java的sendMultimediaMessage方法就可以发送彩信。 CTS 测试彩信部分代码如下, final SmsManager smsManager = SmsManager.getDefault(); ••• smsManager.sendMultimediaMessage(context, contentUri, n

Jack的博客 4346

NXP实战笔记(五):S32K3xx基于RTD-SDK在S32DS上配置ADC的硬件触发同步采样与软件采样过程

恩智浦 S32K3xx 系列汽车微控制器器件具有 15 位分辨率逐次逼近模数转换器(SAR ADC),可用于模拟输入信号的采集和数字化。-15 位的分辨率。转换数据总是15 位宽,与所选转换分辨率无关(每转换数据 14、12、10、8 个有效位,减少这个数字会加快数据转换,因为 SAR 算法的执行步骤会更少)。-每个输入通道捕获的转换数据放在单独寄存器中。-可使用“ 平均法” 提高精度,即通过计算最高 32 次转换数据的平均数来提供最终结果。-正常转换触发转换多个。

梦想技术家 3845

vcs 覆盖率收集1——三种覆盖率类型、covergroup、bins、数据采样、覆盖率选项

介绍各种覆盖率,以及如何编写覆盖率收集的代码

qq_42135020的博客 1万+

android 彩信 下载流程,android短彩信收发流程(应用层).pdf

Android 短彩信收发流程 下图为 ComposeMessageActivity 中 confirmSendMessageIfNeeded 部分的信息发送流程。主要以接收者有效性的确认为主,然后转向 sendMessage 方法进行发送。下图为 ComposeMessageActivity 中 confirmSendMessag...

weixin_31000273的博客 368

AI漫剧实战:MiniMaxH3本地部署+ComfyUI工作流,6G显存出长视频

随着AI视频生成技术的普及,创作者开始追求在有限硬件条件下的本地化部署。本地部署不仅降低使用成本,更能获得对生成流程的完全可控性,这为高频次的内容生产提供了基础。以开源工作流引擎ComfyUI为依托,通过量化模型与显存优化,即便是6G显存的中端显卡也能流畅运行MiniMaxH3视频生成模型,输出60秒级别的AI漫剧片段。本文从视频生成原理出发,讲解模型选择、节点搭建、参数调优与提示词结构化设计,并延伸到剧本拆分、角色一致性控制、后期合成及平台变现路径,为AI漫剧创作者提供一套低成本、可复制的工程化方案。无论

weixin_29051149的博客 161

android看彩信自动退出,Android短彩信收发流程(应用层)

下图为ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息发送流程。主要以接收者有效性的确认为主,然后转向sendMessage方法进行发送。 ComposeMessageActivity.sendMessage从下图可以看出,在这个方法中,主要做的事是确认手机状态的有效性。最终调用WorkingMessage的send方法进行信息的发送。 ...

weixin_36039452的博客 259

BitLocker恢复密钥丢失?从原理到实战的完整解锁与系统重生指南

磁盘加密技术是数据安全的核心防线,它通过对存储设备上的数据进行编码,确保未经授权的用户无法访问。其原理主要基于加密算法(如AES)与密钥管理机制,在操作系统启动前或数据读写时进行实时加解密。这项技术的核心价值在于防止设备丢失或被盗后的数据泄露,尤其对于笔记本电脑和移动设备至关重要。典型的应用场景包括企业办公电脑、存有敏感信息的个人设备以及符合合规性要求的行业。当使用Windows系统自带的BitLocker加密功能时,若因硬件改动、系统更新等触发保护机制,用户可能会面临需要输入恢复密钥才能启动的困境。本文聚

weixin_34006965的博客 491

Jlink除了调试还能干啥?用JFlash SPI给W25Q64烧录固件的5个实用技巧

本文深入探讨了Jlink的隐藏功能,特别是通过JFlash SPI高效烧录W25Q64的5个进阶技巧。从硬件连接优化到批量处理脚本,再到数据安全验证,这些技巧能显著提升烧录速度和稳定性,适用于量产环境。文章还提供了详细的参数配置和脚本示例,帮助工程师充分发挥Jlink的潜力。

weixin_29164843的博客 409

android短彩信附件机制,android短彩信附件机制

将一些认识写下来,和大家交流一下,同时也方便自己复习。用户可以通过附件按钮,添加附件。以添加幻灯片为例:如果点击幻灯片,会走如下代码:ComposeMessageActivity.javaprivate void editSlideshow() {// The user wants to edit the slideshow. That requires us to persist the sli...

weixin_39732027的博客 184

OC5021B 100V宽电压输入 LED车灯/大功率照明 DC降压型恒流驱动器

适用于LED大功率汽车大灯/大功率照明 OC5021B 100V宽电压输入 5A电流设计 DC-DC降压型恒流驱动IC

Handsome63841990的博客 2417

彩信发送流程 --- 之二

6.2 发送流程分析 MmsService的mStub变量的sendMessage方法调用流程图如下, sendMessage方法主要逻辑如下, 1,将要发送的内容等信息封装为SendRequest对象, final SendRequest request = new SendRequest(MmsService.this, subId, contentUri, loc

Jack的博客 1956

【2026年得物春招算法岗- 4月18日 -第二题- 老张爬山】(题目+思路+Java&C++&Python解析+在线测试)

这篇文章介绍了一个动态规划问题,解决老张在n天内安排爬山计划以最大化愉悦值的问题。题目允许最多k次打破"不能连续两天爬山"的规则限制。 摘要要点: 使用三维动态规划数组dp[i][j][s],表示第i天结束时已用j次机会、当天状态为s(0不爬/1爬)时的最大愉悦值 状态转移考虑两种情况:当天不爬山时取前一天两种状态的最大值;当天爬山时分别处理前一天不爬山和爬山(需消耗机会)的情况 最终结果为考虑所有可能用掉的k次机会后,最后一天两种状态的最大值 提供了Python、Java和C++三种实

m0_73659489的博客 1357

配置 SAP Web Dispatcher 的实战指南:打通 SAP Fiori、SAP Gateway 与前端系统的关键一跳

SAP Web Dispatcher 在 Fiori 架构中扮演关键角色,作为统一入口处理 HTTPS 请求、实现安全代理和流量分发。它将分散在不同系统的访问路径统一收口,解决浏览器同源策略限制,集中管理 HTTPS 终止和客户端信息传递。典型配置中,Web Dispatcher 监听 443 端口,根据路径将 OData 请求转发至 Gateway 系统,静态资源请求送至前端服务器。SSL 相关配置(如 PSE 文件)确保安全通信,而路由规则(wdisp/system_xx)决定请求转发目标。实施时需注意

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 103

Android 5.0 Lollipop 短彩信接收流程

短彩信接收流程和来电流程有点类似,最开始也是RIL层上报短信事件,然后上层来处理接收短信的流程。android的ril位于应用程序框架与内核之间,分成了两个部分,一个部分是rild,它负责socket与应用程序框架进行通信。另外一个部分是Vendor RIL,这个部分负责向下是通过两种方式与radio进行通信,它们是直接与radio通信的AT指令通道和用于传输包数据的通道,数据通道用于手机的上网功

Do Better Every Day 3850

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

android源代码短彩信分析之包介绍

很早就像写一些东西用来记录短彩信的一些流程,只不过一直没有动笔,可能没有太多时间,也可能不知道怎么开始,有句话叫“没有开始,就没有远方”,无论怎样,开动自己前进的脚步。同时很高兴和大家交流,如有错误不当之处,欢迎大家指正。 如果我们想提高自己的编码能力,那么我们就要学习别人的编码项目,android上层应用的开源,我们可以看到大洋彼岸的优秀程序员们码下的代码。 在android短彩信应

hailushijie的专栏 2137

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

彩信功能介绍

随着微信的普及,大家几乎很少使用传统的彩信业务了。 本文主要讲述传统的彩信业务,让大家对彩信功能有个了解。彩信主要用于发送图片、视频、文件之类。

weixin_51894735的博客 1691
上一篇: 常用的计算机英语(全集)
下一篇: 相对布局简解
Android_wy
博客等级 码龄16年 37粉丝 7原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值