版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
电话和短信应用程序开发第5章CONTENTS目录01
Intent02
拨号程序03
短信程序04
照相机程序05
综合实例-通讯录电话短信AppIntent015.1IntentIntent被译作“意图”,在Android中提供了Intent机制来协助应用间的交互与通信。Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”,专门提供组件互相调用的相关信息。Intent是对它要完成的动作的一种抽象描述,Intent封装了它要执行动作的属性:Action(动作)、Data(数据)、Category(类别)、Type(类型)、Component(组件信息)和Extras(附加信息)。
手机的基本功能是打电话和发短信。本章通过Intent的使用来介绍在Android系统下如何对电话和短信应用程序进行开发。通过Intent,程序员可以方便地将自己开发的应用程序与手机中的其他应用组件进行交互。1.Action
Action是指Intent要实施的动作,是一个字符串常量。如果指明了一个Action,执行者就会依照这个动作的指示,接收相关输入,表现对应行为,产生符合条件的输出。
在Intent类中定义了大量的Action常量属性,标准的ActivityActions如表5.1所示。
动作名称动作功能ACTION_MAIN
作为一个主要的进入口,而并不期望去接收数据
ACTION_VIEW
向用户显示数据ACTION_ATTACH_DATA用于指定一些数据应该附属于哪些地方,例如,图片数据应该附属于联系人ACTION_EDIT访问已给的数据,提供明确的可编辑接口ACTION_PICK从数据中选择一个子项目,并返回所选中的项目ACTION_CHOOSER显示一个Activity选择器,允许用户在进程之前选择他们想要的ACTION_GET_CONTENT允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)ACTION_DIAL拨打一个指定的号码,显示一个带有号码的用户界面,允许用户去启动呼叫ACTION_CALL根据指定的数据执行一次呼叫ACTION_SEND传递数据,被传送的数据没有指定ACTION_SENDTO发送一个信息到某个指定的人ACTION_ANSWER处理一个打进电话呼叫ACTION_INSERT插入一条空项目到已给的容器ACTION_DELETE从容器中删除已给的数据ACTION_RUN运行数据ACTION_SYNC同步执行一个数据ACTION_PICK_ACTIVITY为已知的Intent选择一个Activity,返回被选中的类ACTION_SEARCH执行一次搜索ACTION_WEB_SEARCH执行一次Web搜索ACTION_FACTORY_TEST工厂测试的主要进入点表5.1标准的ActivityActions2.DataIntent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。例如,通讯录中identifier为1的联系人的信息(一般以U形式描述),给这个人打电话的语句为:ACTION_VIEWcontent://contacts/1ACTION_DIALcontent://contacts/13.CategoryIntent中的Category属性起着对Action补充说明的作用。通过Action,配合Data或Type可以准确表达出一个完整的意图(加一些约束会更精准)。Intent中的Category属性用于执行Action的附加信息。例如,CATEGORY_LAUNCHER表示加载程序时Activity出现在最上面,_HOME表示回到Home界面。4.TypeIntent的Type属性显示指定Intent的数据类型(MIME)。通常Intent的数据类型可以从Data自身判断出来,但是一旦指定了Type类型,就会强制使用Type指定的类型而不再进行推导。6.Extra5.ComponentIntent的Compotent属性指定Intent的目标组件的类名称。通常情况下,Android会根据Intent中包含的其他属性的信息进行查找,比如用Action、Data、Type、Category去描述一个请求,这种模式称为ImplicitIntents。通过这种模式,提供一种灵活可扩展的模式,给用户和第三方应用一个选择权。例如,一个邮箱软件,大部分功能都不错,但是选择图片的功能不尽如人意,如果采用ImplicitIntents,那么它就是一个开放的体系,如果想用手机中的其他图片代替邮箱中默认的图片,可以完成这一功能。但该模式需要付出性能上的开销,因为毕竟存在一个检索过程。于是Android提供了另一种模式ExplicitIntents,该模式需要Component对象。Component就是完整的类名,形如com.xxxxx.xxxx,一旦指明就可以直接调用。根据该属性是否被指定,Intent可分为显式Intent和隐式Intent。Intent的Extra属性用于添加一些组件的附加信息。比如,要通过一个Activity执行“发送电子邮件”这个动作请求,可以将电子邮件的subject、body等保存在Extras里,传给电子邮件发送组件。5.1.1显式Intent和
隐式Intent
为了支持隐式Intent,可以声明一个甚至多个IntentFilter。每个IntentFilter描述组件所能响应Intent请求的能力。比如请求网页浏览器,网页浏览器程序的IntentFliter就应该声明它所希望接收的IntentFilterAction是WEB_SEARCH_ACTION,以及与之相关的请求数据是网页地址URI格式。
如何为组件声明自己的IntentFilter?常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的IntentFilter。
一个隐式Intent请求可以通过Action,Category和Data三个属性来确定能够传递到的目标组件,但是安卓系统要求至少要通过Action和Category两方面的检查。任何一方面不匹配,安卓系统都不会将该隐式Intent传递给目标组件。
一个隐式Intent要求必须设置一个Action属性,同时可以设置多个Category属性。如果没有为Intent对象设置Category属性,那么系统会添加一个值为“android.Intent.Category.DEFAULT”的Category。
Intent寻找目标组件的方式分为两种:显式Intent和隐式Intent。
显式Intent是通过指定Intent组件名称来实现的,它一般用在源组件已知目标组件名称的前提下,这种方式一般在应用程序内部实现。比如在某应用程序内,一个Activity启动一个Service。
在不同应用程序之间,在不知道目标组件名称的情况下,寻找目标组件需要使用隐式Intent。这种方式是通过IntentFilter实现的。
5.1.2IntentFilter1.动作测试<intent-Filter>元素中要求至少要包含一个子元素<action>,比如:<intent-Filter><actionandroid:name=“ject.SHOW-CURRENT”/><actionandroid:name=“ject.SHOW-RECENT”/><actionandroid:name=“ject.SHOW-PENDING”/></intent-Filter>一条<intent-Filter>元素至少包含一个<action>,否则任何Intent请求都不能和该<intent-Filter>匹配。如果Intent请求的Action和<intent-Filter>中的某一条<action>匹配,那么该Intent就通过了这条<intent-Filter>的动作测试。2.类别测试<intent-Filter>元素要求包含至少一个<category>子元素,比如:<intent-Filter><categoryandroid:name=“android.Intent.Category.DEFAULT”/><categoryandroid:name=“android.Intent.Category.BROWSABLE”/></intent-Filter>只有当Intent请求中所有的Category与组件的IntentFilter中同样数量的<catetory>完全匹配时,才会让该Intent请求通过测试,IntentFilter中多余的<category>声明并不会导致匹配失败。一个没有指定任何类别Intent请求与指定了“android.Intent.Category.DEFALT”类别的IntentFliter相匹配。3.数据测试
数据在<intent-Filter>中的描述如下:<intent-Filter><dataandroid:type=“video/mpeg”android:scheme=“http”……/><dataandroid:type=“audio/mpeg”android:scheme=“http”……/></intent-Filter><data>元素指定了要接受的Intent请求的数据URI及数据类型,其中URI被分成三部分来进行匹配:scheme、authority和path。用setData()设定的Intent请求的URI数据类型和scheme必须与IntentFilter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要匹配才会通过测试。拨号程序025.2拨
号
程
序
借助于Intent可以轻松实现拨打电话的应用程序。只需声明一个拨号的Intent对象,并使用startActivity()方法启动即可。创建Intent对象的代码为Intentintent=newIntent(action,uri),其中URI是要拨叫的号码数据,通过Uri.parse()方法把“tel:1234”格式的字符串转换为URI。而Action有两种使用方式:一种是Intent.Action_CALL,直接进行呼叫的方式,这种方式需要应用程序具有android.permission.CALL_PHONE权限;另一种是Intent.Action_DIAL,这种不是不直接进行呼叫,而是启动Android系统的拨号应用程序,然后由用户进行拨号。这种方式不需要任何权限的设置。实例phoneDemo演示了使用Intent.Action_CALL方式进行拨号的过程,运行效果如图5.1所示。图5.1使用Intent.Action_CALL方式拨号
<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><EditTextandroid:layout_marginTop="30dp"android:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/edittext"android:layout_marginLeft="40dp"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拨打电话"android:id="@+id/button"android:layout_marginLeft="80dp"android:layout_marginTop="40dp"/></LinearLayout>实例phoneDemo中main.xml的代码如下:
实例phoneDemo中AndroidManifest.xml的代码如下:<?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="/apk/res/android"xmlns:tools="/tools"><uses-featureandroid:name="android.hardware.telephony"android:required="false"/><uses-permissionandroid:name="android.permission.CALL_PHONE"></uses-permission><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.PhoneDemo"tools:targetApi="36"><activityandroid:name=".PhoneDemoActivity"android:exported="true"android:label="@string/app_name"><intent-filter><actionandroid:name="ent.action.MAIN"/><categoryandroid:name="ent.category.LAUNCHER"/></intent-filter></activity></application></manifest>
其中<uses-featureandroid:name="android.hardware.telephony"android:required="false"/><uses-permissionandroid:name="android.permission.CALL_PHONE"></uses-permission>用于声明使用手机的电话权限。但是从APILEVEL23开始,安卓改为动态权限申请,因此需要在PhoneDemoActivity中动态申请打电话权限。实例phoneDemo中PhoneDemoActivity.java的具体实现代码如下:packageroduction.phonedemo;importandroid.Manifest;importandroid.app.Activity;importandroid.content.Intent;importandroid.content.pm.PackageManager;import.Uri;importandroid.os.Bundle;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.EditText;importandroid.widget.Toast;importandroidx.core.app.ActivityCompat;importandroidx.core.content.ContextCompat;publicclassPhoneDemoActivityextendsActivity{privateButtonbutton; privateEditTextedittext;privatestaticfinalintREQUEST_CALL_PHONE=1;@Override
publicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);button=(Button)findViewById(R.id.button);button.setOnClickListener(newbuttonListener());if(ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.CALL_PHONE},REQUEST_CALL_PHONE);}}//打电话权限回调处理@OverridepublicvoidonRequestPermissionsResult(intrequestCode,String[]permissions,int[]grantResults){super.onRequestPermissionsResult(requestCode,permissions,grantResults);if(requestCode==REQUEST_CALL_PHONE){if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){//权限已授予
}else{//权限被拒绝Toast.makeText(this,"电话权限被拒绝",Toast.LENGTH_SHORT).show();}}}classbuttonListenerimplementsOnClickListener{ @Override publicvoidonClick(Viewv){ //TODOAuto-generatedmethodstub edittext=(EditText)findViewById(R.id.edittext);Stringnumber=edittext.getText().toString();Intentintent=newIntent(Intent.ACTION_CALL,Uri.parse("tel:"+number));startActivity(intent); }}}其中:Intentintent=newIntent(Intent.ACTION_CALL,Uri.parse("tel:"+number));startActivity(intent);通过Intent.ACTION_CALL建立了一个进行拨号的Intent请求,并使用startActivity直接启动Android系统的拨号程序进行呼叫。if(ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.CALL_PHONE},REQUEST_CALL_PHONE);}即为动态权限申请代码。若在实例PhoneDemo中,将PhoneDemoActivity.java中的代码:Intentintent=newIntent(Intent.ACTION_CALL,Uri.parse("tel:"+number));修改为:Intentintent=newIntent(Intent.ACTION_DIAL,Uri.parse("tel:"+number));最后,单击“拨打电话”按钮后不再直接呼叫,而是只运行Android系统默认的拨号程序,用户还拥有进一步决定下一步操作的权限,运行效果如图5.2所示。图5.2
拨打电话短信程序035.3短
信
程
序
5.3.1SMS简介SMS(ShortMessageService,短信息服务)是一种存储和转发服务。也就是说,短信息并不是直接从发信人发送到接收人,而是始终通过SMS中心进行转发。如果接收人处于未连接状态(可能电话已关闭),那么信息将在接收人再次连接时发送。
5.3.2接收短信要使Android应用程序能够接收短信息,需要以下三个步骤: Android应用程序必须具有接收SMS短信息的权限,在AndroidManifest.xml文件中配置如下:<uses-permissionandroid:name="android.permission.RECEIVE_SMS"/> Android应用程序需要定义一个BroadcastReceiver的子类,并通过重载其publicvoidonReceive(Contextarg0,Intentarg1)方法来处理接收到短信息的事件。
在AndroidManifest.xml文件中对BroadcastReceiver子类的<intent-filter>属性进行配置,使其能够获取短信息接收Action。配置如下:<intent-filter><actionandroid:name="vider.Telephony.SMS_RECEIVED"/></intent-filter>
5.3.3接收短信实例实例receiveMessageDemo演示了接收短信并提示的过程,运行效果如图5.3所示。其layout文件main.xml的代码如下:图5.3
receiveMessageDemo实例
<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><EditTextandroid:id="@+id/editText1"android:layout_width="match_parent"android:layout_height="wrap_content"><requestFocus/></EditText></LinearLayout>
AndroidManifest.xml文件的代码如下:<?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="/apk/res/android"xmlns:tools="/tools"><uses-featureandroid:name="android.hardware.telephony"android:required="false"/><uses-permissionandroid:name="android.permission.RECEIVE_SMS"/><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.ReceiveMessageDemo"tools:targetApi="36"><activityandroid:name=".ReceiveMessageDemoActivity"android:exported="true"android:label="@string/app_name"><intent-filter><actionandroid:name="ent.action.MAIN"/><categoryandroid:name="ent.category.LAUNCHER"/></intent-filter></activity><receiverandroid:name="SmsReciver"android:exported="true"><intent-filter><actionandroid:name="vider.Telephony.SMS_RECEIVED"/></intent-filter></receiver></application></manifest>
ReceiveMessageDemoActivity.java用于动态申请权限,显示接收到的短信信息。代码如下:packageroduction.receivemessagedemo;importandroid.app.Activity;importandroid.os.Bundle;importandroid.widget.EditText;importandroid.Manifest;importandroid.content.pm.PackageManager;importandroidx.core.app.ActivityCompat;importandroidx.core.content.ContextCompat;publicclassReceiveMessageDemoActivityextendsActivity{privatestaticfinalintSMS_PERMISSION_REQUEST_CODE=100;/**Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);EditTexttext=(EditText)this.findViewById(R.id.editText1);text.setText("waiting...");
checkAndRequestSmsPermission();}privatevoidcheckAndRequestSmsPermission(){if(ContextCompat.checkSelfPermission(this,Manifest.permission.RECEIVE_SMS)!=PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.RECEIVE_SMS},SMS_PERMISSION_REQUEST_CODE);}}
@OverridepublicvoidonRequestPermissionsResult(intrequestCode,String[]permissions,int[]grantResults){super.onRequestPermissionsResult(requestCode,permissions,grantResults);if(requestCode==SMS_PERMISSION_REQUEST_CODE){if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){//权限已授予}else{//权限被拒绝}}}}
Intent广播接收器定义为SmsReceiver,用于对接收到短信息的事件进行处理。SmsReceiver.Java的代码如下:packageroduction.receivemessagedemo;importandroid.content.BroadcastReceiver;importandroid.content.Context;importandroid.content.Intent;importandroid.os.Bundle;importandroid.telephony.SmsMessage;importandroid.widget.Toast;publicclassSmsReciverextendsBroadcastReceiver{ StringBuilderstrb=newStringBuilder(); @Override publicvoidonReceive(Contextarg0,Intentarg1){ //TODOAuto-generatedmethodstub Bundlebundle=arg1.getExtras();if(bundle==null)return;Object[]pdus=(Object[])bundle.get("pdus");if(pdus==null||pdus.length==0)return;
SmsMessage[]msgs=newSmsMessage[pdus.length];Stringformat=bundle.getString("format");for(inti=0;i<pdus.length;i++){ msgs[i]=SmsMessage.createFromPdu((byte[])pdus[i],format);} for(SmsMessagemsg:msgs){ strb.append("发信人:\n"); strb.append(msg.getDisplayOriginatingAddress()); strb.append("\n信息内容:\n"); strb.append(msg.getDisplayMessageBody()); } Toast.makeText(arg0,strb.toString(),Toast.LENGTH_LONG).show()}}当接收到短信息后,onReceive方法被调用。由于Android设备接收到的SMS短信息是PDU(ProtocolDescriptionUnit)形式的,因此通过Bundle类对象获取到PDUS,并创建SmsMessage对象。然后从SmsMessage对象中提取出短信息的相关信息,并存储到StringBuilder类的对象中,最后使用Toast显示出来。测试该实例时,可通过AVDMananger,再启动一个AVD,通过AVD的短信程序向当前AVD号码发送短信,就可使该实例被触发运行。
5.3.4发送短信要实现发送短信功能,需要在AndroidManifest.xml文件中注册发送短信的权限:<uses-permissionandroid:name="android.permission.SEND_SMS"/>,然后才可以使用发送短信功能。发送短信使用的是android.telephony.SmsManager类的sendTextMessage方法,该方法定义如下:publicvoidsendTextMessage(StringdestinationAddress,StringscAddress,Stringtext,PendingIntentsentIntent,PendingIntentdeliveryIntent)其中,各个参数的意义如下。
destinationAddress:表示接收短信的手机号码。
scAddress:短信服务中心号码,设置为null表示使用手机默认的短信服务中心。
text:要发送的短信内容。
sentIntent:当消息被成功发送给接收者时,广播该PendingIntent。
deliveryIntent:当消息被成功发送时,广播该PendingIntent。
5.3.5短信发送实例实例sendMessageDemo演示了发送短信的过程,其运行效果如图5.4所示。图5.4
sendMessageDemo实例
在实例sendMessageDemo中,main.xml的代码如下:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/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:id="@+id/textview01"android:text="@string/receiver"android:layout_marginLeft="15dp"/><EditTextandroid:layout_marginLeft="20dp"android:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/edittext01"android:inputType="number"/></LinearLayout><LinearLayoutandroid:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginTop="30dp">
<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/textview02"android:text="@string/msg"android:layout_marginLeft="15dp"/><EditTextandroid:layout_marginLeft="10dp"android:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/edittext02"/></LinearLayout><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/button"android:layout_marginLeft="100dp"android:layout_marginTop="30dp"android:text="点击发送"/></LinearLayout>
在实例sendMessageDemo中,AndroidManifest.xml的代码如下:<?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="/apk/res/android"xmlns:tools="/tools"><uses-featureandroid:name="android.hardware.telephony"android:required="false"/><uses-permissionandroid:name="android.permission.SEND_SMS"/><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar"tools:targetApi="31"><activityandroid:name=".SendMessageDemoActivity"android:exported="true"android:label="@string/app_name"><intent-filter><actionandroid:name="ent.action.MAIN"/><categoryandroid:name="ent.category.LAUNCHER"/></intent-filter></activity></application></manifest>
在实例sendMessageDemo中,SendMessageDemoActivity.java实
现了发送短信的功能,其代码如下:packageroduction.sendmessagedemo;importandroid.app.Activity;importandroid.os.Bundle;importandroid.telephony.SmsManager;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.EditText;importandroid.widget.Toast;importandroid.Manifest;importandroid.content.pm.PackageManager;importandroidx.core.app.ActivityCompat;importandroidx.core.content.ContextCompat;publicclassSendMessageDemoActivityextendsActivity{ /**Calledwhentheactivityisfirstcreated.*/ privateButtonbutton; privateEditTextedittext01,edittext02; privatestaticfinalintSMS_PERMISSION_REQUEST_CODE=100;
@Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); button=(Button)findViewById(R.id.button); button.setOnClickListener(newbuttonListener());//为发送按钮添加监听器
//检查并请求短信权限 if(ContextCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS) !=PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(this, newString[]{Manifest.permission.SEND_SMS}, SMS_PERMISSION_REQUEST_CODE); } } classbuttonListenerimplementsOnClickListener{ @Override publicvoidonClick(Viewv){ //TODOAuto-generatedmethodstub edittext01=(EditText)findViewById(R.id.edittext01); edittext02=(EditText)findViewById(R.id.edittext02); Stringnumber=edittext01.getText().toString();//获取手机号码 Stringmessage01=edittext02.getText().toString();//获取短信内容 if(number.equals("")||message01.equals(""))//判输入是否有空内容 { Toast.makeText(SendMessageDemoActivity.this,"输入有误,请检查输入",Toast.LENGTH_LONG).show(); } else{ if(ContextCompat.checkSelfPermission(SendMessageDemoActivity.this, Manifest.permission.SEND_SMS)==PackageManager.PERMISSION_GRANTED){ SmsManagersmsManager=getSystemService(SmsManager.class); smsManager.sendTextMessage(number,null,message01,null,null); Toast.makeText(SendMessageDemoActivity.this,"短信发送成功",
Toast.LENGTH_LONG).show(); }else{ Toast.makeText(SendMessageDemoActivity.this,"请先授予短信发送权限",Toast.LENGTH_LONG).show(); } } } }
@Override publicvoidonRequestPermissionsResult(intrequestCode,String[]permissions,int[]grantResults){ super.onRequestPermissionsResult(requestCode,permissions,grantResults); if(requestCode==SMS_PERMISSION_REQUEST_CODE){ if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){ Toast.makeText(this,"短信权限已授予",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this,"短信权限被拒绝,无法发送短信",Toast.LENGTH_SHORT).show(); } } }}在实际应用该短信发送程序时,要注意一些限制问题,比如接收手机号码的格式、短信内容超过预定字符的提示等。一般情况下,手机号码格式可以使用Pattern来设置,此外AndroidSDK提供了PhoneNumberUtils类来对电话号码格式进行处理,而短信内容超过70个字符会被自动分解为多条短信发送,在此不做具体描述。照相机程序045.4照相机程序
借助于Intent,可以方便地调用Android系统的照相机程序进行拍照,且不需要申请摄像头的使用权限。
实例CameraDemo演示了通过Intent调用系统的拍照程序并返回照片的过程,该实例运行效果如图5.5所示。
当单击“启动摄像头”按钮时,启动Android系统自带的照相机应用程序进行拍照,并将拍摄的照片显示到ImageView组件中。实例CameraDemo中的main.xml代码如下:图5.5
CameraDemo实例运行效果<?xmlversion="1.0"encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:id="@+id/linearLayout"android:layout_width="fill_parent"android:layout_height="fill_parent"><Buttonandroid:id="@+id/button1"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginTop="50dp"android:text="@string/camera"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><ImageViewandroid:id="@+id/imageview"android:layout_width="383dp"android:layout_height="443dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.571"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/button1"app:layout_constraintVertical_bias="0.178"/></androidx.constraintlayout.widget.ConstraintLayout>
<?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="/apk/res/android"xmlns:tools="/tools">
<applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.CameraDemo"tools:targetApi="36"><activityandroid:name=".CameraDemoActivity"android:exported="true"android:label="@string/app_name"><intent-filter><actionandroid:name="ent.action.MAIN"/><categoryandroid:name="ent.category.LAUNCHER"/></intent-filter></activity></application></manifest>在实例CameraDemo中的AndroidManifest.xml代码如下:在实例CameraDemo中的CameraDemoActivity.java代码如下:
packageroduction.camerademo;importandroid.app.Activity;importandroid.content.Intent;importandroid.graphics.Bitmap;importandroid.os.Bundle;importvider.MediaStore;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.ImageView;publicclassCameraDemoActivityextendsActivity{ /**Calledwhentheactivityisfirstcreated.*/ privateImageViewimageview; privateButtonbtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); imageview=(ImageView)findViewById(R.id.imageview); btn=(Button)findViewById(R.id.button1); btn.setOnClickListener(newOnClickListener(){
@Override publicvoidonClick(Viewv){ //TODOAuto-generatedmethodstub try{ Intenti=newIntent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(i,1); } catch(Exceptione){ } } }); } protectedvoidonActivityResult(intrequestcode,intresultCode,Intentdata){ try{ if(requestcode!=1){ return; } super.onActivityResult(requestcode,resultCode,data); Bundleextras=data.getExtras(); Bitmapbitmap=(Bitmap)extras.get("data"); imageview.setImageBitmap(bitmap); } catch(Exceptione){ } }}在启动摄像头程序时,因为要传回拍摄的图像,所以调用了Activity.startActivityForResult(Intentintent,intrequestCode)方法。当startActivityForResult()方法启动的Activity正常结束时,会自动返回发出请求的Activity,并且该方法会返回对应的requestCode值给onActivityResult(intrequestcode,intresultCode,Intentdata)方法,借此可以在请求Activity和发出请求的Activity之间进行数据传递。本实例借助于这一特点传回了Android系统照相机程序拍摄的照片。综合实例-通讯录电话信息APP055.5综合实例-通讯录电话短信App本章开发了一个从通讯录进行打电话和发短信的综合实例PhoneAndMsgDemo。运行程序,启动页面如图5.6所示。单击“打开通讯录”按键,会读取手机的通讯录信息显示在新界面里,如图5.7所示。这里要求手机的通讯录里面有联系人的姓名和电话。如果AVD里面没有,请读者自行添加。图5.6启动页面
图5.7读取通讯录单击通讯录中的任意一条人员信息,弹出contexmenu菜单,显示相关功能,如图5.8所示。选择“复制号码”选项,会把联系人的号码复制进剪贴板。选择“打电话”选项,弹出动态权限申请菜单,用户授权后才能使用打电话和发短信等相关功能。图5.8功能菜单
图5.9动态权限申请图5.10打电话功能
图5.11发短信功能
该实例的AndroidManifest.xml文件内容如下:<?xmlversion=
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 山东东营市垦利区2025-2026学年五年级下学期期末语文试题(文字版含答案)
- 福建省厦门市集小片区2025-2026学年三年级上学期期末语文试题(文字版含答案)
- 2026年自来水公司水费分类出纳内勤招聘考试笔试试题(含答案)
- 2026年烟草物流调度半年度台账专员烟草公司招聘考试笔试试题(含答案)
- 新版教科版艺术音乐六年级下册教案
- 业务员个人工作总结800字范文5篇
- 气溶胶光学厚度
- 2026 年重型颅脑损伤 ICU 护理个案分享
- 2026 年肺结核大咯血窒息应急抢救护理个案
- 2026年秋季初中数学开学第一课 新学期学习规划课件
- 2026年云南省基层法律服务考试真题及答案
- 2027创新设计一轮生物第14讲 减数分裂和受精作用
- 2026年宁夏惠安市政产业有限公司公开招聘工作人员考试参考题库及答案详解
- 仪陇县2026年数学四年级第二学期期末检测模拟试题含解析
- 2026年天津高考(英语)考试试卷真题(含答案)
- 2026年6月大学英语四级考试真题(第3套)附答案解析
- 信息管理岗位笔试题国企及答案
- 2026年高考真题-语文(全国二卷) 含解析
- 2026年江苏省初级注册安全工程师考试真题及答案
- 兽医实验室管理制度
- 临床腹腔内压力经膀胱间接测量技术解读及实践经验共享
评论
0/150
提交评论