转载请注明http://www.cnblogs.com/devtrees/p/4405519.html

一.创建第一个应用HelloWorld

(一)创建步骤:

1.New出一个Android Application Project

三种方式

1):

2):

3):

 

2.会出现下图的窗口:

 

分别是:应用名:给用户看的

        工程名:开发工具中显示的项目名

        包名: 客户端中设置->应用->应用列表中显示的名字

        兼容的最低版本:

        兼容的最高版本:

        开发基于的版本:(一般将兼容的最高版本和开发所基于的版本设为一样)

        样式: 默认即可(点Next)

3.进入下图:

 

分别是:创建一个自定义的图标(要勾选)

        创建一个活动(目前理解为一个界面即可)(要勾选)

        默认在以下工作空间创建此工程项目(勾选)

        提供一个jar包工程供别人调用(一般不勾选)

        (学习期间基本上这一页和后面几页都是默认即可)

4.点Next,跳转到下一页,见下图:

 

上一页你默认勾选了创建一个应用图标,那么这一页就是对图标的设置,你可以对图标要选择的图片、大小、颜色、背景色、形状等进行设置,完成后Next。学习期间,一般是默认直接Next.

 

5.上上一页,你勾选了创建一个应用界面,那么这一页就是对界面的样式进行设置,学习期间一般是默认,完成后Next。

 

 

这一页是对你设置好的界面进一步进行设置,一般情况下为默认:

        界面名称:即在预览图中,那个波浪线的位置,显示当前界面的名称

        布局名称:设置好后,会生成相应名称的xml文件,用于对当前页面的布局设置。

        点击Finish。你的第一个Android工程就创建好了!见下图,进入工程默认界面

 

(二)工程目录结构(重点)

项目我们已经创建好了,那么我们应该开始大显身手的编程了,但是不要急,先让我们来了解Android工程的目录结构

1.src:是我们程序员要编写的android程序的源代码,它和java中的src一样,在这里我们可    以创建包,类等。

2.gen:注意旁边的文字:Generated java Files. 这是Android系统自动生成的文件,我们不要         改动它(一般情况下也改动不了)。gen 目录中存放所有由Android开发工具自动        生成的文 件 。目录中最重要的就是R.java文件。 这个文件由Android开发工具        自动产生的。Android 开发工具会自动根据你放入res目录的资源,同步更新修改        R.java文件。正因为R.java文件是由开发工具自动生成的,所以我们应避免手工修        改R.java。R.java在应用中起到了字典的 作用,它包含了各种资源的id,通过R.java,        应用可以很方便地找到对应资源。另外编绎器 也会检查R.java列表中的资源是否        被使用到,没有被使用到的资源不会编绎进软件中,这样 可以减少应用在        手机占用的空间。这里边包含了:

        BuildConfig.java 这里边只有一行代码

                public final static boolean DEBUG = true;是指默认情况下,我们创建的应用                程序是可以做Debug调试的。

        R.java 见下图

 

        这R.java文件中有很多静态内部类,我们程序中的一些资源文件在编译过程中会生        成id,R.java文件的作用就是产生id值,好让我们的程序去调用,找到资源。并且        R.java中的信息会随着程序资源的改变而自动改变。

3.Android X.X:应用程序开发所需的核心jar包

4.Android Dependencies:应用程序开发所需的扩展jar包

5.assets: 资产目录

        Android除了提供/res目录存放资源文件外,在/assets目录也可以存放资产文件,        而且/assets目录下的资源文件不会在R.java自动生成ID,即不会被编译,目录中            的所有文件将会被打包到应用程序的apk中。所以读取/assets目录下的文件必须        指定文件的路径,如:file:///android_asset/xxx.3gp

6.bin:编译出来的结果文件目录

7.libs:支持库目录

程序开发时需要的一些三方的jar包可以放在这个目录,系统会自动把里面的jar包,    添加到环境变量.其中默认会有一个支持jar包,是在高版本的API向下兼容低版本API    时所用的。

8.res:资源(Resource)目录

    在这个目录中我们可以存放应用使用到的各种资源,如xml界面文件,图片或数据。

    示例:1).我们可以在res/目录下存放应用程序的图标

    Drawable-hdpi/ 高分辨率

    Drawable-ldpi/ 低分辨率

    Drawable-mdpi/ 中等分辨率

    Drawable-xhdpi/ 特高分辨率

    Drawable-xxhdpi/ 超高分辨率

        2).layout/ 可以在预览选项卡上选择模拟器进行预览(可翻转)

            这里面有activity_main.xml文件,打开,可以看到下图:

        这其中还有几行代码,在这里简单介绍一下:

        CenterHorizontal:水平方向居中

        CenterVertical:垂直方向居中

        android:text="@string/hello_world

        @代表R.java文件

        String代表R.java文件中String的内部类

        Hello_world代表R.java文件中String内部类中所定义的常量id值。

    扩展阅读:

        res/drawable 专门存放png、jpg等图标文件。在代码中使用                        getResources().getDrawable(resourceId)获取该目录下的资源。

        res/layout 专门存放xml界面文件,xml界面文件和HTML文件一样,主要用于显        示用户操作界面。

        res/values 专门存放应用使用到的各种类型数据。不同类型的数据存放在不同的文        件中,如下:

        · strings.xml 定义字符串和数值,在Activity中使用                                getResources().getString(resourceId) 或getResources().getText(resourceId)取得资源。

        它的作用和struts中的国际化资源文件一样。

        <?xml version="1.0" encoding="UTF-8"?>

        <resources>

         <string name="itcast">传智播客</string>

        </resources>

        

        · arrays.xml 定义数组。

        <?xml version="1.0" encoding="utf-8"?>

        <resources>

        <string-array name="colors">

        <item>red</item>

        <item>yellow</item>

        <item>green</item>

        <item>blue</item>

        </string-array>

        </resources>

 

        · colors.xml 定义颜色和颜色字串数值,你可以在Activity中使用                    getResources().getDrawable(resourceId) 以及getResources().getColor(resourceId)取        得这些资源。例子如下:

    <?xml version="1.0" encoding="UTF-8"?>

        <resources>

         <color name="contents_text">#ff0000</color>

        </resources>

 

        · dimens.xml 定义尺寸数据,在Activity中使用                                    getResources().getDimension(resourceId) 取得这些资源

    <?xml version="1.0" encoding="UTF-8"?>

        <resources>

        <dimen name="key_height">50dip</dimen>

        </resources>

 

        · styles.xml 定义样式。

        <?xml version="1.0" encoding="utf-8"?>

        <resources>

        <style name="itcastText" parent="@style/Text">

        <item name="android:textSize">18sp</item>

        <item name="android:textColor">#0066FF</item>

        </style>

        </resources>

 

        res/anim/ 存放定义动画的XML文件。

        res/xml/ 在Activity中使用getResources().getXML()读取该目录下的XML资源文件。

        res/raw/ 该目录用于存放应用使用到的原始文件,如音效文件等。编译软件时,这        些数据不会被编译,它们被直接加入到程序安装包里。 为了在程序中使用这些资        源,你可以调用getResources().openRawResource(ID) , 参数ID形式:                    R.raw.somefilename。

9.AndroidManifest.xml 项目清单文件

    这个文件列出了应用程序所提供的功能,以后你开发好的各种组件需要在该文件中进行    配置,如果应用使用到了系统内置的应用(如电话服务、互联网服务、短信服务、GPS服    务等等),你还需在该文件中声明使用权限。

        package="com.example.copypic" 包名,应用程序在系统中的唯一标识;

        <uses-sdk/>应用兼容API的最高和最低版本(高于最高可用,低于最低不可用)。

        <application>应用程序配置信息

            android:label="@string/app_name"应用程序的名称(给用户看的那个)

            <activity>标签中也有一个android:label="@string/app_name"它显示的是当前            界面的名称。

            <intent-filter>在桌面显示图标

10. project.properties: 项目环境信息,一般是不需要修改此文件,这里只有一行代码:

        target=android-X 意为编译基于哪个API版本开发的,将数字更改,可降低或提高        API版本,这是一种改法,还有一种:右键点击相应的工程名,选择最后一个选项        Properties.弹出窗口,左边列表里选择Android,在右边的Project Build Target中选择        相应的版本。

setContentView(R.layout.activity_main);

设置内容的view对象

一般设置布局的xml文件的命名是与相对应的显示界面的java文件名反过来的,例如:

MainActivity.java对应activity_main

ShowActivity.java对应activity_show

如上图所示,当把Project选项中的Build Automatically勾选上时,eclipse会自动帮我们把.java文件编译成.class文件。(可在工作空间查看,其中$代表内部类)

调用da.bat文件将.class文件转化成.dex文件

将所有资源(图片,音乐等)与清单文件打包生成.apk文件。

其中有这样一个文件夹也被打包到里面,是META-INF文件夹(META代表源数据),这里面有三个文件,其中有个叫CERT.RSA的文件,是签名文件。

然后是签名,只有签名后,应用程序才能被装到手机上。

在用eclipse将应用安装到模拟器上的时候,也会用到签名,在c:\Document and Setting\当前用户\.android\debug.keystore部署apk文件的过程: IDE判断adb是不是正在工作,用adb把apk文件上传到模拟上,模拟器安装apk文件,开启应用软件。

#13.Android的打包过程

是把Android的应用程序打包成一个.apk文件,.apk文件可以安装在手机或者模拟器上。

如果是签名打包,是在打包的过程中,对文件进行了加密。 投放到Android市场上的应用软件必须签名。

    开发项目的步骤:

    

    1、理解需求,弄明白需求后在写代码;

2、在Android工程中设计UI界面;

3、代码实现业务逻辑;

l两个小案例:

1电话拨号器

我们发现当我们新建成完一个工程时,eclipse默认给我们展示的窗口是我们想要创建程序的样式,而不是代码窗口。Android所有的界面展示(窗口、图标、动画、图片、文字等等)都是基于xml中定义的。(当然,代码里也是可以动态配置的,这个以后我们在涉及。)所以,我们要向创建出一个电话拨号器的界面,就需要配置xml文件。

android系统中,应用程序界面中所展示的所有东西(包括图标、按键、图片、文字等等)统统都叫"view",或者叫组件或者控件,并且会按照一定的分类,赋予各自的名字,比如说,显示的文字,就叫textview,图片或者图标就叫imageview等等。而这些文字、图片等等这些组件我们有时会把它这样处理:这些文字图片放一起,那些文字图片放在一起。那如何区分呢?就诞生了父控件这一说法,叫layout,和view相同,根据不同的分类有不同的layout,layout之间是可以相互嵌套的,而view不可以。一个具体的view或者一个具体的layout都是具体的java类。

 

那么咱们当前这个电话拨号器的应用的界面是这样的。

那么咱们当前这个电话拨号器的应用的xml文件的代码是这样的。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 4 
 5 android:layout_width="fill_parent"
 6 
 7 android:layout_height="fill_parent"
 8 
 9 android:orientation="vertical">
10 
11 <EditText
12 
13 android:layout_width="fill_parent"
14 
15 android:layout_height="wrap_content"
16 
17 android:id="@+id/ddddd"
18 
19 android:text="Hello World, MyActivity"
20 
21 android:inputType="phone">
22 
23 <requestFocus/>
24 
25 </EditText>
26 
27 <Button android:layout_width="wrap_content"
28 
29 android:layout_height="wrap_content"
30 
31 android:id="@+id/eeeeee"
32 
33 android:text="打电话的按钮"/>
34 
35 </LinearLayout>

 

<?xml version="1.0" encoding="utf-8"?>表示xml文件的版本和编码,是任何xml文件都有的。

xmlns:android=http://schemas.android.com/apk/res/android代表命名空间,我们以后也可以自定义命名空间。

LinearLayout是我们上文提到的viewgroup子类中的一种布局layout,叫线性布局,我们稍后会讲到它,是经常用到的一种布局。android:orientation="vertical"属性代表垂直排列,这个我们后面也会讲到。并且在这个xml文件中,它是作为根节点出现的。

EditText和上文提到的textview,imageview一样,是一种具体的view,叫文本输入框。在里面我们可以输入数字、英文、汉字、不可见的密码形式文字等等。

Button也是一样,也是个view。是按钮。当我们按下时,它就会按照我们设定的执行某些代码,做出某些动作。

这里我们来说一下三者共有的属性:

android:layout_width="fill_parent"指定在父窗体内的宽

android:layout_height="wrap_content"指定在父窗体内的高

android中,view组建是没有自己的宽和高的,都是相对于父窗体(上一级节点)来说的宽和高。同时,宽和高有相同的三个属性:

Fill_parent:充满父窗体,将父窗体占满

Match_parent:也是与父窗体对其,将父窗体占满,2.3版本以后出现,谷歌觉得fill_parent不够形象。两者任选其一,都可使用。

Wrap_parent:包裹内容,依照里面内容的大小多少而定宽高。

宽和高这两个属性凡是view或layout就都需要指定。

下面我们再来说一下,三者非必需有的,但开发中常用到的属性:

android:text="xxxxxxxxxxxxx"用于组件显示的文本,在双引号内填入什么,在应用程序中我们就会看到什么。这个属性有的组件有,有的没有。有一点需要注意:文本内容不推荐在xml文件中写死,可以将文本内容写在String文件中,方便国际化使用。选定文本内容eclipse按ctrl+1,弹出对话框,输入string的名字即可。

android:id="@+id/xxxxx "表示组件在R文件中的id或者是在xml中的名字。@代表R文件,+号代表在R文件中添加或创建一个id,id/代表id是,后面就是你所创建的id名,随你起。但为了开发方便,最好遵循"什么组件_干什么用"这样命名。名字之前的是固定写法,不要丢掉东西。如果你的java代码里需要对这个控件进行操作,那么就需要声明这个id属性,因为代码是通过id名来找到控件的,或者如果你的xml文件中需要声明这个组件与其他组件或父控件在布局上的相对位置,也需要声明id。

这样,布局这一块我们就讲完了,接下来我们看代码部分

代码部分

 1 public class MyActivity extends Activity {
 2 
 3 /**
 4 
 5 * Called when the activity is first created.
 6 
 7 */
 8 
 9     @Override
10 
11    public void onCreate(Bundle savedInstanceState) {
12 
13       super.onCreate(savedInstanceState);
14 
15       setContentView(R.layout.main);
16 
17     }
18 
19 }

 

代码一上来不是空的,IDE已经帮我们创建了一个类继承了activity,并且创建了一个onCreate()方法里面有句代码:

setContentView(R.layout.main);

这句代码的作用是用来加载布局用的。但仅仅有这些代码是不够的,我们还需要实现我们的功能:打电话。

前面的需求已经说了,布局里有个文本输入框,用来输入电话号码,有个按钮,我们一按按钮就能够打电话。那么到这里我们的步骤就变成了:

1.将文本输入框里的内容获取出来

2.按键能够打电话。

那我想要获取这个输入框的内容,我们首先应该获取或者说找这个输入框。同理,按钮我们要想响应它的点击事件,也需要先找到按钮。

Android有一个方法可以让我们快速的找到组件:

findViewById();根据在xml文件中定义好的id寻找组件。这个寻找方式是以二叉树的形式去寻找。这个方法是context对象的方法,所以在activity中我们不需要用这个ontext对象去调用,直接写就可以,因为activity就是继承context。这个方法返回的是一个view对象。但我们开发中一般都将其强转成我们具体的view对象。把父类类型转换成子类类型。例如:

Button btCall = (Button)findViewById(R.id.eeeeee);

那么按钮找到了,按钮是需要点击的,我们就需要给按钮加一个对点击事件的处理代码:

Android有一种监听事件,叫点击监听事件,它可以对任何view或者layout进行附加,只要你给这个组件设置了这个点击监听事件,这个组件就和button一样,是可点击的。同样,button也具有这样的。

btCall.setOnClickListener();

看源码,这个方法里需要传入OnClickListener类型的参数

 1 public void setOnClickListener(OnClickListener l) {
 2 
 3     if (!isClickable()) {
 4 
 5         setClickable(true);
 6 
 7     }
 8 
 9     getListenerInfo().mOnClickListener = l;
10 
11 }

 

我们再点击这个OnClickListener,

 1 public interface OnClickListener {
 2 
 3     /**
 4 
 5     * Called when a view has been clicked.
 6 
 7     *
 8 
 9     * @param v The view that was clicked.
10 
11     */
12 
13     void onClick(View v);
14 
15 }

 

发现它其实是一个接口,那接口我们都知道,必须用子类去实现。所以setOnClickListener()这个括号里我们实际上需要传入的是一个类,或者直接点,叫内部类。

这个内部类是否匿名,由你或者由公司开发规范决定。这里为了方便,我们创建了匿名内部类。重写里面的onClik()方法。需要注意的是当我们创建这个内部类时需要导包,会有两个包,要导入View包下的。

 1 btCall.setOnClickListener(new View.OnClickListener() {
 2 
 3     @Override
 4 
 5     public void onClick(View v) {
 6 
 7  
 8 
 9     }
10 
11 });

 

接下来我们就要在这个方法里写我们的代码了。

1.首先我们需要找到文本输入框组件,获取其中内容,用findViewById()。但是前文说了,在activity类中我们是可以直接写这个方法,那么在内部类中,这样做就不行了,所以我们用当前的activity类.this去引用可以达到一样的目的。

2.获取组件中的文本内容将文本内容转成字符串类型并将内容的左右两边的空格去除。

谷歌工程师希望android系统是低耦合的。即所有组件间的耦合度低。

所以在安卓中传递并开启某一动作、消息,有专门的一个类,Intent类,我们叫意图。(关于这个意图我们以后会专题讲到)

Intent intent = new Intent();

在android中,意图仅仅代表一种手段,一种干什么事情的方式。那么这样就会产生另外两种对象:干什么事情,和事情的接受者。

比如说,看书,看就是干什么事情,书就是事情或者动作的接受者。

所以,intent对象有一个方法setaction();就代表要干什么事情,做什么动作。而括号里的参数,谷歌工程师早已经在里面定义好了很多的动作,作为Intent类的属性,等我们去调用。

Intent intent = new Intent(Intent.ACTION_CALL);//既是拨打电话的动作。

可我们仅仅指定打电话还不行,打给谁呀?电话号码是多少?我们都需要另指定。同样,intent对象也有这样的方法,将数据进行传递。

intent.setData();括号里的参数是uri类型。url是统一资源定位符,uri是统一资源标识符。所以我们直接用uri去调用parse()方法,这个方法中传入"tel:"+我们之前转换好的字符串。

关于这个意图还有最后一步,开启意图,这一步是不能够省略的,也就是说,必须有。

这里因为是打电话,打电话就需要开启一个新的界面,所以这里的开启意图是这样的:

startActivity(intent);

代码就这样全部写完了,全部代码:

 1 package com.example.myapp;
 2 
 3  
 4 
 5 import android.app.Activity;
 6 
 7 import android.content.Intent;
 8 
 9 import android.net.Uri;
10 
11 import android.os.Bundle;
12 
13 import android.view.View;
14 
15 import android.widget.Button;
16 
17 import android.widget.EditText;
18 
19  
20 
21 public class MyActivity extends Activity {
22 
23 /**
24 
25 * Called when the activity is first created.
26 
27 */
28 
29 @Override
30 
31 public void onCreate(Bundle savedInstanceState) {
32 
33 super.onCreate(savedInstanceState);
34 
35 setContentView(R.layout.main);
36 
37 Button btCall = (Button)findViewById(R.id.eeeeee);
38 
39 btCall.setOnClickListener(new View.OnClickListener() {
40 
41 @Override
42 
43 //当按钮被点击时调用的方法
44 
45 public void onClick(View v) {
46 
47 EditText editText = (EditText) MyActivity.this.findViewById(R.id.ddddd);
48 
49 String text = editText.getText().toString().trim();
50 
51 //意图,想干一件什么事情
52 
53 Intent intent = new Intent(Intent.ACTION_CALL);
54 
55 //url统一资源定位符,uri统一资源标识符
56 
57 intent.setData(Uri.parse("tel:"+text));
58 
59 startActivity(intent);
60 
61 }
62 
63 });
64 
65 }
66 
67 }

 

当然,如果你现在就运行应用程序,是会报异常的,报什么异常呢?

Java.lang.SecurityException:…android.permission.CALL PHONE

这个是什么异常呢?

这个是缺少权限异常。

Android智能系统手机是基于linux系统开发的,而linux系统会给不同级别的管理员及用户下放不同的权限,android也是如此,比如现在我们要实现打电话的功能,就需要拥有打电话的权限。那么在哪里添加这个权限呢?

来到androidmanifest清单文件,在manifest根节点内部添加<uses-permission >节点

根据提示找到android.permission.CALL_PHONE打电话的权限。

这样,代码,布局,权限就都完成了。就可以实现打电话的功能(直接打电话,而非跳转到拨号页面)。

最后说明一点,由于xml文件中,组件Edittext添加了属性android:inputType="phone",所以会导致弹出的软件盘只能是数字键盘。去掉该属性,可输入中文、英文,并可拨打但无效。

 1 Main.xml:
 2 
 3 <?xml version="1.0" encoding="utf-8"?>
 4 
 5 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 6 
 7 android:layout_width="fill_parent"
 8 
 9 android:layout_height="fill_parent"
10 
11 android:orientation="vertical">
12 
13 <EditText
14 
15 android:layout_width="fill_parent"
16 
17 android:layout_height="wrap_content"
18 
19 android:id="@+id/ddddd"
20 
21 android:text="Hello World, MyActivity"
22 
23 android:inputType="phone">
24 
25 <requestFocus/>
26 
27 </EditText>
28 
29 <Button android:layout_width="wrap_content"
30 
31 android:layout_height="wrap_content"
32 
33 android:id="@+id/eeeeee"
34 
35 android:text="打电话的按钮"/>
36 
37 </LinearLayout>

 

MyActivity

 1 package com.example.myapp;
 2 
 3  
 4 
 5 import android.app.Activity;
 6 
 7 import android.content.Intent;
 8 
 9 import android.net.Uri;
10 
11 import android.os.Bundle;
12 
13 import android.view.View;
14 
15 import android.widget.Button;
16 
17 import android.widget.EditText;
18 
19  
20 
21 public class MyActivity extends Activity {
22 
23 /**
24 
25 * Called when the activity is first created.
26 
27 */
28 
29 @Override
30 
31 public void onCreate(Bundle savedInstanceState) {
32 
33 super.onCreate(savedInstanceState);
34 
35 setContentView(R.layout.main);
36 
37 Button btCall = (Button)findViewById(R.id.eeeeee);
38 
39 btCall.setOnClickListener(new View.OnClickListener() {
40 
41 @Override
42 
43 //当按钮被点击时调用的方法
44 
45 public void onClick(View v) {
46 
47 EditText editText = (EditText) MyActivity.this.findViewById(R.id.ddddd);
48 
49 String text = editText.getText().toString().trim();
50 
51 //意图,想干一件什么事情
52 
53 Intent intent = new Intent(Intent.ACTION_CALL);
54 
55 //url统一资源定位符,uri统一资源标识符
56 
57 intent.setData(Uri.parse("tel:"+text));
58 
59 startActivity(intent);
60 
61 }
62 
63 });
64 
65 }
66 
67 }

 

Androidmanifest.xml

<uses-permission android:name="android.permission.CALL_PHONE"></usespermission>

 

接下来我们再来创建一个小案例,加深一下android应用开发流程的理解。

2.短信发送器

1.简单的界面需求:

 

经过第一个案例后,我们在写这样的界面就轻车熟路了,这里就不多说了,直接贴代码:

<?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:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:text="请输入电话号码"

            />

    <EditText android:layout_width="match_parent"

              android:layout_height="wrap_content"

              android:inputType="phone"

              android:id="@+id/et_phonenum"/>

    <TextView

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:text="请输入短信内容"

            />

    <EditText android:layout_width="match_parent"

              android:layout_height="wrap_content"

              android:inputType="textMultiLine"

              android:lines="5"

              android:id="@+id/et_text"/>

    <Button android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="发送"

            android:id="@+id/send"/>

</LinearLayout>

接下来我们就开始写java代码,与上一个案例相同,先找到组件,再获取文本内容,接着判空,这样,接下来我们就要进行发送短信的操作了。

在android系统中,有很多的管理者(即Manager),像界面管理者,应用管理者等等。同样,信息也有个管理者,SmsManager。需要注意两点:

1.导包,不能导gsm下面的包,会提示过时,因为android手机刚问世时,还是以2g为主,也就是gsm,所以谷歌为了迎合后期3g网络的发展,添加了telephony包下的SmsManager,要导这个包。

2.创建,这个SmsManager不能直接new出来,所有的Manager都不能直接new出来。所以需要这样初始化:

SmsManager smsManager =SmsManager.getDefault();

这样就获取到了信息管理者对象,与打电话不同的是,短信实际上还有最大长度的限制,如果是纯中文,短信最长是70个汉字,如果是英文,则是140个字符。那么在获取短信的内容后,我们应该先检查一下这个文本的长度是否超出了最大限度。谷歌工程师也想到了这个问题,并且给我们提供了apia,不用我们再去自己做处理了发送短信的动作实际上是调用系统里面的api:

smsManager.divideMessage(text);

这个方法做的事情就是把文本信息拆分成几个文本片段,每个片段又不超出最大限制。由于是拆分成几个片段,所以返回值类型就是arraylist的集合,代表一组短信的内容,接下里我们再对集合进行遍历,将变量塞进下面的其中的一个方法中:

smsManager.sendxxxxxxMessage();,这个方法就是用信息管理者去发送信息xxx代表不同类别的信息:

smsManager.sendDataMessage();发送彩信

smsManager.sendMultipartTextMessage();发送多个部分的文本信息

smsManager.sendMultimediaMessage();发送多媒体信息

smsManager.sendTextMessage();发送纯文本信息,就是我们说的短信,我们要用的就是这个。

我们来看看上面的方法接受的参数。

第一个参数是发送给谁,我们将获取到的字符串电话号码,传进来。

第二个参数表示这个短信来自于哪里,目前我国的电信运营商对这个参数根本不支持,所以这个地方,我们填null

第三个参数就是发送的文本内容了,这里我们把遍历获取到的字符串内容传进来。

后两个参数的类型都是PendingIntent,大家先有个概念,这个PendingIntent是延期的意图,是一个延迟才会获取到的消息。其中:

第四个参数:sentInent代表当我们的手机处在信号不强的状态下发送短信时会有发送失败的情况出现。那么我们现可以不管它,填入null.

第五个参数deliveryInent代表着送达报告。短信发送出去了,如果你想确保对方收到了,你可以请求这个送达报告,但是只有对方接收到了才会获取到送达报告。如果对方关机,就获取不到报告。那么这个参数我们也不用填什么,填个null就可以了。

这样,发送短信的代码,我们也就完成了。

最后一步,添加权限,同打电话一样,发送短信也是需要用户权限的。

<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>

需要注意的是,通过我们这个小应用发送的短信是不会在系统短信中有记录的,如果想要有记录,我们需要在系统的短信数据库中进行存储,关于这个部分以后我们会学习到。

Main.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3               android:orientation="vertical"
 4               android:layout_width="fill_parent"
 5               android:layout_height="fill_parent"
 6         >
 7     <TextView
 8             android:layout_width="fill_parent"
 9             android:layout_height="wrap_content"
10             android:text="请输入电话号码"
11             />
12     <EditText android:layout_width="match_parent"
13               android:layout_height="wrap_content"
14               android:inputType="phone"
15               android:id="@+id/et_phonenum"/>
16     <TextView
17             android:layout_width="fill_parent"
18             android:layout_height="wrap_content"
19             android:text="请输入短信内容"
20             />
21     <EditText android:layout_width="match_parent"
22               android:layout_height="wrap_content"
23               android:inputType="textMultiLine"
24               android:lines="5"
25               android:id="@+id/et_text"/>
26     <Button android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:text="发送"
29             android:id="@+id/send"/>
30 </LinearLayout>
SmsSendActivity
 1 package com.example.smsapp;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.telephony.SmsManager;
 6 import android.text.TextUtils;
 7 import android.view.View;
 8 import android.widget.Button;
 9 import android.widget.EditText;
10 import android.widget.Toast;
11 
12 import java.util.ArrayList;
13 
14 public class SmsSendActivity extends Activity {
15     EditText editText;
16     EditText editnum;
17     Button btSend;
18     /**
19      * Called when the activity is first created.
20      */
21     @Override
22     public void onCreate(Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.main);
25         editText = (EditText)findViewById(R.id.et_text);
26         editnum = (EditText)findViewById(R.id.et_phonenum);
27         btSend = (Button)findViewById(R.id.send);
28         final String text = editText.toString().trim();
29         final String num = editnum.toString().trim();
30         btSend.setOnClickListener(new View.OnClickListener() {
31             @Override
32             public void onClick(View v) {
33                 if(TextUtils.isEmpty(text) || TextUtils.isEmpty(num)){
34                     Toast.makeText(SmsSentActivity.this,"电话号码或短信内容不能为空",Toast.LENGTH_SHORT).show();
35                     return;
36                 }else{
37                     SmsManager smsManager =SmsManager.getDefault();
38                     ArrayList<String> contextList = smsManager.divideMessage(text);
39                     for(String smsText : contextList){
40                         smsManager.sendTextMessage(num,null,smsText,null,null);
41                     }
42 
43                 }
44             }
45         });
46     }
47 }

AndroidManifest.xml

<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>