2013年12月11日星期三
android 发送短信的两种方式
android中可以通过两种方式发送短信
第一:调用系统短信接口直接发送短信;主要代码如下:
Java代码 收藏代码
/**
* 直接调用短信接口发短信
* @param phoneNumber
* @param message
*/
public void sendSMS(String phoneNumber,String message){
//获取短信管理器
android.telephony.SmsManager smsManager = android.telephony.SmsManager.getDefault();
//拆分短信内容(手机短信长度限制)
List<String> divideContents = smsManager.divideMessage(message);
for (String text : divideContents) {
smsManager.sendTextMessage(phoneNumber, null, text, sentPI, deliverPI);
}
}
第二:调起系统发短信功能;主要代码如下:
Java代码 收藏代码
/**
* 调起系统发短信功能
* @param phoneNumber
* @param message
*/
public void doSendSMSTo(String phoneNumber,String message){
if(PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber)){
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:"+phoneNumber));
intent.putExtra("sms_body", message);
startActivity(intent);
}
}
别忘了权限:
<uses-permission android:name="android.permission.SEND_SMS" />
这里主要讲解第一种方法,第一种方法可以监控发送状态和对方接收状态。
处理返回的发送状态:
Java代码 收藏代码
//处理返回的发送状态
String SENT_SMS_ACTION = "SENT_SMS_ACTION";
Intent sentIntent = new Intent(SENT_SMS_ACTION);
PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, sentIntent,
0);
// register the Broadcast Receivers
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context _context, Intent _intent) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(context,
"短信发送成功", Toast.LENGTH_SHORT)
.show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
break;
}
}
}, new IntentFilter(SENT_SMS_ACTION));
处理返回的接收状态 :
Java代码 收藏代码
//处理返回的接收状态
String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
// create the deilverIntent parameter
Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
PendingIntent deliverPI = PendingIntent.getBroadcast(context, 0,
deliverIntent, 0);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context _context, Intent _intent) {
Toast.makeText(context,
"收信人已经成功接收", Toast.LENGTH_SHORT)
.show();
}
}, new IntentFilter(DELIVERED_SMS_ACTION));
发送短信的参数说明:
Java代码 收藏代码
smsManager.sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent)
-- destinationAddress:目标电话号码
-- scAddress:短信中心号码,测试可以不填
-- text: 短信内容
-- sentIntent:发送 -->中国移动 --> 中国移动发送失败 --> 返回发送成功或失败信号 --> 后续处理 即,这个意图包装了短信发送状态的信息
-- deliveryIntent: 发送 -->中国移动 --> 中国移动发送成功 --> 返回对方是否收到这个信息 --> 后续处理 即:这个意图包装了短信是否被对方收到的状态信息(供应商已经发送成功,但是对方没有收到)。
转自:http://gundumw100.iteye.com/blog/1774899
2013年9月1日星期日
在ActionBar中进行Fragment之间的切换
在ActionBar中添加标签(Tabs),每个标签对应的是一个Fragment,点击不同的Tab时,就会切换到对应的Fragment。
这里有五个关键步骤:
1. 要实现
2. 通过
3. 设置AcitonBar的操作模式:
4. 在ActionBar中添加Tabs:一.调用AciontBar的newTab()生成一个ActionBar.Tab. 二.为Tab增加text或者icon .调用
5. 调用addTab()将生成的Tab加入ActionBar中
以下是例子代码,就是为了测试,没有实际的用途.
有两个Fragment:EditFragment和ComputerFragment,对应的Tab是"编辑"和计算。他们的XML和Activity如下:
EditFragment:
editfragment.xml:
ComputerFragment:
computerfragment.xml:
主要的程序:MainActivity:
程序运行结果:

这里有五个关键步骤:
1. 要实现
ActionBar.TabListener接口,当点击Tab的时候触发这个接口里面的事件,有onTabSelected(), onTabUnselected(), 和 onTabReselected(). 实现ActionBar.TabListener接口时,应当在类内有个Fragment的引用,这样点击这个Tab时就可以调用对应的Fragment.2. 通过
getActionBar() 方法得到Activity中的ActionBar。3. 设置AcitonBar的操作模式:
setNavigationMode(NAVIGATION_MODE_TABS)。4. 在ActionBar中添加Tabs:一.调用AciontBar的newTab()生成一个ActionBar.Tab. 二.为Tab增加text或者icon .调用
setText() , setIcon() 三.为每个 ActionBar.Tab 添加ActionBar.TabListener.5. 调用addTab()将生成的Tab加入ActionBar中
以下是例子代码,就是为了测试,没有实际的用途.
有两个Fragment:EditFragment和ComputerFragment,对应的Tab是"编辑"和计算。他们的XML和Activity如下:
EditFragment:
public class EditFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { System.out.println("EidtFragment--->onCreate"); super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { System.out.println("EidtFragment--->onCreateView"); return inflater.inflate(R.layout.editfragment, container, false); } @Override public void onStop() { System.out.println("EidtFragment--->onStop"); super.onStop(); } }
editfragment.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="请输入你的信息:" android:textSize="20dp" /> <EditText android:layout_width="fill_parent" android:layout_height="40pt" android:layout_margin="5dp" android:background="@android:color/darker_gray" android:textSize="18dp" /> </LinearLayout>
public class ComputerFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { System.out.println("ComputerFragment--->onCreate"); super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { System.out.println("ConputerFragment--->onCreateView"); return inflater.inflate(R.layout.computerfragment, container, false); } @Override public void onStop() { System.out.println("ConputerFragment--->onStop"); super.onStop(); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="简单加法计算" android:textSize="20dp" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:background="@android:color/darker_gray" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:background="@android:color/darker_gray" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="开始计算" /> </LinearLayout>
主要的程序:MainActivity:
public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { System.out.println("MainActivity--->onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.main); // 得到Activity的ActionBar ActionBar actionBar = getActionBar(); // 设置AcitonBar的操作模型 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // 将Activity的头部去掉 actionBar.setDisplayShowTitleEnabled(false); // 生成Tab Tab edit = actionBar.newTab().setText("编辑"); Tab computer = actionBar.newTab().setText("计算"); // 为每个Tab添加Listener MyTabListener editListener = new MyTabListener(new EditFragment()); edit.setTabListener(editListener); MyTabListener computerListener = new MyTabListener(new ComputerFragment()); computer.setTabListener(computerListener); // 将Tab加入ActionBar中 actionBar.addTab(edit); actionBar.addTab(computer); } @Override protected void onStop() { System.out.println("MainActivity--->onStop"); super.onStop(); } /** * 实现ActionBar.TabListener接口 */ class MyTabListener implements TabListener { // 接收每个Tab对应的Fragment,操作 private Fragment fragment; public MyTabListener(Fragment fragment) { this.fragment = fragment; } public void onTabReselected(Tab tab, FragmentTransaction ft) { } // 当Tab被选中的时候添加对应的Fragment public void onTabSelected(Tab tab, FragmentTransaction ft) { ft.add(R.id.context, fragment, null); } // 当Tab没被选中的时候删除对应的此Tab对应的Fragment public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(fragment); } } }
程序运行结果:

使用viewpager,actionbar,fragment时正确导入android-support-v4.jar的方法
很多同学在导入使用了ViewPage,ActionBar,Fragment的工程后出现错误,很有可能是没有导入4.0版本的支持包。本人也是碰到这个问题,特意搜索了一下,得到解决办法如下,记录下来,以免忘记。
正确导入方法为:
首先在Project->properties->Java Build Path->Libraries->Add External Jars中加入sdk目录下的extras/android/support/v4/android-support-v4.jar(如果找不到,则需要用sdk manager下载android support package)。加入这个jar包之后就可以使用ViewPager类了。
举一反三,其它的包加入应该也是这个步骤。
每天记录一下,希望尽快积累起知识。祝每个开发安卓的同志学有大成!大家一起努力!加油!
正确导入方法为:
首先在Project->properties->Java Build Path->Libraries->Add External Jars中加入sdk目录下的extras/android/support/v4/android-support-v4.jar(如果找不到,则需要用sdk manager下载android support package)。加入这个jar包之后就可以使用ViewPager类了。
举一反三,其它的包加入应该也是这个步骤。
每天记录一下,希望尽快积累起知识。祝每个开发安卓的同志学有大成!大家一起努力!加油!
Android兼容包及Fragment, Loader, ActionBar简介
最近使用了一下Android Compatibility Package(最新版本r4改名叫做了Support Package),地址:http://developer.android.com/sdk/compatibility-library.html。这个Package主要是提供了较早平台版本不支持的一些API。目的是为了使程序员较少关注平台版本,而写出前向兼容的程序。比如http://code.google.com/p/iosched/这个应用就是使用的Compatibility Package。
Compatibility Package主要是加入了平板平台引入的一些API的支持,如Fragment,Loader等,我最近就把玩了一下Fragment和Loader,感觉很有意思。
(以上两段抄自《Android前向兼容的几个问题 》)
(以上两段抄自《Android前向兼容的几个问题 》)
关于Android的兼容包,官方原文介绍:
The Support Package includes static "support libraries" that you can add to your Android application in order to use APIs that are either not available for older platform versions or that offer "utility" APIs that aren't a part of the framework APIs. The goal is to simplify your development by offering more APIs that you can bundle with your application so you can worry less about platform versions.
主要的类有:
Fragment
FragmentManager
FragmentTransaction
ListFragment
DialogFragment
LoaderManager
Loader
AsyncTaskLoader
CursorLoader
Fragment
FragmentManager
FragmentTransaction
ListFragment
DialogFragment
LoaderManager
Loader
AsyncTaskLoader
CursorLoader
源码目录extras/android/support/v4/samples/下有例子,类似于Api Demos,可以编译安装试用。
看现在的Google更新的手机设备App的UI风格基本上都是ActionBar,左右滑动ViewPager。android兼容包没有提供Action Bar的兼容类,但是官方有个Demo,在http://developer.android.com/resources/samples/ActionBarCompat/index.html。还有一个就是,ViewPager实现了水平View滑动效果。http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html,这里有介绍。
对于使用Compatibility Package来使用Fragment和Loader,使用上同Android 3.0引入的APIs基本相同,有些许细微差别,可以看http://developer.android.com/sdk/compatibility-library.html#Using
接下来简单介绍一下这几个类的概念和使用场景。
Fragment 介绍
Fragment是在Android 3.0引入的,从名字可以看出是片段。我的理解就是类似于,早年人们认为分子是构成物质的基本单位,但是后来人们发现原子才是。我觉得Fragment就类似于原子,而View之类的应该是电子。以View作为片段也是可以的,但是麻烦之处在于生命周期的管理和动态布局时View层次的变更处理起来比较麻烦,并且View一般很少用来处理业务逻辑,它的感觉更Base,在View的外面包装业务逻辑,而Fragment在内部封装业务逻辑,可以达到模块化,解耦合,代码重用。对于大的Activity可以进一步模块划分。但是Fragment的出现按文档来看应该是方便了动态布局的需求,特别是针对手机和平板设备。
一个典型的应用场景是,一个概要的列表的界面,然后一个详细信息的界面。比如在手机上做这个应用,往往是一个ListActivity,然后点击对应的项目后,跳转到项目的详细的Activity。但是对于大屏幕设备,比如说平板设备,一个10寸的屏幕,就显示个单行的大列表是太奢侈了,可能的布局是左面是题目列表,然后右面显示具体的内容。如图,

http://developer.android.com/guide/practices/tablets-and-handsets.html,这个链接里详细说了对于同时支持平板和手机设备的应用的最佳实践。简单概括起来一句话,Google鼓励基于Fragment和ActionBar来设计Activity。
Loader 介绍
Loader用来异步加载数据,刚看接口和Guide的时候,感觉挺牛的,方便了异步加载数据,现在很多应用都是基于请求服务器获取数据,然后客户端不过是个前端展示应用。里面有大量的Web请求,写起来很麻烦。Loader封装了看起来不错的接口,但是我初步使用的感受是也不是很方便。
APIs主要有LoaderManager,LoaderManager是一个管理类,对于一个Activity或者Fragment可以有多个Loader,可以通过LoaderManager进行统一管理。还有两个基于Loader虚基类的两个类CursorLoader和AsyncTaskLoader。对于CursorLoader主要是用于数据库或者Content Provider的相关接口的数据的load。对于AsyncTaskLoader是在AsyncTask基础上和Loader的一个集成。AsyncTaskLoader也是个虚的类,要实现loadInBackgroud()方法,起初,我以为只要实现了这个方法,就好了,但是事实并不是这样,所以我觉得这个类设计的并不是很方便。简单的应用场景还不如用AsyncTask来的方便爽快。
Action Bar 介绍
原有Title升级版,主要是UI。对于手机设备,就是左边是Logo,右边是几个按钮,中间是标题。对于平板设备会复杂一些,Tab或者Drop-down导航,方便导航。对于ActionBar的非主Activity会有个向左的箭头,这个不是后退的意思,是上一级的意思。类似于Windows的向上,是同个应用的上一级。详细:http://developer.android.com/guide/topics/ui/actionbar.html#Up
android兼容包没有提供Action Bar的兼容类,但是官方有个Demo,在http://developer.android.com/resources/samples/ActionBarCompat/index.html
小结一下,个人感觉Fragment很有用,方便了代码重用,便于模块化,运行时动态变更布局。
另外,有人根据Google官方的Android兼容包写了http://actionbarsherlock.com/ 这个,个人感觉不错,主要是加入了ActionBar的支持。
END#每次水文后焦虑值都蹭蹭涨#
android读取系统通话记录及短信
权限
读取通话记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
public ArrayList<HashMap<String, Object>> getCallLogList(Context context,
int start,int limitKey) {
// TODO Auto-generated method stub
Date d = new Date();
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm:ss");
Cursor cursor = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI, null, null, null,
CallLog.Calls.DEFAULT_SORT_ORDER + " limit " + start+"," +limitKey);
while (cursor.moveToNext()){
HashMap<String, Object> hm = new HashMap<String, Object>();
//String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
String date = sdf.format(new Date(Long.valueOf(cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE)))));
String status = cursor.getString(cursor.getColumnIndex(CallLog.Calls.TYPE));
if (status.equals("1")) {
status = Constants.CALL_STATE_FROM_GET;
hm.put("callStateImg", R.drawable.call_state_from);
} else if (status.equals("2")) {
status = Constants.CALL_STATE_TO;
hm.put("callStateImg", R.drawable.call_state_to);
} else {
status = Constants.CALL_STATE_MISSES ;
hm.put("callStateImg", R.drawable.call_state_hangup);
}
String contact_name = GlobalUtil.getContactNameFromPhoneNum(context,number);
if(contact_name!=null && !contact_name.equals("")){
hm.put("name", contact_name);
hm.put("categray", Constants.CATEGRAY_IN_CONTACTS);
hm.put("disp", "联系人");
}else{
hm.put("name", number);
initNumberCateGrayAndInfo(number,hm);
}
hm.put("status", status);
hm.put("number", number);
hm.put("date", date);
hm.put("belongs", this.findNumBelongs(number));
list.add(hm);
}
return list;
}
|
读取短信
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
public ArrayList<HashMap<String, Object>> getMessageLogList(
Context context, int start,int limitKey) {
// TODO Auto-generated method stub
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
String[] projection = new String[] { "_id", "address", "person",
"body", "read", "date" };
Cursor cur = context.getContentResolver()
.query(Uri.parse("content://sms/inbox"), projection, null, null,
"date desc limit " + start+"," +limitKey);
int smsColumn_id = cur.getColumnIndex("_id");
int phoneColumn = cur.getColumnIndex("address");
int smsColumn = cur.getColumnIndex("body");
int readColum = cur.getColumnIndex("read");
int dateColum = cur.getColumnIndex("date");
while (cur.moveToNext()){
// Get the field values
HashMap<String, Object> hm = new HashMap<String, Object>();
String number = cur.getString(phoneColumn);
if(number!=null){
String name = GlobalUtil.getContactByAddr(context,number);
String sms = cur.getString(smsColumn);
String sms_id = cur.getString(smsColumn_id);
int read = cur.getInt(readColum);
String date = cur.getString(dateColum);
SimpleDateFormat sfd = new SimpleDateFormat("MM/dd hh:mm:ss");
Date date_format = new Date(Long.parseLong(date));
String date_time = sfd.format(date_format);
// 还要判断是否存在于本地黑名单、和临时通讯录、还要联系人中
if(name!=null && !name.equals("")){
hm.put("categray", Constants.CATEGRAY_IN_CONTACTS);
hm.put("disp", "联系人");
hm.put("name", name);
}else{
initNumberCateGrayAndInfo(number,hm);
hm.put("name", number);
}
hm.put("number", number);
if(sms!=null && sms.length()>4){
hm.put("short_sms", date_time+"-"+sms.substring(0,4)+"...");
hm.put("sms", sms);
}else if(sms!=null){
hm.put("sms", sms);
hm.put("short_sms", sms);
}else{
hm.put("sms", "");
hm.put("short_sms", "");
}
if(0 == read){//未读
hm.put("read_state", R.drawable.msg_unread);
}else{//已读
hm.put("read_state", R.drawable.msg_read);
}
hm.put("read", read+"");
hm.put("date", date_time + "");
hm.put("sms_id", sms_id + "");
hm.put("belongs", findNumBelongs(number));
list.add(hm);
}
}
return list;
}
|
订阅:
博文 (Atom)