Android笔记----Android手势和ContentProvider

来源:互联网 发布:阿里二手域名 编辑:程序博客网 时间:2024/06/14 06:04

手势(Gesture)

ContentProvider简介

操作系统的ContentProvider

实现ContentProvider

监听ContentProvider的数据改变

 

 

 

 

 

手势(Gesture)

        所谓手势,指用户手指或触摸笔在触摸屏上的连续触碰行为。手势这种连续的触碰会形成某个方向上的移动趋势,也会形成一个不规则的几何图形。

Android对两种手势行为都提供了支持:

第一种手势行为而言,Android提供了手势检测,并为手势提供相应的监听器。

对于第二种手势行为,Android允许开发者添加手势,并提供相应的API

1.1 手势检测

       GestureDetector是一个手势检测器,创建GestureDetector时需要传入一个GestureDetector.OnGestureListener实例, 负责对用户的手势行为提供响应。GestureDetector包含的事件处理方法如下:

       boolean onDown(MotionEvent e):当触碰事件按下时触发该方法。

       boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) :在触摸屏上拖过时触发该方法。

       void onLongPress(MotionEvent e):当用户在屏幕上长按时触发该方法。

       boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):当用户在屏幕上”滚动”时触发该方法。

       void onShowPress(MotionEvent e) :当用户在触摸屏上按下、而且还未移动和松开时触发该方法。

       boolean onSingleTapConfirmed(MotionEvent e)

       boolean onSingleTapUp(MotionEvent e):用户在屏幕上的轻击事件将会触发该方法。

使用Android手势检测只需要两个步骤:

       创建一个GestureDetector对象,创建该对象时必须实现GestureDetector.OnGestureListener监听器实例。

       为应用程序的ActivityTouchEvent事件绑定监听器,在事件处理中指定把Activity上的TouchEvent事件交给GestureDetector处理。

 

例:手势动作测试:

手势动作测试

GestureTest.java

public class GestureTest extends Activityimplements OnGestureListener{// 定义手势检测器实例GestureDetector detector;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);//创建手势检测器detector = new GestureDetector(this);}//将该Activity上的触碰事件交给GestureDetector处理@Overridepublic boolean onTouchEvent(MotionEvent me){return detector.onTouchEvent(me);}@Overridepublic boolean onDown(MotionEvent arg0){Toast.makeText(this,"onDown" , 8000).show();return false;}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY){Toast.makeText(this , "onFling" , 8000).show();return false;}@Overridepublic void onLongPress(MotionEvent e){Toast.makeText(this ,"onLongPress" , 8000).show();}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY){Toast.makeText(this ,"onScroll" , 8000).show();return false;}@Overridepublic void onShowPress(MotionEvent e){Toast.makeText(this ,"onShowPress" , 8000).show();}@Overridepublic boolean onSingleTapUp(MotionEvent e){Toast.makeText(this ,"onSingleTapUp" , 8000).show();return false;}}

 

例:手势实现翻页效果:

GestureFlip.java

public class GestureFlip extends Activityimplements OnGestureListener{// ViewFlipper实例ViewFlipper flipper;// 定义手势检测器实例GestureDetector detector;//定义一个动画数组,用于为ViewFlipper指定切换动画效果Animation[] animations = new Animation[4];//定义手势动作两点之间的最小距离final int FLIP_DISTANCE = 50;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);//创建手势检测器detector = new GestureDetector(this);// 获得ViewFlipper实例flipper = (ViewFlipper) this.findViewById(R.id.flipper);// 为ViewFlipper添加5个ImageView组件flipper.addView(addImageView(R.drawable.java));flipper.addView(addImageView(R.drawable.ee));flipper.addView(addImageView(R.drawable.ajax));flipper.addView(addImageView(R.drawable.xml));flipper.addView(addImageView(R.drawable.classic));//初始化Animation数组animations[0] = AnimationUtils.loadAnimation(this, R.anim.left_in);animations[1] = AnimationUtils.loadAnimation(this, R.anim.left_out);animations[2] = AnimationUtils.loadAnimation(this, R.anim.right_in);animations[3] = AnimationUtils.loadAnimation(this, R.anim.right_out);}// 定义添加ImageView的工具方法private View addImageView(int resId){ImageView imageView = new ImageView(this);imageView.setImageResource(resId);imageView.setScaleType(ImageView.ScaleType.CENTER);return imageView;}@Overridepublic boolean onFling(MotionEvent event1, MotionEvent event2,float velocityX, float velocityY){/* * 如果第一个触点事件的X座标大于第二个触点事件的X座标超过FLIP_DISTANCE * 也就是手势从右向左滑。 */if (event1.getX() - event2.getX() > FLIP_DISTANCE){// 为flipper设置切换的的动画效果flipper.setInAnimation(animations[0]);flipper.setOutAnimation(animations[1]);flipper.showPrevious();return true;}/* * 如果第二个触点事件的X座标大于第一个触点事件的X座标超过FLIP_DISTANCE  * 也就是手势从右向左滑。 */else if (event2.getX() - event1.getX() > FLIP_DISTANCE){// 为flipper设置切换的的动画效果flipper.setInAnimation(animations[2]);flipper.setOutAnimation(animations[3]);flipper.showNext();return true;}return false;}@Overridepublic boolean onTouchEvent(MotionEvent event){//将该Activity上的触碰事件交给GestureDetector处理return detector.onTouchEvent(event);}@Overridepublic boolean onDown(MotionEvent arg0){return false;}@Overridepublic void onLongPress(MotionEvent event){}@Overridepublic boolean onScroll(MotionEvent event1, MotionEvent event2,float arg2, float arg3){return false;}@Overridepublic void onShowPress(MotionEvent event){}@Overridepublic boolean onSingleTapUp(MotionEvent event){return false;}}

 

Main.xm

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <!-- 定义ViewFlipper组件 -->    <ViewFlipper        android:id="@+id/flipper"        android:layout_width="fill_parent"        android:layout_height="fill_parent" /></LinearLayout>


 

1.2 增加手势

       Android除了手势检测外,还允许应用程序把用户手势添加到指定文件,以备以后使用,如果程序需要,当用户下次再次画出该手势,系统将可识别该手势。

Android使用GestureLibrary来代表手势库,并提供GestureLibraries工具类来创建手势库,添加手势库的方法如下:

       static GestureLibraryfromFile(File path):从path代表的文件中加载手势库。

       static GestureLibraryfromFile(String path):从path代表的文件中加载手势库。

       static GestureLibraryfromPrivateFile(Context context, String name):从指定的应用程序的数据文件中name文件中加载手势库。

       static GestureLibraryfromRawResource(Context context, int resourceId):从resourceId所代表的资源中加载手势库。

一旦程序中获得了GestureLibrary对象后,该对象提供了如下方法来添加手势、识别手势。

 

例:增加手势:

AddGesture.java

public class AddGesture extends Activity{EditText editText;GestureOverlayView gestureView;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 获取文本编辑框editText = (EditText) findViewById(R.id.gesture_name);// 获取手势编辑视图gestureView = (GestureOverlayView) findViewById(R.id.gesture);// 设置手势的绘制颜色gestureView.setGestureColor(Color.RED);// 设置手势的绘制宽度gestureView.setGestureStrokeWidth(4);// 为gesture的手势完成事件绑定事件监听器gestureView.addOnGesturePerformedListener(new OnGesturePerformedListener(){@Overridepublic void onGesturePerformed(GestureOverlayView overlay,final Gesture gesture){//加载save.xml界面布局代表的视图View saveDialog = getLayoutInflater().inflate(R.layout.save, null);// 获取saveDialog里的show组件ImageView imageView = (ImageView) saveDialog.findViewById(R.id.show);// 获取saveDialog里的gesture_name组件final EditText gestureName = (EditText) saveDialog.findViewById(R.id.gesture_name);// 根据Gesture包含的手势创建一个位图Bitmap bitmap = gesture.toBitmap(128, 128, 10, 0xFFFF0000);imageView.setImageBitmap(bitmap);//使用对话框显示saveDialog组件new AlertDialog.Builder(AddGesture.this).setView(saveDialog).setPositiveButton("保存", new OnClickListener(){@Overridepublic void onClick(DialogInterface dialog,int which){// 获取指定文件对应的手势库GestureLibrary gestureLib = GestureLibraries.fromFile("/sdcard/mygestures");// 添加手势gestureLib.addGesture(gestureName.getText().toString(),gesture);// 保存手势库gestureLib.save();}}).setNegativeButton("取消", null).show();}});}}


 

Main.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"android:gravity="center_horizontal"><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:text="请在下面屏幕上绘制手势"/><!-- 使用手势绘制组件 --><android.gesture.GestureOverlayViewandroid:id="@+id/gesture"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gestureStrokeType="multiple" /></LinearLayout>

 

save.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"><LinearLayoutandroid:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="8dip"android:text="@string/gesture_name" /><!-- 定义一个文本框来让用户输入手势名 --> <EditTextandroid:id="@+id/gesture_name"android:layout_width="fill_parent"android:layout_height="wrap_content"/></LinearLayout><!-- 定义一个图片框来显示手势 --> <ImageViewandroid:id="@+id/show"android:layout_width="128dp"android:layout_height="128dp"android:layout_marginTop="10dp" /></LinearLayout>


 

ContentProvider简介

       为了在应用程序之间交换数据,Android提供了ContentProvider,它提供了不同应用程序之间交换数据的标准API,当一个应用程序需要把自己的数据暴露给其他应用程序使用时,该应用程序通过提供ContentProvider来实现其他应用程序可通过ContentResolver来操作ContentProvider暴露的数据。

       ContentProvider是四大组件之一,也需要在AndroidManifest.xml文件中进行配置。

2.1共享数据标准: ContentProvider简介

ContentProvider提供了数据访问的接口,以某种Uri的形式对外提供数据,允许其他应用访问或修改数据;其他应用程序使用ContentResolver根据Uri去访问操作指定的数据。

开发一个ContentProvider的步骤如下:

       定义ContentProvider类,该类需要继承ContentProvider基类。

       在AndroidManifest.xml文件中配置该ContentProvider


一个ContentProvider类除了继承ContentProvider基类外,还需要提供的方法如下:

       onCreate():ContentProvider在其它应用第一次访问时才会被创建。 

       insert ():用于供外部应用往ContentProvider添加数据。 

       delete ():用于供外部应用从ContentProvider删除数据。 

       update():用于供外部应用更新ContentProvider中的数据 

       query():用于供外部应用从ContentProvider中获取数据。 

对于ContentProvider而言,都是以Uri形式对外提供数据,Uri形如:

       content://www.abc/words/2

       content:这部分是Android所规定的。

       com.boby.providers.dictprovider:这部分是ContentProviderauthority

       words:资源部分,当访问不同资源时,这部分是动态变化的。

 

2ID部分

其他应用程序使用ContentResolver根据Uri去访问指定数据。可以通过getContentResolver()方法来获得该对象。获得ContentResolver对象后,就可以利用如下方法操作数据。

insert(Uri uri,ContentValues values):向Uri对应的ContentProvider中插入values对应的数据。

delete(Uri uri,String where, String[] selectionArgs):删除Uri对应的ContentProviderwhere提交匹配的数据。

update(Uri uri,ContentValues values,String where, String[] selectionArgs):更新Uri对应的ContentProviderwhere提交匹配的数据。

query (Uri uri,String[] projection,String selection, String[] selectionArgs,String sortOrder):查询Uri对应的ContentProviderwhere提交匹配数据。

 

 

操作系统的ContentProvider

使用ContentResolver操作数据的步骤很简单如下所示:

       调用ActivitygetContentResolver()获取ContentResolver()对象。

       根据需要调用ContentResolverinsert()delete()update()query方法。

Android系统中提供了Contacts应用程序来管理联系人,而且Android系统中还为联系人管理提供了ContentProvider,这就允许其他应用程序ContentResolver来管理联系人数据。

Android系统对联系人管理ContentProvider的几个Uri如下:

       ContactsContract.Contacts.CONTENT_URI:管理联系人的Uri

       ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理联系人电话的Uri

       ContactsContract.CommonDataKinds.Email.CONTENT_URI:管理联系人EmailUri

例:

ContactProviderTest.java

public class ContactProviderTest extends Activity{Button search;Button add;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 获取系统界面中查找、添加两个按钮search = (Button) findViewById(R.id.search);add = (Button) findViewById(R.id.add);search.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View source){// 定义两个List来封装系统的联系人信息、指定联系人的电话号码、Email等详情final ArrayList<String> names = new ArrayList<String>();final ArrayList<ArrayList<String>> details= new ArrayList<ArrayList<String>>();// 使用ContentResolver查找联系人数据Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);// 遍历查询结果,获取系统中所有联系人while (cursor.moveToNext()){// 获取联系人IDString contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));// 获取联系人的名字String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));names.add(name);// 使用ContentResolver查找联系人的电话号码Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);ArrayList<String> detail = new ArrayList<String>();// 遍历查询结果,获取该联系人的多个电话号码while (phones.moveToNext()){// 获取查询结果中电话号码列中数据。String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));detail.add("电话号码:" + phoneNumber); }phones.close();// 使用ContentResolver查找联系人的Email地址Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,null,ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null);// 遍历查询结果,获取该联系人的多个Email地址while (emails.moveToNext()){// 获取查询结果中Email地址列中数据。String emailAddress = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));detail.add("邮件地址:" + emailAddress); }emails.close();details.add(detail);}cursor.close();//加载result.xml界面布局代表的视图View resultDialog = getLayoutInflater().inflate(R.layout.result, null);// 获取resultDialog中ID为list的ExpandableListViewExpandableListView list = (ExpandableListView)resultDialog.findViewById(R.id.list);//创建一个ExpandableListAdapter对象ExpandableListAdapter adapter = new BaseExpandableListAdapter(){//获取指定组位置、指定子列表项处的子列表项数据@Overridepublic Object getChild(int groupPosition, int childPosition){return details.get(groupPosition).get(childPosition);}@Overridepublic long getChildId(int groupPosition, int childPosition){return childPosition;}@Overridepublic int getChildrenCount(int groupPosition){return details.get(groupPosition).size();}private TextView getTextView(){AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, 64);TextView textView = new TextView(ContactProviderTest.this);textView.setLayoutParams(lp);textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);textView.setPadding(36, 0, 0, 0);textView.setTextSize(20);return textView;}// 该方法决定每个子选项的外观@Overridepublic View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent){TextView textView = getTextView();textView.setText(getChild(groupPosition, childPosition).toString());return textView;}//获取指定组位置处的组数据@Overridepublic Object getGroup(int groupPosition){return names.get(groupPosition);}@Overridepublic int getGroupCount(){return names.size();}@Overridepublic long getGroupId(int groupPosition){return groupPosition;}//该方法决定每个组选项的外观@Overridepublic View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent){TextView textView = getTextView();textView.setText(getGroup(groupPosition).toString());return textView;}@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition){return true;}@Overridepublic boolean hasStableIds(){return true;}};// 为ExpandableListView设置Adapter对象list.setAdapter(adapter);// 使用对话框来显示查询结果。new AlertDialog.Builder(ContactProviderTest.this).setView(resultDialog).setPositiveButton("确定" , null).show();}});// 为add按钮的单击事件绑定监听器add.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){// 获取程序界面中的3个文本框String name = ((EditText)findViewById(R.id.name)).getText().toString();String phone = ((EditText)findViewById(R.id.phone)).getText().toString();String email = ((EditText)findViewById(R.id.email)).getText().toString();// 创建一个空的ContentValuesContentValues values = new ContentValues();// 向RawContacts.CONTENT_URI执行一个空值插入,// 目的是获取系统返回的rawContactId Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values);long rawContactId = ContentUris.parseId(rawContactUri);values.clear();values.put(Data.RAW_CONTACT_ID, rawContactId); // 设置内容类型values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);// 设置联系人名字values.put(StructuredName.GIVEN_NAME, name);// 向联系人URI添加联系人名字getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);values.clear();values.put(Data.RAW_CONTACT_ID, rawContactId);values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);// 设置联系人的电话号码values.put(Phone.NUMBER, phone);// 设置电话类型values.put(Phone.TYPE, Phone.TYPE_MOBILE);// 向联系人电话号码URI添加电话号码getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);values.clear();values.put(Data.RAW_CONTACT_ID, rawContactId);values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);// 设置联系人的Email地址values.put(Email.DATA, email);// 设置该电子邮件的类型values.put(Email.TYPE, Email.TYPE_WORK);// 向联系人Email URI添加Email数据getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);Toast.makeText(ContactProviderTest.this, "联系人数据添加成功" , 8000).show();}});}}

 

main.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 android:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"><Button android:id="@+id/search"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/search"/><Button android:id="@+id/add"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/add"/></LinearLayout><TextView  android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/name"/><EditTextandroid:id="@+id/name"android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/input"/><TextView  android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/phone"/><EditTextandroid:id="@+id/phone"android:layout_width="fill_parent" android:layout_height="wrap_content" android:phoneNumber="true"android:hint="@string/input"/><TextView  android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/email"/><EditTextandroid:id="@+id/email"android:layout_width="fill_parent" android:layout_height="wrap_content"android:hint="@string/input"/></LinearLayout>

 

result.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"><ExpandableListViewandroid:id="@+id/list"android:layout_width="fill_parent" android:layout_height="wrap_content" android:childIndicator="@drawable/icon"/></LinearLayout>

 

前面是如何使用ContentResolver来操作系统的ContentProvider提供的数据。下面介绍如何开发自己的ContentProvider

 

4.1 创建ContentProvider的步骤

       开发一个ContentProvider子类,该子类需要实现增、删、改、查等方法。

       在AndroidManifest.xml文件中注册该ContentProvider

为了确定该ContentProvider实际能匹配的Uri,以及确定每个方法中Uri参数所操作的数据,Android系统中提供了UriMatcher工具类,提供了以下两个方法:

       void addURI(String quthority,String path,int code):该方法用于向UriMatcher对象注册Uri

       int match(Uri uri):根据前面注册的Uri来判断指定Uri对应的标识码。

 

实现ContentProvider

Android还提供了ContentUris工具类,它是一个Uri字符串的工具类,它提供了如下两个工具方法。

       withAppendedId(uri, id):用于为路径加上ID部分。

       parseId(uri):用于从指定Uri中解析出所包含的ID值。

 

 

监听ContentProvider的数据改变

       当ContentProvider将数据共享出来以后,ContentResolver会根据业务需要主动查询ContentProvider所共享数据;在有些时候,应用程序需要实时监听ContentProvider所共享数据的改变。并随着ContentProvider的数据改变而提供响应,这就需要利用ContentObserver了。

 

5.1 ContentObserver简介

ContentProvider 发生数据变化时,调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者

访问者使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserveronChange()方法 。

ContentResolver提供了如下方法来注册监听器:registerContentObserver(Uri uri,boolean notifyForDescendents , ContentObserver observer)

uri:该监听器所监听的ContentProviderUri

notifyForDescendents:如果该参数设为true,假如注册监听的Uricontent://abc,那么Uricontent://abc/xyz的数据改变时也会触发该监听器。如果该参数设为false,只有content://abc的数据发生改变时会触发该监听器。

observer:监听器实例。

 

例:监听发出的短信:

MonitorSms.java

public class MonitorSms extends Activity{@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);//为content://sms的数据改变注册监听器getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler()));}// 提供自定义的ContentObserver监听器类private final class SmsObserver extends ContentObserver{public SmsObserver(Handler handler){super(handler);}public void onChange(boolean selfChange){// 查询发送箱中的短信(处于正在发送状态的短信放在发送箱)Cursor cursor = getContentResolver().query(Uri.parse("content://sms/outbox"), null, null, null, null);// 遍历查询得到的结果集,即可获取用户正在发送的短信while (cursor.moveToNext()){StringBuilder sb = new StringBuilder();// 获取短信的发送地址sb.append("address=").append(cursor.getString(cursor.getColumnIndex("address")));// 获取短信的标题sb.append(";subject=").append(cursor.getString(cursor.getColumnIndex("subject")));// 获取短信的内容sb.append(";body=").append(cursor.getString(cursor.getColumnIndex("body")));// 获取短信的发送时间sb.append(";time=").append(cursor.getLong(cursor.getColumnIndex("date")));System.out.println("Has Sent SMS:::" + sb.toString());}}}}


注意添加权限:

<!-- 授予读联系人ContentProvider的权限 --><uses-permission android:name="android.permission.READ_SMS"/>



 

 

 

 

 

 

 

0 0
原创粉丝点击