- 浏览: 21371893 次
- 性别:
- 来自: 杭州
最新评论
-
ZY199266:
配置文件还需要额外的配置ma
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
ZY199266:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我又一个问题就是 如果像你的这种形式写。配置文件还需要额外的 ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
y1210251848:
你的那个错误应该是项目所使用的目标框架不支持吧
log4net配置(web中使用log4net,把web.config放在单独的文件中)
SMS管理:收信箱 发信息 编写新信息
SMS管理:收信箱 发信息 编写新信息
文章分类:移动开发
SMS管理
[功能]
1. 收信箱:显示所有收到的信息 且实时显示 即:当有新信息收到 能自动刷新显示
2. 发信箱:显示所有已发信息 同上
3. 编写新信息: 鉴于一些问题 打算不自行定义 而只通过Intent调用系统的
[原理]
1. 通过目标Uri显示收信箱 发信箱 目标Uri:content://sms/inbox content://sms/sent
2. 实时刷新:一个办法是开辟thread 定时查询目标Uri 显示之 但会带来一些效能影响 所以决定使用ContentObserve监听目标Uri 当有变动 由ContentObserve通知注册方 该Uri:content://sms
3. 注意:ContentObserve不能监听: content://sms/inbox & content://sms/sent 而只能监听content://sms
[代码 步骤]
1. 定义SMSObserver 用于监听目标 并通过Handle通知注册方
- public class SMSObserver extends ContentObserver{
- public final static int SMS_CHANGE= 0 ;
- Handlerhandle;
- public SMSObserver(Handlerh){
- super (h);
- //TODOAuto-generatedconstructorstub
- handle=h;
- }
- public void onChange( boolean selfChange){
- //TODOAuto-generatedmethodstub
- super .onChange(selfChange);
- //notifySMSInbox&SMSSent
- handle.sendEmptyMessage(SMS_CHANGE);
- }
- }
public class SMSObserver extends ContentObserver { public final static int SMS_CHANGE = 0; Handler handle; public SMSObserver(Handler h) { super(h); // TODO Auto-generated constructor stub handle = h; } public void onChange(boolean selfChange) { // TODO Auto-generated method stub super.onChange(selfChange); //notify SMSInbox & SMSSent handle.sendEmptyMessage(SMS_CHANGE); } }
2. 定义注册方:SMSInbox 鉴于SMSSent与其原理类似 故打算以SMSInbox为例
> 2.1. 显示当前所有收信箱 并与ListView适配
- lv=(ListView)findViewById(R.id.list);
- cursor=getContentResolver().query(Uri.parse("content://sms/inbox" ), null , null , null , null );
- adapter=new ItemAdapter( this );
- lv.setAdapter(adapter);
lv = (ListView)findViewById(R.id.list); cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null); adapter = new ItemAdapter(this); lv.setAdapter(adapter);
> 2.2. 定义Handle 用于接受变动 并注册与ContentObserve 当接到通知后 查询目标Uri 并刷新显示
- handler= new Handler(){
- public void handleMessage(Messagemsg){
- if (msg.what==SMSObserver.SMS_CHANGE){
- cursor=getContentResolver().query(Uri.parse("content://sms/inbox" ), null , null , null , null );
- adapter.notifyDataSetChanged();
- }
- }
- };
- sObserver=new SMSObserver(handler);
- this .getContentResolver().registerContentObserver(Uri.parse( "content://sms" ), true ,sObserver);
handler = new Handler(){ public void handleMessage(Message msg){ if(msg.what == SMSObserver.SMS_CHANGE){ cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null); adapter.notifyDataSetChanged(); } } }; sObserver = new SMSObserver(handler); this.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, sObserver);
> 2.3. SMSInbox 仅用于显示 收信箱 故定义 SMSDetails extends Activity 用于详细显示 sms信息
- 2.3.1. 定义布局:details.xml
- <?xmlversion= "1.0" encoding= "utf-8" ?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:id="@+id/detailsNumber"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <TextView
- android:id="@+id/detailsBody"
- android:layout_width="fill_parent"
- android:layout_height="200dip"
- />
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="300dip"
- android:layout_height="wrap_content"
- >
- <Button
- android:id="@+id/detailsReply"
- android:layout_width="100dip"
- android:layout_height="wrap_content"
- android:layout_gravity="left"
- android:text="回复"
- />
- <Button
- android:id="@+id/detailsOK"
- android:layout_width="100dip"
- android:layout_height="wrap_content"
- android:layout_gravity="right"
- android:text="确定"
- />
- </LinearLayout>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/detailsNumber" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/detailsBody" android:layout_width="fill_parent" android:layout_height="200dip" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="300dip" android:layout_height="wrap_content" > <Button android:id="@+id/detailsReply" android:layout_width="100dip" android:layout_height="wrap_content" android:layout_gravity="left" android:text="回复" /> <Button android:id="@+id/detailsOK" android:layout_width="100dip" android:layout_height="wrap_content" android:layout_gravity="right" android:text="确定" /> </LinearLayout> </LinearLayout>
- 2.3.2. 其中2个TextView 分别显示信息地址和正文 2个Button 一个用于关闭当前窗口 一个用于短信回复 且自动填充 收信人地址
- public class SMSDetails extends Activity{
- TextViewtextNumber,textBody;
- ButtonbtnOK,btnReply;
- OnClickListenercl;
- Stringaddress,body;
- /**Calledwhentheactivityisfirstcreated.*/
- @Override
- public void onCreate(BundlesavedInstanceState){
- super .onCreate(savedInstanceState);
- setContentView(R.layout.details);
- textNumber=(TextView)findViewById(R.id.detailsNumber);
- textBody=(TextView)findViewById(R.id.detailsBody);
- btnReply=(Button)findViewById(R.id.detailsReply);
- btnOK=(Button)findViewById(R.id.detailsOK);
- Intenti=this .getIntent();
- Bundlebundle=i.getExtras();
- address=bundle.getString("address" );
- body=bundle.getString("body" );
- textNumber.setText("from:" +address);
- textBody.setText("messagebody:/n" +body);
- cl=new OnClickListener(){
- @Override
- public void onClick(Viewarg0){
- //TODOAuto-generatedmethodstub
- switch (arg0.getId()){
- case R.id.detailsReply:
- sendGoNativeNew(address);
- break ;
- case R.id.detailsOK:
- sendBack();
- break ;
- }
- }
- };
- btnReply.setOnClickListener(cl);
- btnOK.setOnClickListener(cl);
- }
- public void sendGoNativeNew(Stringaddress){
- //nativesendsmsapp
- IntentsendIntent=new Intent(Intent.ACTION_SENDTO,Uri.parse( "sms://" ));
- //autofill"address"
- sendIntent.putExtra("address" ,address);
- startActivity(sendIntent);
- }
- public void sendBack(){
- Intenti=new Intent();
- this .setResult(RESULT_OK,i);
- this .finish();
- }
- }
public class SMSDetails extends Activity { TextView textNumber,textBody; Button btnOK,btnReply; OnClickListener cl; String address,body; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.details); textNumber = (TextView)findViewById(R.id.detailsNumber); textBody = (TextView)findViewById(R.id.detailsBody); btnReply = (Button)findViewById(R.id.detailsReply); btnOK = (Button)findViewById(R.id.detailsOK); Intent i = this.getIntent(); Bundle bundle = i.getExtras(); address = bundle.getString("address"); body = bundle.getString("body"); textNumber.setText("from:"+address); textBody.setText("message body:/n"+body); cl = new OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub switch(arg0.getId()){ case R.id.detailsReply: sendGoNativeNew(address); break; case R.id.detailsOK: sendBack(); break; } } }; btnReply.setOnClickListener(cl); btnOK.setOnClickListener(cl); } public void sendGoNativeNew(String address){ //native send sms app Intent sendIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("sms://")); //auto fill "address" sendIntent.putExtra("address", address); startActivity(sendIntent); } public void sendBack(){ Intent i = new Intent(); this.setResult(RESULT_OK, i); this.finish(); } }
- 2.3.3. 点击SMSInbox 某项 跳转到SMSDetails
- lv.setOnItemClickListener( new OnItemClickListener(){
- @Override
- public void onItemClick(AdapterView<?>arg0,Viewarg1, int arg2,
- long arg3){
- //TODOAuto-generatedmethodstub
- cursor.moveToPosition(arg2);
- Stringbody=cursor.getString(cursor.getColumnIndexOrThrow("body" )).toString();
- Stringaddress=cursor.getString(cursor.getColumnIndexOrThrow("address" )).toString();
- Bundleb=new Bundle();
- b.putString("body" ,body);
- b.putString("address" ,address);
- Intentintent=new Intent(SMSInbox. this ,SMSDetails. class );
- intent.putExtras(b);
- startActivity(intent);
- }
- });
lv.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub cursor.moveToPosition(arg2); String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString(); String address = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString(); Bundle b = new Bundle(); b.putString("body", body); b.putString("address", address); Intent intent = new Intent(SMSInbox.this,SMSDetails.class); intent.putExtras(b); startActivity(intent); } });
- 2.3.4. 其中item.xml 用于定义子项布局
- <? xml version = "1.0" encoding = "utf-8" ?>
- < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
- android:orientation = "vertical"
- android:layout_width = "fill_parent"
- android:layout_height = "fill_parent"
- >
- < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
- android:orientation = "horizontal"
- android:layout_width = "wrap_content"
- android:layout_height = "wrap_content"
- >
- < ImageView
- android:id = "@+id/body"
- android:layout_width = "wrap_content"
- android:layout_height = "wrap_content"
- />
- < TextView
- android:id = "@+id/num"
- android:layout_width = "wrap_content"
- android:layout_height = "wrap_content"
- android:paddingLeft = "5dip"
- />
- </ LinearLayout >
- < TextView
- android:id = "@+id/body"
- android:layout_width = "fill_parent"
- android:layout_height = "wrap_content"
- android:paddingLeft = "10dip"
- />
- </ LinearLayout >
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/body" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/num" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="5dip" /> </LinearLayout> <TextView android:id="@+id/body" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="10dip" /> </LinearLayout>
3. 鉴于SMSSent与SMSInbox大同小异 故不再细说 仅补上代码
- public class SMSSent extends Activity{
- ListViewlv;
- Cursorcursor;
- ItemAdapteradapter;
- SMSObserversObserver;
- Handlerhandler;
- /**Calledwhentheactivityisfirstcreated.*/
- @Override
- public void onCreate(BundlesavedInstanceState){
- super .onCreate(savedInstanceState);
- setContentView(R.layout.list);
- setTitle(R.string.sent);
- lv=(ListView)findViewById(R.id.list);
- cursor=getContentResolver().query(Uri.parse("content://sms/sent" ), null , null , null , null );
- adapter=new ItemAdapter( this );
- lv.setAdapter(adapter);
- lv.setOnItemClickListener(new OnItemClickListener(){
- @Override
- public void onItemClick(AdapterView<?>arg0,Viewarg1, int arg2,
- long arg3){
- //TODOAuto-generatedmethodstub
- cursor.moveToPosition(arg2);
- Stringbody=cursor.getString(cursor.getColumnIndexOrThrow("body" )).toString();
- Stringaddress=cursor.getString(cursor.getColumnIndexOrThrow("address" )).toString();
- Bundleb=new Bundle();
- b.putString("body" ,body);
- b.putString("address" ,address);
- Intentintent=new Intent(SMSSent. this ,SMSDetails. class );
- intent.putExtras(b);
- startActivity(intent);
- }
- });
- //registerSMSObserve
- handler=new Handler(){
- public void handleMessage(Messagemsg){
- if (msg.what==SMSObserver.SMS_CHANGE){
- cursor=getContentResolver().query(Uri.parse("content://sms/sent" ), null , null , null , null );
- adapter.notifyDataSetChanged();
- }
- }
- };
- sObserver=new SMSObserver(handler);
- this .getContentResolver().registerContentObserver(Uri.parse( "content://sms" ), true ,sObserver);
- }
- public class ItemAdapter extends BaseAdapter{
- Activityactivity;
- public ItemAdapter(Activitya){
- activity=a;
- }
- @Override
- public int getCount(){
- //TODOAuto-generatedmethodstub
- return cursor.getCount();
- }
- @Override
- public ObjectgetItem( int arg0){
- //TODOAuto-generatedmethodstub
- return cursor.getString(arg0);
- }
- @Override
- public long getItemId( int arg0){
- //TODOAuto-generatedmethodstub
- return arg0;
- }
- @Override
- public ViewgetView( int arg0,Viewarg1,ViewGrouparg2){
- //TODOAuto-generatedmethodstub
- return composeItem(arg0);
- }
- private ViewcomposeItem( int position){
- cursor.moveToPosition(position);
- Stringbody=cursor.getString(cursor.getColumnIndexOrThrow("body" )).toString();
- Stringnumber=cursor.getString(cursor.getColumnIndexOrThrow("address" )).toString();
- LinearLayoutitem=(LinearLayout)activity.getLayoutInflater().inflate(R.layout.item,null );
- LinearLayoutl1=(LinearLayout)item.getChildAt(0 );
- TextViewtbody=(TextView)item.getChildAt(1 );
- if (tbody!= null ){
- tbody.setText(body);
- }
- TextViewtnum=(TextView)l1.getChildAt(1 );
- if (tnum!= null ){
- tnum.setText(number);
- }
- ImageViewimage=(ImageView)l1.getChildAt(0 );
- image.setImageResource(R.drawable.message);
- return item;
- }
- }
- }
public class SMSSent extends Activity { ListView lv; Cursor cursor; ItemAdapter adapter; SMSObserver sObserver; Handler handler; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list); setTitle(R.string.sent); lv = (ListView)findViewById(R.id.list); cursor = getContentResolver().query(Uri.parse("content://sms/sent"), null, null, null, null); adapter = new ItemAdapter(this); lv.setAdapter(adapter); lv.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub cursor.moveToPosition(arg2); String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString(); String address = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString(); Bundle b = new Bundle(); b.putString("body", body); b.putString("address", address); Intent intent = new Intent(SMSSent.this,SMSDetails.class); intent.putExtras(b); startActivity(intent); } }); //register SMSObserve handler = new Handler(){ public void handleMessage(Message msg){ if(msg.what == SMSObserver.SMS_CHANGE){ cursor = getContentResolver().query(Uri.parse("content://sms/sent"), null, null, null, null); adapter.notifyDataSetChanged(); } } }; sObserver = new SMSObserver(handler); this.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, sObserver); } public class ItemAdapter extends BaseAdapter { Activity activity; public ItemAdapter(Activity a){ activity = a; } @Override public int getCount() { // TODO Auto-generated method stub return cursor.getCount(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return cursor.getString(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub return composeItem(arg0); } private View composeItem(int position){ cursor.moveToPosition(position); String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString(); String number = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString(); LinearLayout item = (LinearLayout)activity.getLayoutInflater().inflate(R.layout.item, null); LinearLayout l1 = (LinearLayout)item.getChildAt(0); TextView tbody = (TextView)item.getChildAt(1); if(tbody != null){ tbody.setText(body); } TextView tnum = (TextView)l1.getChildAt(1); if(tnum != null){ tnum.setText(number); } ImageView image = (ImageView)l1.getChildAt(0); image.setImageResource(R.drawable.message); return item; } } }
4. emulator 运行截图
> 4.1.SMSInbox:
- 4.1.1. 通过telnet localhost 5554 登录emulator 通过 sms send 123 hello to 123 模拟发送短信
- 4.1.2. 短信发送记录为:
- AndroidConsole:type 'help' for alistofcommands
- OK
- smssend12 ds
- OK
- smssend23 hito 23
- OK
- smssend34 iamgriddinshi
- OK
Android Console: type 'help' for a list of commands OK sms send 12 ds OK sms send 23 hi to 23 OK sms send 34 i am griddinshi OK
- 4.1.3. SMSInbox:
<!-- StartFragment -->> 4.2. SMSSent
- 4.2.1. 已发短信记录:
- 4.2.2. SMSSent:
5. 未解决问题:
> 5.1. ContentObserver 只能监听content://sms 而不支持content://sms/inbox content://sms/sent 个人猜测是因为:android 在写sms数据库 insert(...) 没有通过ContentResolver通知content://sms/inbox content://sms/sent 所致 即:没有以下代码:
getContext().getContentResolver().notifyChange(noteUri, null);
相关推荐
c#编写的短信猫(WAVECOM)发送短信程序dll,没有任何功能限制,在你的程序中引用SIMSMS.dll就可以了。帮助文档就不写了,在程序中有注释,在测试的winform中也有简单应用的示例。看看就明白了! 如果感觉功能不够,...
一方面,电子邮件的使用越来越频繁,...该软件对指定邮件服务器的邮箱进行监控,可以实现邮件到达通知、直接用邮件发送短信息、发送邮件的同时发送短消息、短信群发等功能,将信息的传递从桌面上延伸到移动通讯设备上。
//给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener 在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息...
//给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener 在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息...
与Light Flow,增强的SMS和呼叫者ID,云打印,Apex Launcher Pro,Nova Launcher / Tesla Unread,执行助理,DashClock Widget集成。 许多设置可以按您想要的方式配置应用程序。WiFi和移动连接的单独设置。 ...
我们提供SMS文本(并非每个人都拥有智能手机),交易邮件(老式邮箱没有问题)和本机推送通知,包括自定义模板和通知掩码。 安装 将此行添加到您的应用程序的Gemfile中: gem 'myxy' 然后执行: $ bundle 或将...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...
LemonSMS 这个Java库可以让开发者在应用程序中集成使用GSM调制解调器或兼容电话来发送SMS消息。 远程桌面 Java Remote Desktop.tar Java Remote Desktop 是一个Java 的远程桌面软件,支持很多特性例如文件传输、...