(三)通信和聯網 3.1顯示Web信息 1.WebView通過loadUrl()方法直接訪問網頁時,點擊跳轉鏈接會打開系統預設的瀏覽器,若要攔截WebView事件,可為其添加WebViewClient 2.WebView預設不支持JavaScript,要通過setJavaScriptEnabled( ...
(三)通信和聯網
3.1顯示Web信息
1.WebView通過loadUrl()方法直接訪問網頁時,點擊跳轉鏈接會打開系統預設的瀏覽器,若要攔截WebView事件,可為其添加WebViewClient
webView.setWebViewClient(new WebViewClient())
2.WebView預設不支持JavaScript,要通過setJavaScriptEnabled()進行設置
webView.getSettings().setJavaScriptEnabled(true);
3.WebView可以直接顯示Html內容
3.4下載圖片文件
1.自定義一個ImageView控制項,實現資源的下載與顯示
值得一提的是,設置本地資源應該提供2個方法,一個通過資源id獲取,一個通過drawable獲取
網路下載可以通過asynctask實現,要註意不要在doInBackground()中更新UI線程
下麵附上完整代碼
public class WebImageView extends ImageView { private Drawable mPlaceholder, mImage; public WebImageView(Context context) { this(context, null); } public WebImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public WebImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setPlaceholderImage(Drawable drawable) { mPlaceholder = drawable; if (mImage == null) { setImageDrawable(mPlaceholder); } } public void setPlaceholderImage(int resid) { mPlaceholder = getResources().getDrawable(resid); System.out.println(1); if (mImage == null) { System.out.println(2); setImageDrawable(mPlaceholder); } } public void setImageUrl(String url) { DownloadTask task = new DownloadTask(); task.execute(url); } private class DownloadTask extends AsyncTask<String, Void, Bitmap> { @Override protected Bitmap doInBackground(String... params) { String url = params[0]; try { URLConnection connection = (new URL(url)).openConnection(); InputStream is = connection.getInputStream(); return BitmapFactory.decodeStream(is); } catch (IOException e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(Bitmap bitmap) { mImage = new BitmapDrawable(getContext().getResources(), bitmap); setImageDrawable(mImage); } } }
3.5完全在後臺下載
1.DownloadManager適合處理和管理需要長時間運行的下載操作。其優點是即使在下載失敗,鏈接改變甚至設備重啟時,依然會繼續嘗試下載
2.首先實現一個廣播接收者來監聽下載狀態
private BroadcastReceiver receiver=new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { queryDownloadStatus(); } }; private void queryDownloadStatus(){ DownloadManager.Query query=new DownloadManager.Query(); query.setFilterById(prefs.getLong(DL_ID,0)); Cursor c=dm.query(query); if(c.moveToFirst()){ int status=c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)); switch (status){ case DownloadManager.STATUS_PAUSED: case DownloadManager.STATUS_PENDING: case DownloadManager.STATUS_RUNNING: break; case DownloadManager.STATUS_SUCCESSFUL: try { ParcelFileDescriptor file=dm.openDownloadedFile(prefs.getLong(DL_ID,0)); FileInputStream fis=new ParcelFileDescriptor.AutoCloseInputStream(file); imageView.setImageBitmap(BitmapFactory.decodeStream(fis)); Toast.makeText(this,"download over!",Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { e.printStackTrace(); } break; case DownloadManager.STATUS_FAILED: dm.remove(prefs.getLong(DL_ID, 0)); prefs.edit().clear().apply(); break; } } }
3.接著獲取系統服務
dm= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
4.最後,在onResume中註冊廣播並開始下載
@Override protected void onResume() { super.onResume(); if(!prefs.contains(DL_ID)){ Uri resource=Uri.parse("http://f2.market.xiaomi.com/download/AppChannel/0965d34f016634cb83347f609306d9a3fa045a9c5/com.netease.onmyoji.mi.apk"); DownloadManager.Request request=new DownloadManager.Request(resource); request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE| DownloadManager.Request.NETWORK_WIFI); request.setTitle("Download Sample"); request.setDescription("Download SSR!"); request.setAllowedOverRoaming(false); long id=dm.enqueue(request); prefs.edit().putLong(DL_ID,id).apply(); }else{ queryDownloadStatus(); } registerReceiver(receiver,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); }
3.10發送簡訊
1.與之前的DownloadManager一樣,發送簡訊的SmsManager也是系統級服務,二者的調用極為相似
2..首先實現廣播接收者,發送簡訊一共有2個接受者,一個返回發送是否成功
private BroadcastReceiver sent = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (getResultCode()) { case Activity.RESULT_OK: Toast.makeText(SendSmsActivity.this, "發送成功", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_GENERIC_FAILURE: case SmsManager.RESULT_ERROR_NO_SERVICE: case SmsManager.RESULT_ERROR_NULL_PDU: case SmsManager.RESULT_ERROR_RADIO_OFF: Toast.makeText(SendSmsActivity.this, "發送失敗", Toast.LENGTH_SHORT).show(); break; } } };
另一個返回接收是否成功
private BroadcastReceiver delivered = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (getResultCode()) { case Activity.RESULT_OK: Toast.makeText(SendSmsActivity.this, "傳遞成功", Toast.LENGTH_SHORT).show(); break; case Activity.RESULT_CANCELED: Toast.makeText(SendSmsActivity.this, "傳遞失敗", Toast.LENGTH_SHORT).show(); break; } } };
3.接著,分別在resume和pause中註冊和註銷廣播
@Override protected void onResume() { super.onResume(); registerReceiver(sent, new IntentFilter(ACTION_SENT)); registerReceiver(delivered,new IntentFilter(ACTION_DELIVERED)); }
@Override protected void onPause() { super.onPause(); unregisterReceiver(sent); unregisterReceiver(delivered); }
4.最後調用SmsManager即可
private void sendSms(String msg) { PendingIntent sIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_SENT),0); PendingIntent dIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_DELIVERED),0); SmsManager manager=SmsManager.getDefault(); manager.sendTextMessage(RECIPIENT_ADDRESS,null,msg,sIntent,dIntent); }
3.11藍牙通信
1.藍牙通信需要獲取許可權
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
2.有時藍牙並沒有開啟,所以要通過startActivityForResult啟動
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, REQUEST_ENABLE);
3.此時應該設置一個onActivityResult方法來獲取藍牙的啟動情況
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_ENABLE: if (resultCode != RESULT_OK) { Toast.makeText(this, "藍牙啟動失敗", Toast.LENGTH_SHORT).show(); finish(); } break; case REQUEST_DISCOVERABLE: if (resultCode == RESULT_CANCELED) { Toast.makeText(this, "藍牙必須被設置為可見", Toast.LENGTH_SHORT).show(); finish(); } else { startListening(); } break; default: break; } }
4.藍牙功能分兩方,一方讓設備處於監聽狀態,監聽其他設備的連入
listenButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { email = emailField.getText().toString(); if (mBtAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3000); startActivityForResult(discoverableIntent, REQUEST_DISCOVERABLE); } startListening(); } });
監聽時要用到唯一的UUID
private void startListening() { AcceptTask task = new AcceptTask(); task.execute(MY_UUID); setProgressBarIndeterminateVisibility(true); }
5.另一方要讓設備掃描可連入的設備,主要通過startDiscovery()方法
scanButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { email = emailField.getText().toString(); mBtAdapter.startDiscovery(); setProgressBarIndeterminateVisibility(true); } });
6.程式要使用2個AsyncTask來執行具體的功能,一個用來連接
private class AcceptTask extends AsyncTask<UUID, Void, BluetoothSocket> { @Override protected BluetoothSocket doInBackground(UUID... params) { String name = mBtAdapter.getName(); mBtAdapter.setName(SEARCH_NAME); try { BluetoothServerSocket socket = mBtAdapter.listenUsingRfcommWithServiceRecord("BluetoothRecipe", params[0]); BluetoothSocket connected = socket.accept(); mBtAdapter.setName(name); return connected; } catch (IOException e) { e.printStackTrace(); mBtAdapter.setName(name); return null; } } @Override protected void onPostExecute(BluetoothSocket bluetoothSocket) { mBtSocket = bluetoothSocket; ConnectedTask task = new ConnectedTask(); task.execute(mBtSocket); } }
7.另一個用來傳輸數據
private class ConnectedTask extends AsyncTask<BluetoothSocket, Void, String> { @Override protected String doInBackground(BluetoothSocket... params) { InputStream in = null; OutputStream out = null; try { //發送數據 out = params[0].getOutputStream(); out.write(email.getBytes()); //接受其他數據 in = params[0].getInputStream(); byte[] buffer = new byte[1024]; in.read(buffer); String result = new String(buffer); mBtSocket.close(); return result.trim(); } catch (IOException e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(String result) { Toast.makeText(ExchangeActivity.this, result, Toast.LENGTH_SHORT).show(); setProgressBarIndeterminateVisibility(false); } }
8.兩個AsyncTask之間使用BroadCast進行連接
private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device.getName().equals(SEARCH_NAME)) { mBtAdapter.cancelDiscovery(); try { mBtSocket = device.createRfcommSocketToServiceRecord(MY_UUID); mBtSocket.connect(); ConnectedTask task = new ConnectedTask(); task.execute(mBtSocket); } catch (IOException e) { e.printStackTrace(); } } } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { setProgressBarIndeterminateVisibility(false); } } };
9.廣播接收者分別在resume和pause中註冊和註銷
@Override protected void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver(mReceiver, filter); }
10.create中一些初始化信息
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.activity_exchange); mBtAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBtAdapter == null) { Toast.makeText(this, "不支持藍牙", Toast.LENGTH_SHORT).show(); finish(); } //開啟藍牙 if (!mBtAdapter.isEnabled()) { Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, REQUEST_ENABLE); } emailField = (EditText) findViewById(R.id.emailField);
11.退出時將藍牙的Socket清除
@Override protected void onDestroy() { super.onDestroy(); if (mBtSocket != null) { try { mBtSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
3.12查詢網路狀態
1.通過系統服務ConnectivityManager來獲取網路狀態
2.是否可以獲取網路
public static boolean isNetworkReachable(Context context) { final ConnectivityManager mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo current = mManager.getActiveNetworkInfo(); return current != null && current.getState() == NetworkInfo.State.CONNECTED; }
3.是否可以獲取wifi
public static boolean isWifiReachable(Context context) { final ConnectivityManager mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo current = mManager.getActiveNetworkInfo(); return current != null && current.getType() == ConnectivityManager.TYPE_WIFI; }