前言

多媒体这块感觉也是不太需要,快速略过,了解下就行。

多媒体的运用

使用通知

通知是Android系统中的一个功能,当某个应用程序希望向用户发出一些提示消息,而该应用程序又不在前台运行时,就可以借助通知来实现。

通知的基本用法

通知即可以在活动里创建,也可以在广播接收器里创建,当然也可以在服务里创建。

创建通知

首先需要一个NotificationManager来对通知进行管理,可以调用Context的getSystemService()方法获取到。getSystemService()方法接收到一个字符串参数用于确定获取系统的哪个服务(这里我们传入Context.NOTIFICATION_SERVICE即可)。因此,获取NotificationManager的实例就可以写成:

1
NotificationManager manager = (NotificationManager) getSyetemService(Context.NOTIFICATION_SERVICE);

接下来需要使用一个Builder构造器来创建Notification对象,代码如下:

1
Notification notification = new NotificationCompat.Builder(context).build();

上面只是一个空的Notification对象,下面来创建一个丰富的Notification对象:

1
2
3
4
5
6
7
8
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle("This is content title")//标题
.setContentText("This is content Text")//通知正文内容
.setWhen(System.currentTimeMillis())//指定通知创建时间
.setSmallIcon(R.drawable.small_icon)//设置通知小图标
.setLargeIcon(BitmapFactory.decodeResource(getResource(),
R.drawable.large_icon))//设置通知大图标,即下拉状态栏后显示的图标
.build();

接下来只需要调用NotificationManager的notify()方法就可以显示了。它第一个参数的id,第二个参数是Notification对象:

1
manager.notify(1, notification);

实现通知的点击效果

PendingIntent用于在某个合适的时机去执行某个动作,可以理解为是延迟执行的Intent。

有几个静态方法可以获取PendingIntent实例:getActivity()、getBroadcast()、getService()。这几个方法的参数都相同,分别是:Context、0(一般用不到)、Intent对象、PendingIntent的行为(有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT这四种值可选)。

NotificationCompat对象还可以再连缀一个setContentIntent()方法,其参数正是PendingIntent对象,因此可以加上这一方法从而实现通知的点击效果。

另外还需连缀.setAutoCancel(true)以达到点击后消息取消的目的。

在点击消息后创建的活动中调用NotificationManager的cancel()方法取消:

1
2
NotificationManager manager = (NotificationManager) getSyetemService(Context.NOTIFICATION_SERVICE);
manager.cancel(1);

其中cancel中的参数1即是上面设置的通知id。

进阶技巧

setSound()在通知发出时播放音频。

setVibrate()在通知发出时振动(需要权限声明)

setLights(color, light_time,dark_time)在通知时闪烁通知灯,时间以毫秒为单位

还有更多的技巧可以直接查询相关文档,就不再研究了。

调用摄像头和相册以及播放多媒体文件

具体即intent与内容提供器的结合,具体实现过程就不搞了。。。需要的话到时候直接网上copy。

使用网络技术

WebView用法

Android提供了一个WebView空间,可以用于在应用程序中嵌入一个浏览器,从而轻松的展示各种各样的网页。

新建一个WebView项目,修改布局文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>


</LinearLayout>

然后修改代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = (WebView) findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("http://www.baidu.com");
}
}

另外,还需添加访问网络的权限说明:

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

这样就具备了一个简易的浏览器的功能了。

使用HTTP协议访问网络

使用HttpURLConnection

获取HttpURLConnection实例:

1
2
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection (HttpURLConnection) url.openConnection();

设置:

1
2
3
connection.setRequestMethod("GET);
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);

然后获取服务器返回的输入流:

1
InputStream in = connection.getInputStream();

关闭HTTP连接:

1
connection.disconnect();

下面进行实战,首先修改布局文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/send_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send Request"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
android:id="@+id/response_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>

然后修改代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}

@Override
public void onClick(View v){
if (v.getId() == R.id.send_request){
sendRequestWithHttpURLConnection();
}
}
private void sendRequestWithHttpURLConnection(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL("http://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
showResponse(response.toString());
} catch (Exception e){
e.printStackTrace();
} finally {
if(reader != null){
try{
reader.close();
}catch(IOException e){
e.printStackTrace();
}
}
if (connection != null){
connection.disconnect();
}
}
}
}).start();
}

private void showResponse(final String response){
runOnUiThread(new Runnable() {
@Override
public void run() {
responseText.setText(response);
}
});
}

}

Android不允许在子线程中进行UI操作,runOnUiThread()方法用于将线程切换到主线程,然后再更新UI元素。

如果想提交数据,可用如下方法:

1
2
3
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(conncetion.getOutputStream());
out.writeBytes("username=admin&password=123456");

使用OkHttp

源码地址:http://github.com/square/okhttp

首先添加库依赖,在app/build.gradle的dependencies闭包中添加:

1
implementation 'com.squareup.okhttp3:okhttp:3.4.1'

然后创建一个OkHttpClient实例:

1
OkHttpClient client = new OkHttpClient();

然后创建一个Request对象:

1
2
3
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();

之后发起请求并获取返回数据:

1
Response response = client.newCall(request).execute();

我们可以使用如下写法来获得返回的具体内容:

1
String responseData = response.body().string();

发起POST请求写法:

1
2
3
4
5
6
7
8
9
10
Request requestBody = new FormBody.Builder()
.add("username", "admin")
.add("password", "123456")
.build();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();

实践下,布局部分不用改,直接修改代码即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}

@Override
public void onClick(View v){
if (v.getId() == R.id.send_request){
sendRequestWithOkHttp();
}
}
private void sendRequestWithOkHttp(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
showResponse(responseData);
} catch (Exception e){
e.printStackTrace();
}

}
}).start();
}

private void showResponse(final String response){
runOnUiThread(new Runnable() {
@Override
public void run() {
responseText.setText(response);
}
});
}

}

这样就完成了OkHttp的基本用法了。

解析XML格式数据

这里首先搭建一个web服务器用于提供数据。(这块就直接百度找吧,这里懒得搞)

在网站目录下添加一个get_data.xml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<apps>
<app>
<id>1</id>
<name>Google Maps</name>
<version>1.0</version>
</app>
<app>
<id>2</id>
<name>Chrome</name>
<version>2.1</version>
</app>
<app>
<id>3</id>
<name>Google Play</name>
<version>2.3</version>
</app>
</apps>

然后就开始在android程序里获取和解析这段数据。

Pull解析方式

这里继续之前的项目代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}

@Override
public void onClick(View v){
if (v.getId() == R.id.send_request){
sendRequestWithOkHttp();
}
}
private void sendRequestWithOkHttp(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://localhost/get_data.xml")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
parseXMLWithPull(responseData);
} catch (Exception e){
e.printStackTrace();
}

}
}).start();
}

private void parseXMLWithPull(String xmlData) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlData));
int eventType = xmlPullParser.getEventType();
String id = "";
String name = "";
String version = "";
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlPullParser.getName();
switch (eventType) {
case XmlPullParser.START_TAG: {
if ("id".equals(nodeName)) {
id = xmlPullParser.nextText();
} else if ("name".equals(nodeName)) {
name = xmlPullParser.nextText();
} else if ("version".equals(nodeName)) {
version = xmlPullParser.nextText();
}
break;
}
case XmlPullParser.END_TAG: {
if ("app".equals(nodeName)) {
Log.d("MainActivity", "id is " + id);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "version is " + version);
}
break;
}
default:
break;

}
eventType = xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}

}

SAX解析方式

首先新建一个MyHandler类继承自DefaultHandler,修改为如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class MyHandler extends DefaultHandler {
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
@Override
public void startDocument() throws SAXException{
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{
nodeName = localName;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException{
if("id".equals(nodeName)){
id.append(ch, start, length);
}else if("name".equals(nodeName)){
name.append(ch, start, length);
}else if("version".equals(nodeName)){
version.append(ch, start, length);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException{
if ("app".equals(nodeName)) {
Log.d("MainActivity", "id is " + id.toString().trim());
Log.d("MainActivity", "name is " + name.toString().trim());
Log.d("MainActivity", "version is " + version.toString().trim());
}
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
}

其中trim()方法用于清除换行符。然后修改活动代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View v){
if (v.getId() == R.id.send_request){
sendRequestWithOkHttp();
}
}
private void sendRequestWithOkHttp(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://localhost/get_data.xml")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
parseXMLWithSAX(responseData);
} catch (Exception e){
e.printStackTrace();
}

}
}).start();
}
private void parseXMLWithSAX(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
MyHandler handler = new MyHandler();
xmlReader.setContentHandler(handler);
xmlReader.parse(new InputSource(new StringReader(xmlData)));

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

解析JSON个数数据

首先在网站目录下添加get_data.json文件:

1
2
3
[{"id":"5","version":"5.5","name","Clash of Clans"},
{"id":"6","version":"7.0","name","Boom Beach"},
{"id":"7","version":"3.5","name","Clash Royale"}]

使用JSONObject

修改代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View v){
if (v.getId() == R.id.send_request){
sendRequestWithOkHttp();
}
}
private void sendRequestWithOkHttp(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://localhost/get_data.json")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
parseJSONWithJSONObject(responseData);
} catch (Exception e){
e.printStackTrace();
}

}
}).start();
}
private void parseJSONWithJSONObject(String jsonData) {
try {
JSONArray jsonArray = new JSONArray(jsonData);
for(int i=0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");
Log.d("MainActivity", "id is " + id);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "version is " + version);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

使用GSON

首先添加依赖环境:

1
implementation 'com.google.code.gson:gson:2.7'

GSON库可以将一段JSON格式的字符串自动映射成一个对象(这里用Person),所以就可以直接定义一个类,然后自动解析即可了。

如果是数组的话会稍微麻烦:

1
List<Person> people = gson.fromJson(JsonData, new TypeToken<List<Person>>(){}.getType());

接下来新建一个App类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class App {
private String id;
private String name;
private String version;
public String getId(){
return id;
}
public void setId(String id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String getVersion(){
return version;
}
public void setVersion(String version){
this.version = version;
}
}

然后修改代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View v){
if (v.getId() == R.id.send_request){
sendRequestWithOkHttp();
}
}
private void sendRequestWithOkHttp(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://localhost/get_data.json")
.build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
parseJSONWithGSON(responseData);
} catch (Exception e){
e.printStackTrace();
}

}
}).start();
}
private void parseJSONWithGSON(String jsonData) {
Gson gson = new Gson();
List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>(){}.getType());
for(App app : applist){
Log.d("MainActivity", "id is " + app.getId());
Log.d("MainActivity", "name is " + app.getName()));
Log.d("MainActivity", "version is " + app.getVersion()));
}
}
}