Android基础-05

Android基础-05 网络编程2

01_post方式提交数据的中文乱码解决(重点)

Android应用程序中默认是的字符集编码是UTF-8。

java.io.IOException: exceeded content-length limit of 29 bytes

在代码中对中文进行URL编码:

String data = "username="+URLEncoder.encode(username,"UTF-8")+"&password="+URLEncoder.encode(pwd,"UTF-8");

02_get提交数据乱码的解决(重点):

解决办法:保持服务器端和客户端的字符集编码一致。

03_使用HttpClient向服务器端提交数据(重点)

HttpClient apache下面的子项目。轻量级的浏览器。

步骤:

1、创建一个浏览器:
2、输入网址:
3、敲回车,发送请求:

1、使用GET方式发送请求:

package com.itheima.qqloginbyget;

import java.io.InputStream;
import java.net.URLEncoder;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    protected static final int SUCCESS = 0;

    protected static final int FAILED = 1;

    private EditText et_username;

    private EditText et_pwd;

    private Handler handler = new Handler(){
        public void handleMessage(Message msg) {

            switch (msg.what) {
            case SUCCESS:
                String result = (String) msg.obj;
                Toast.makeText(MainActivity.this, result, 0).show();
                break;

            case FAILED:
                Toast.makeText(MainActivity.this, "网络异常,获取数据失败", 0).show();
                break;
            }

        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_username = (EditText) findViewById(R.id.et_username);
        et_pwd = (EditText) findViewById(R.id.et_pwd);
    }

    public void login(View view){
        final String username = et_username.getText().toString().trim();

        final String pwd = et_pwd.getText().toString().trim();

        if(TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd) ){
            Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
            return;
        }else{
            //访问网络,提交数据给服务器端
            new Thread(){
                public void run() {
                    // 访问网络,从网络上获取图片的数据,并且现在imageview
                    try {
                        String path="http://192.168.1.254:8080/web/servlet/LoginServlet";
                        // 1、创建URL对象,打开一个HTTP类型的连接:
                        String data = "?username="+URLEncoder.encode(username, "UTF-8")+"&password="+URLEncoder.encode(pwd, "UTF-8");

//                      1、创建一个浏览器:
                        HttpClient client = new DefaultHttpClient();
//                      2、输入网址:
                        HttpGet httpGet = new HttpGet(path + data);
//                      3、敲回车,发送请求:
                        HttpResponse response = client.execute(httpGet);
                        //得到响应码(状态吗)
                        int code = response.getStatusLine().getStatusCode();
                        if(200 == code){
                            //得到服务器端返回的响应数据
                            InputStream is  = response.getEntity().getContent();
                            // 4、把二进制流的响应数据转换成需要的数据类型:
                            String result = StreamTools.readStreamToStr(is);

                            Message msg = Message.obtain();
                            //定义一个消息码,用来区分消息从什么地方发送的
                            msg.what = SUCCESS;
                            msg.obj = result;
                            handler.sendMessage(msg);
                        }

                    } catch (Exception e) {
                        Message msg = Message.obtain();
                        //定义一个消息码,用来区分消息从什么地方发送的
                        msg.what = FAILED;
                        msg.obj = "网络异常,获取数据失败";
                        handler.sendMessage(msg);

                        e.printStackTrace();
                    }
                };
            }.start();
        }
    }

}

2、使用POST方式发送请求:

package com.itheima.qqloginbyget;

import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    protected static final int SUCCESS = 0;

    protected static final int FAILED = 1;

    private EditText et_username;

    private EditText et_pwd;

    private Handler handler = new Handler(){
        public void handleMessage(Message msg) {

            switch (msg.what) {
            case SUCCESS:
                String result = (String) msg.obj;
                Toast.makeText(MainActivity.this, result, 0).show();
                break;

            case FAILED:
                Toast.makeText(MainActivity.this, "网络异常,获取数据失败", 0).show();
                break;
            }

        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_username = (EditText) findViewById(R.id.et_username);
        et_pwd = (EditText) findViewById(R.id.et_pwd);
    }

    public void login(View view){
        final String username = et_username.getText().toString().trim();

        final String pwd = et_pwd.getText().toString().trim();

        if(TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd) ){
            Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
            return;
        }else{
            //访问网络,提交数据给服务器端
            new Thread(){
                public void run() {
                    // 访问网络,从网络上获取图片的数据,并且现在imageview
                    try {
                        String path="http://192.168.1.254:8080/web/servlet/LoginServlet";
                        // 1、创建URL对象,打开一个HTTP类型的连接:
                        String data = "username="+URLEncoder.encode(username,"UTF-8")+"&password="+URLEncoder.encode(pwd,"UTF-8");

//                      1、创建一个浏览器:
                        HttpClient client = new DefaultHttpClient();

//                      2、输入网址:
                        HttpPost httpPost = new HttpPost(path);
                        //封装需要提交的数据
                        List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();

                        BasicNameValuePair pair1 = new BasicNameValuePair("username", username);

                        BasicNameValuePair pair2 = new BasicNameValuePair("password", pwd);

                        list.add(pair1);
                        list.add(pair2);
                        //把需要提交的数据封装到form实体中
                        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
                        //把数据实体放到post对象
                        httpPost.setEntity(entity);
//                      3、敲回车,发送请求:
                        HttpResponse response = client.execute(httpPost);

                        int code = response.getStatusLine().getStatusCode();
                        if(200 == code){
                            InputStream is  = response.getEntity().getContent();
                            // 4、把二进制流的响应数据转换成需要的数据类型:
                            String result = StreamTools.readStreamToStr(is);

                            Message msg = Message.obtain();
                            //定义一个消息码,用来区分消息从什么地方发送的
                            msg.what = SUCCESS;
                            msg.obj = result;
                            handler.sendMessage(msg);
                        }

                    } catch (Exception e) {
                        Message msg = Message.obtain();
                        //定义一个消息码,用来区分消息从什么地方发送的
                        msg.what = FAILED;
                        msg.obj = "网络异常,获取数据失败";
                        handler.sendMessage(msg);

                        e.printStackTrace();
                    }
                };
            }.start();
        }
    }

}

04使用开源项目Asynchttpclient的GETPOST访问网络(重点)

原理:

内部使用子线程访问访问,并对提交的数据进行了URL编码;

代码:

1、使用GET方式发送请求:

package com.itheima.qqloginbyget;

import java.io.InputStream;
import java.net.URLEncoder;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    protected static final int SUCCESS = 0;

    protected static final int FAILED = 1;

    private EditText et_username;

    private EditText et_pwd;

    private Handler handler = new Handler(){
        public void handleMessage(Message msg) {

            switch (msg.what) {
            case SUCCESS:
                String result = (String) msg.obj;
                Toast.makeText(MainActivity.this, result, 0).show();
                break;

            case FAILED:
                Toast.makeText(MainActivity.this, "网络异常,获取数据失败", 0).show();
                break;
            }

        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_username = (EditText) findViewById(R.id.et_username);
        et_pwd = (EditText) findViewById(R.id.et_pwd);
    }

    public void login(View view){
        final String username = et_username.getText().toString().trim();

        final String pwd = et_pwd.getText().toString().trim();

        if(TextUtils.isEmpty(username) || TextUtils.isEmpty(pwd) ){
            Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
            return;
        }else{
            String path="http://192.168.1.254:8080/web/servlet/LoginServlet";
            String data = "?username="+username+"&password="+pwd;

            AsyncHttpClient client = new AsyncHttpClient();
            client.get(path + data, new AsyncHttpResponseHandler() {

                //当前请求处理成功时调用这个方法
                //statusCode 状态码
                //headers 响应头
                //responseBody 响应数据
                @Override
                public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                    Toast.makeText(MainActivity.this, new String(responseBody), 0).show();
                }

                //当前请求处理失败时调用这个方法
                @Override
                public void onFailure(int statusCode, Header[] headers,
                        byte[] responseBody, Throwable error) {

                    Toast.makeText(MainActivity.this,"网络异常,请检查网络", 0).show();
                }
            });

        }
    }

}

使用POST方式发送请求

String path="http://192.168.1.254:8080/web/servlet/LoginServlet";
    // 1、创建URL对象,打开一个HTTP类型的连接:
    //String data = "username="+URLEncoder.encode(username,"UTF-8")+"&password="+URLEncoder.encode(pwd,"UTF-8");

    AsyncHttpClient client = new AsyncHttpClient();

    RequestParams params = new RequestParams();
    params.put("username", username);
    params.put("password", pwd);

    client.post(path, params, new AsyncHttpResponseHandler() {

        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
            Toast.makeText(MainActivity.this, new String(responseBody), 0).show();
        }

        @Override
        public void onFailure(int statusCode, Header[] headers,
                byte[] responseBody, Throwable error) {
            Toast.makeText(MainActivity.this, "网络异常,情检查网络", 0).show();
        }
    });

05_上传文件(重点)

代码:

//根据用户输入的文件路径得到文件对象
String filePath = et_path.getText().toString().trim();
File file = new File(filePath);

String path = "http://192.168.1.254:8080/web/servlet/UploadServlet";
AsyncHttpClient client = new AsyncHttpClient();

RequestParams params = new RequestParams();
//传递文件对象给服务器端
params.put("file", file);
client.post(path, params, new AsyncHttpResponseHandler() {

    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
        Toast.makeText(MainActivity.this, new String(responseBody), 0).show();
    }

    @Override
    public void onFailure(int statusCode, Header[] headers,
            byte[] responseBody, Throwable error) {

        Toast.makeText(MainActivity.this, "网络异常", 0).show();
    }
});

06_多线程加速下载的原理

07_多线程下载的原理

多线程下载的原理或步骤:

1、在本地创建一个服务器端一模一样大小的空文件:
    大小:content-length;
    RandomAccessFile setLength();
2、设置使用几个子线程去下载服务器上的文件:
    在应用程序中设置变量代表子线程的个数;
3、每个子线程下载的数据块的大小:
    length/threaCount=blocksize;
4、计算每个子线程下载开始位置和结束位置:
     开始位置:threadId * blocksize; 结束位置:(threadId+1) * blocksize -1;
     最后一个子线程下载结束位置: length-1;
5、创建子线程,下载数据:
    设置每个子线程下载数据的范围:Range:bytes=0-3

6、知道在什么时候文件下载完成,所有的子线程都下载完毕:
    在程序中设置变量代表正在运行的线程的个数,当每个子线程下载完毕都去减1,当变量为0时表示所有的子线程都结束了;

08_javase多线程下载的逻辑

根据以上6个步骤实现代码:

MultiThreadDownLoader.java:

package com.itheima.multithread;

import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class MultiThreadDownLoader {

    // 2、设置线程的个数
    private static int threadCount = 3;

    /**
     * @param args
     */
    public static void main(String[] args) {

        try {
            String path = "http://192.168.1.254:8080/sogou.exe";
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setRequestMethod("GET");
            conn.setReadTimeout(3000);

            int code = conn.getResponseCode();
            if (code == 200) {
                // 1、在本地创建一个服务器端一模一样大小的空文件
                int length = conn.getContentLength();
                RandomAccessFile raf = new RandomAccessFile("temp.exe", "rw");
                raf.setLength(length);

                // 3、每个子线程下载的数据块的大小
                int blockSize = length / threadCount;
                for (int threadId = 0; threadId < threadCount; threadId++) {
                    // 4、计算每个子线程下载开始位置和结束位置
                    int startIndex = threadId * blockSize;
                    int ednIndex =  (threadId+1) * blockSize - 1;
                    //最后一个子线程下载的结束位置
                    if(threadId == (threadCount-1)){
                        ednIndex = length - 1;
                    }
                    //创建子线程开始下载数据
                    new DownLoadChildThread(path,threadId,startIndex,ednIndex).start();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

DownLoadChildThread.java:

package com.itheima.multithread;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

public class DownLoadChildThread extends Thread {

    private String url;
    private int threadId;
    private int startIndex;
    private int ednIndex;

    //设置正在运行的线程的个数
    private static int runningThreadCount = 3;

    public DownLoadChildThread(String url, int threadId, int startIndex,
            int ednIndex) {
        this.url = url;
        this.threadId = threadId;
        this.startIndex = startIndex;
        this.ednIndex = ednIndex;
    }

    @Override
    public void run() {
        try {
            //5、创建子线程,下载数据:
            URL url = new URL("http://192.168.1.254:8080/sogou.exe");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setRequestMethod("GET");
            conn.setReadTimeout(3000);

            //设置请求的数据范围
            conn.setRequestProperty("Range", "bytes="+startIndex+"-"+ednIndex);
            System.out.println("线程"+threadId+"下载的范围:"+startIndex+"-"+ednIndex);
            //请求部分数据成功,响应码为206
            int code = conn.getResponseCode();
            if(code == 206){
                InputStream is = conn.getInputStream();
                RandomAccessFile raf = new RandomAccessFile("temp.exe", "rw");
                //从指定的位置开始写数据
                raf.seek(startIndex);
                byte[] buffer = new byte[1024];
                int len = -1;
                while((len = is.read(buffer)) != -1){
                    raf.write(buffer, 0, len);
                }
                is.close();
                raf.close();
                System.out.println("线程"+threadId+"下载完成........................");

                //每个子线程下载完成时都去减1
                synchronized (DownLoadChildThread.class) {
                    runningThreadCount--;
                    if(runningThreadCount == 0){
                        System.out.println("文件下载完成...........................");
                    }
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

09_多线程下载的Android移植

代码:

MainActivity.java:

package com.itheima.multithreaddownload;

import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    private EditText et_path;

    private EditText et_threadCount;

    // 2、设置线程的个数
    private static int threadCount = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_path = (EditText) findViewById(R.id.et_path);
        et_threadCount = (EditText) findViewById(R.id.et_threadCount);
    }

    public void download(View view){
        final String path = et_path.getText().toString().trim();
        String threadCountStr = et_threadCount.getText().toString().trim();
        if(TextUtils.isEmpty(path)){
            Toast.makeText(this, "请输入文件的下载地址", 0).show();
            return;
        }
        if(!TextUtils.isEmpty(threadCountStr)){
            threadCount = Integer.parseInt(threadCountStr);
        }

        new Thread(){
            public void run() {
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(3000);

                    int code = conn.getResponseCode();
                    if (code == 200) {
                        // 1、在本地创建一个服务器端一模一样大小的空文件
                        int length = conn.getContentLength();
                        RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe", "rw");
                        raf.setLength(length);

                        // 3、每个子线程下载的数据块的大小
                        int blockSize = length / threadCount;
                        for (int threadId = 0; threadId < threadCount; threadId++) {
                            // 4、计算每个子线程下载开始位置和结束位置
                            int startIndex = threadId * blockSize;
                            int ednIndex =  (threadId+1) * blockSize - 1;
                            //最后一个子线程下载的结束位置
                            if(threadId == (threadCount-1)){
                                ednIndex = length - 1;
                            }
                            //创建子线程开始下载数据
                            new DownLoadChildThread(path,threadId,startIndex,ednIndex,threadCount).start();
                        }

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
        }.start();
    }

}

DownLoadChildThread.java:

package com.itheima.multithreaddownload;

import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

import android.os.Environment;

public class DownLoadChildThread extends Thread {

    private String path;
    private int threadId;
    private int startIndex;
    private int ednIndex;

    //设置正在运行的线程的个数
    private  int runningThreadCount;

    public DownLoadChildThread(String path, int threadId, int startIndex,
            int ednIndex,int runningThreadCount) {
        this.path = path;
        this.threadId = threadId;
        this.startIndex = startIndex;
        this.ednIndex = ednIndex;
        this.runningThreadCount = runningThreadCount;
    }

    @Override
    public void run() {
        try {
            //5、创建子线程,下载数据:
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setRequestMethod("GET");
            conn.setReadTimeout(3000);

            //设置请求的数据范围
            conn.setRequestProperty("Range", "bytes="+startIndex+"-"+ednIndex);
            System.out.println("线程"+threadId+"下载的范围:"+startIndex+"-"+ednIndex);
            //请求部分数据成功,响应码为206
            int code = conn.getResponseCode();
            if(code == 206){
                InputStream is = conn.getInputStream();
                RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/temp.exe", "rw");
                //从指定的位置开始写数据
                raf.seek(startIndex);
                byte[] buffer = new byte[1024];
                int len = -1;
                while((len = is.read(buffer)) != -1){
                    raf.write(buffer, 0, len);
                }
                is.close();
                raf.close();
                System.out.println("线程"+threadId+"下载完成........................");

                //每个子线程下载完成时都去减1
                synchronized (DownLoadChildThread.class) {
                    runningThreadCount--;
                    if(runningThreadCount == 0){
                        System.out.println("文件下载完成...........................");
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

10_开目实现多线程下载(重点)

XUtils

引入xUtils-2.6.10.jar文件;

代码:

package com.itheima.xutils;

import java.io.File;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;

public class MainActivity extends Activity {

private TextView tv_start;

private TextView tv_progress;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tv_start = (TextView) findViewById(R.id.tv_start);
    tv_progress = (TextView) findViewById(R.id.tv_progress);
}

public void download(View view){
    HttpUtils http = new HttpUtils();
    String path = "http://192.168.1.254:8080/11.exe";

    http.download(path, Environment.getExternalStorageDirectory()+"/11.exe", true, new RequestCallBack<File>() {

        @Override
        public void onSuccess(ResponseInfo<File> response) {
            Toast.makeText(MainActivity.this, "文件下载,保存在"+response.result.getPath(), 0).show();
        }

        @Override
        public void onFailure(HttpException e, String str) {
            Toast.makeText(MainActivity.this, "文件失败", 0).show();
        }

        @Override
        public void onLoading(long total, long current, boolean isUploading) {
            super.onLoading(total, current, isUploading);

            tv_progress.setText(current+"/"+total);
        }

        @Override
        public void onStart() {

            super.onStart();

            tv_start.setText("开始下载...");
        }
    });

}
}
时间: 2024-10-09 04:22:32

Android基础-05的相关文章

Android # 基础汇总

主題彙總: 源碼下載/Android开发 源码下载: [更新4.4]Android 2.2.2到Android 4.2.2源码下载地址 - Android开发资料库 - Android开发论坛 - 安卓开发论坛 - Android开发 - 安卓论坛 - 移动互联网门户http://www.apkbus.com/android-108480-1-1.html Android4.2源码下载过程_Linux教程_Linux公社-Linux系统门户网站http://www.linuxidc.com/Li

Android基础入门教程——10.1 TelephonyManager(电话管理器)

Android基础入门教程--10.1 TelephonyManager(电话管理器) 标签(空格分隔): Android基础入门教程 本节引言: 本章节是Android基础入门教程的最后一章,主要讲解是一些零零散散的一些知识点,以及一些遗漏 知识点的补充,这些零散的知识点包括,各种系统服务的使用,比如本节的电话管理器,短信管理器, 振动器,闹钟,壁纸等等,还有传感器之类的东西!乱七八糟什么都有哈!好的,本节我们要学习的 是TelephonyManager,见名知义:用于管理手机通话状态,获取电

Android基础01 快速入门 &amp; 布局

Android基础01 快速入门 & 布局 01.01  手机制式 第一代模拟制式手机(1G):1G就是大哥大,手机类似于简单的无线电双工电台,通话是锁定在一定频率,所以使用可调频电台就可以窃听通话.   第二代GSM.CDMA等数字手机(2G):手机使用PHS,GSM或者CDMA这些十分成熟的标准,具有稳定的通话质量和合适的待机时间,支持彩信业务的GPRS和上网业务的WAP服务,以及各式各样的Java程序等. 第三代移动通信技术(3G):3G,是英文3rd Generation的缩写,指第三代

Android基础-07

Android基础-07 广播与服务 01_为什么需要广播接受者 电台:中央人民广播电台,93.4mhz: 收音机:93.4mhz,收听广播: Android系统内置的电台,发送一些事件:接收短信.外拨电话.电量不足.电量充满.SD插拔.软件安装与下载等. Android应用程序中的收音机:广播接收者,指定需要接收的事件类型: 可以做一些对用户有用的业务逻辑操作. 广播接收者的特点: 1.即使广播接收者没有运行,当广播事件到达的时候,系统会自动启动广播接收者,并且调用onReceive方法处理消

Android基础入门教程——10.12 传感器专题(3)——加速度-陀螺仪传感器

Android基础入门教程--10.12 传感器专题(3)--加速度/陀螺仪传感器 标签(空格分隔): Android基础入门教程 本节引言: 本节继续来扣Android中的传感器,本节带来的是加速度传感器(Accelerometer sensor)以及 陀螺仪传感器(Gyroscope sensor),和上一节的方向传感器一样有着x,y,z 三个轴, 还是要说一点:x,y轴的坐标要和绘图那里的x,y轴区分开来!传感器的是以左下角 为原点的!x向右,y向上!好的,带着我们的套路来学本节的传感器吧

Android基础入门教程——8.1.3 Android中的13种Drawable小结 Part 3

Android基础入门教程--8.1.3 Android中的13种Drawable小结 Part 3 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来把剩下的四种Drawable也学完,他们分别是: LayerDrawable,TransitionDrawable,LevelListDrawable和StateListDrawable, 依旧贴下13种Drawable的导图: 1.LayerDrawable 层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来

Android基础入门教程——8.1.2 Android中的13种Drawable小结 Part 2

Android基础入门教程--8.1.2 Android中的13种Drawable小结 Part 2 标签(空格分隔): Android基础入门教程 本节引言: 本节我们继续来学习Android中的Drawable资源,上一节我们学习了: ColorDrawable:NinePatchDrawable: ShapeDrawable:GradientDrawable!这四个Drawable~ 而本节我们继续来学习接下来的五个Drawable,他们分别是: BitmapDrawable:Insert

Android基础入门教程——2.3.12 Date &amp; Time组件(下)

Android基础入门教程--2.3.12 Date & Time组件(下) 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来继续学习Android系统给我们提供的几个原生的Date & Time组件,他们分别是: DatePicker(日期选择器),TimePicker(时间选择器),CalendarView(日期视图),好吧, 其实一开始让我扣这几个玩意我是拒绝的,因为在我的印象里,他们是这样的: 简直把我丑哭了,有木有,终于知道为什么那么多人喜欢自定义这种类型的

Android基础入门教程——2.1 View与ViewGroup的概念

Android基础入门教程--2.1 View与ViewGroup的概念 标签(空格分隔): Android基础入门教程 本节引言: 告别了第一章,迎来第二章--Android中的UI(User Interface)组件的详解, 而本节我们要学习的是所有控件的父类View和ViewGroup类!突发奇想,直接翻译官方文档对 这两个东西的介绍吧,对了,天朝原因,google上不去,Android developer上不去,我们可以 改hosts或者用vpn代理,当然也可以像笔者一样使用国内的API