按照顺序本来应该看多媒体的,但是代码实在有点麻烦,算了吧,大不了当成demo就好了。比较有用的好像就是通知栏的通知功能。
看看网络技术,使用HTTP协议和服务器进行交互,并且解析返回的数据。
WebView
可以通过这个控件在应用程序内嵌一个浏览器浏览网址。
布局文件中添加一个WebView
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/WebBrowser"></WebView>
修改onCreate()方法,可以通过getSetting()方法设置一些属性,这里只设置了允许js脚本。还有调用了setWebViewClient()方法,参数是一个WebClient实例,表示当需要跳转页面的时候,仍然留在这个WebView,而不是打开系统浏览器。然后加载网址。
这里使用到了网络权限,需要在AndroidManifest.xml中声明权限
<uses-permission android:name="android.permission.INTERNET"/>
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebBrowserWebView=findViewById(R.id.WebBrowser);
WebBrowserWebView.getSettings().setJavaScriptEnabled(true);
WebBrowserWebView.setWebViewClient(new WebViewClient());
WebBrowserWebView.loadUrl("http://www.baidu.com");
}
启动程序,可以看到打开了网页。
报错
这里有两三个报错。
但是这里如果点击其他链接,浏览器会报错ERR_UNKNOW_URL_SCHEME。
有一个办法是换成WebBrowserWebView.setWebChromeClient(new WebChromeClient());
,但是这样就变相调用谷歌浏览器了。
还有个说法是连接不是http://或者https://开头的网址,无法解析协议所以加载不出来。重写这个方法,这里主要用途就是检查网址是否为特定开头,是的话加载页面,否则调用其他浏览器。
WebBrowserWebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try{
if (url.startsWith("http:") || url.startsWith("https:")){
WebBrowserWebView.loadUrl(url);
}else{
Intent intent=new Intent(Intent.ACTION_VIEW,Uri.parse(url));
startActivity(intent);
}
return true;
}catch (Exception e){
return false;
}
}
});
但是点击其他链接后还是会报错
“Uncaught TypeError: Cannot read property ‘getItem’ of null”, source: https://m.baidu.com/?from=844b&vit=fps (2)
添加一个WebView的设置以后,可以访问百度搜索页面了WebBrowserWebView.getSettings().setDomStorageEnabled(true);
这个报错
I/chromium: [INFO:CONSOLE(0)] “Mixed Content: The page at ‘https://m.baidu.com/?from=844b&vit=fps’ was loaded over HTTPS, but requested an insecure image ‘http://shijuezhongguo.cdn.bcebos.com/1/812800023.jpg@s_2,w_370,h_245’. This request has been blocked; the content must be served over HTTPS.”, source: https://m.baidu.com/?from=844b&vit=fps (0)
这主要是因为加载https的时候不能动态加载,先加载http然后加载https。
谷歌在Android5.0以后默认关闭混合模式,https中不能加载http资源了,得手动打开这个功能,还是添加一个设置
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WebBrowserWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
所以完整代码这样写就可以使用WebView上网冲浪了
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebBrowserWebView=findViewById(R.id.WebBrowser);
WebBrowserWebView.getSettings().setJavaScriptEnabled(true);
WebBrowserWebView.getSettings().setDomStorageEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WebBrowserWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
WebBrowserWebView.setWebViewClient(new WebViewClient());
WebBrowserWebView.loadUrl("http://www.baidu.com");
}
HTTP协议访问网络
很简单的原理:客户端向服务器端发一条HTTP请求,服务器收到请求后会返回相应数据给客户端,客户端解析展示出来。
在上一步使用WebView冲浪的时候它已经自己处理好这整个流程了,现在手动看看。
HttpURLConnection
原先的Android有两种发送Http请求的方式,HttpURLConnection和HttpClient。但是后者API太多,扩展困难等问题,很不推荐了,直到Android 6.0终于被废弃了。
获取一个实例。new一个对象,调用openConnection()即可。
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
得到实例以后就可以使用Http的发给发,GET和POST,如获取数据
connection.setRequestMethos("GET");
还可以对这个连接设置一些其他属性,比如设置连接超时,读取超时的毫秒数、服务器希望得到的一些消息头等等
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
然后调用getInputStream()方法获取服务器返回的输入流,对这个流解析即可。
InputStream in=connection.getInputStream();
connection.disconnect();
小栗子
修改一下布局文件,一个Button、一个套着ScrollView的TextView
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.k.androidpractice.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/Test"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/Show"/>
</ScrollView>
</android.support.constraint.ConstraintLayout>
先编写主方法逻辑,其实看着麻烦,但是有不少都是try-catch。
这里是创建了一个线程运行,new Thread(new Runnable(){…
然后就是正常操作
- new一个URL对象
- 调用openConnection()方法建立连接
- 设置参数,比如GET方法、超时时间等
- 调用getInputStream()方法接收返回的数据
- 利用BufferedReader读取InputStream中的数据
- 展示到TextView中,由于在子线程中不允许修改UI内容,因此这里使用了一个runOnUIThread()方法,这个方法可以让线程切换到主线程去,代码在下面的下面,在这里面进行TextView的文本设置
void sendRequestWithHttpURLConnection(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection=null;
BufferedReader br=null;
try {
URL url = new URL("https://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
br = new BufferedReader(new InputStreamReader(in));
//处理返回的数据