Android5.0开发范例大全 读书笔记(四)

(三)通信和联网

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;
    }
原文地址:https://www.cnblogs.com/xx-wqj/p/5987594.html