Android單片機(jī)與藍(lán)牙模塊通信實(shí)例代碼
啦啦畢業(yè)了,畢業(yè)前要寫畢業(yè)設(shè)計,需要寫一個簡單的藍(lán)牙APP進(jìn)行交互,通過參考網(wǎng)上資料,問題順利搞定,下面小編把具體實(shí)現(xiàn)思路分享給大家,供大家參考。
1、Android藍(lán)牙編程
藍(lán)牙3.0及以下版本編程需要使用UUID,UUID是通用唯一識別碼(Universally Unique Identifier),這是一個軟件構(gòu)建的標(biāo)準(zhǔn),也是被開源基金會組織應(yīng)用在分布式計算環(huán)境領(lǐng)域的一部分。在藍(lán)牙3.0及下一版本中,UUID被用于唯一標(biāo)識一個服務(wù),比如文件傳輸服務(wù),串口服務(wù)、打印機(jī)服務(wù)等,如下:
#藍(lán)牙串口服務(wù) SerialPortServiceClass_UUID = '{00001101-0000-1000-8000-00805F9B34FB}' LANAccessUsingPPPServiceClass_UUID = '{00001102-0000-1000-8000-00805F9B34FB}' #撥號網(wǎng)絡(luò)服務(wù) DialupNetworkingServiceClass_UUID = '{00001103-0000-1000-8000-00805F9B34FB}' #信息同步服務(wù) IrMCSyncServiceClass_UUID = '{00001104-0000-1000-8000-00805F9B34FB}' SDP_OBEXObjectPushServiceClass_UUID = '{00001105-0000-1000-8000-00805F9B34FB}' #文件傳輸服務(wù) OBEXFileTransferServiceClass_UUID = '{00001106-0000-1000-8000-00805F9B34FB}' IrMCSyncCommandServiceClass_UUID = '{00001107-0000-1000-8000-00805F9B34FB}'
藍(lán)牙的連接有主從設(shè)備,提供服務(wù)的可以認(rèn)為是從設(shè)備。主設(shè)備通過UUID訪問從設(shè)備提供具有相同UUID的服務(wù),從而建立客服端—服務(wù)器(C/S)模式。
2、編程步驟
Android使用藍(lán)牙,需要獲得權(quán)限,藍(lán)牙權(quán)限獲得代碼如下:
<!-- 藍(lán)牙權(quán)限 --> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
獲取本地藍(lán)牙適配器,如果藍(lán)牙未開啟,開啟藍(lán)牙設(shè)備:
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { // Device does not support Bluetooth return; } // 開啟藍(lán)牙 int REQUEST_ENABLE_BT = 1; if (!bluetoothAdapter.isEnabled()) { Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, REQUEST_ENABLE_BT); }
搜索已配對的藍(lán)牙設(shè)備,并添加到已配對列表中:
// 查詢配對設(shè)備 List<String> devices = new ArrayList<String>(); Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices(); for (BluetoothDevice device : bondedDevices) { devices.add(device.getName() + "-" + device.getAddress()); }
搜索未配對藍(lán)牙設(shè)備,并添加到未配對列表:
mBluetoothAdapter.startDiscovery(); //開始收索 搜索接收函數(shù): final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } }; // 收索接收函數(shù)需要注冊: // Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
如果是服務(wù)器端,需要建立監(jiān)聽,注意監(jiān)聽的是某個服務(wù)的UUID,服務(wù)器監(jiān)聽類如下:
private class ConnectThread extends Thread { private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB"; private final BluetoothSocket socket; private final BluetoothDevice device; public ConnectThread(BluetoothDevice device) { this.device = device; BluetoothSocket tmp = null; try { tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID)); } catch (IOException e) { e.printStackTrace(); } this.socket = tmp; } public void run() { bluetoothAdapter.cancelDiscovery(); try { socket.connect(); connectedThread = new ConnectedThread(socket); connectedThread.start(); } catch (IOException e) { try { socket.close(); } catch (IOException ee) { ee.printStackTrace(); } return; } //manageConnectedSocket(socket); } public void cancel() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
客戶端與服務(wù)器端建立連接成功后,需要ConnectedThread類接收發(fā)送數(shù)據(jù):
// 客戶端與服務(wù)器建立連接成功后,用ConnectedThread收發(fā)數(shù)據(jù) private class ConnectedThread extends Thread { private final BluetoothSocket socket; private final InputStream inputStream; private final OutputStream outputStream; public ConnectedThread(BluetoothSocket socket) { this.socket = socket; InputStream input = null; OutputStream output = null; try { input = socket.getInputStream(); output = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } this.inputStream = input; this.outputStream = output; } public void run() { byte[] buff = new byte[1024]; int bytes; while (true) { try { bytes = inputStream.read(buff); String str = new String(buff, "ISO-8859-1"); str = str.substring(0, bytes); Log.e("recv", str); } catch (IOException e) { e.printStackTrace(); break; } } } public void write(byte[] bytes) { try { outputStream.write(bytes); } catch (IOException e) { e.printStackTrace(); } } public void cancel() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
到此為止就是藍(lán)牙開發(fā)的大致步驟,其中沒有涉及到藍(lán)牙客戶端建立連接類,不過可查閱BLE和經(jīng)典藍(lán)牙Android開發(fā)。
3、畢設(shè)藍(lán)牙APP介紹
畢設(shè)藍(lán)牙APP需要接收單片機(jī)通過藍(lán)牙模塊發(fā)送上來的數(shù)據(jù),并且藍(lán)牙APP也可以給單片機(jī)發(fā)送數(shù)據(jù)來進(jìn)行控制。頁面布局如下,一個是整體頁面,一個是設(shè)置頁面,測試手機(jī)是魅藍(lán)note。因?yàn)楫呍O(shè)做的是十字路口紅綠燈控制系統(tǒng),所有頁面布局有4個LED燈,分別代表路口的4個紅綠燈,會根據(jù)時間不同顯示不同的顏色(紅/綠/黃),并且會顯示倒計時,最后來一張紅綠燈系統(tǒng)整體圖。
activity_main.xml文件如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <LinearLayout android:id="@+id/linear_layout_top" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="40dp"> <TextView android:id="@+id/notice_view" android:layout_width="0dp" android:layout_height="40dp" android:text="藍(lán)牙未開啟" android:layout_weight="3"/> <TextView android:id="@+id/notice_recv_view" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="3"/> <TextView android:id="@+id/notice_send_view" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="3"/> <Button android:id="@+id/turn_on_off" android:layout_width="0dp" android:layout_height="40dp" android:layout_weight="2" android:text="ON"/> </LinearLayout> <TextView android:id="@+id/led1" android:layout_centerHorizontal="true" android:layout_below="@+id/linear_layout_top" android:layout_width="40dp" android:layout_height="20dp" android:gravity="center" android:text="LED1"/> <TextView android:id="@+id/led0" android:layout_centerHorizontal="true" android:layout_below="@+id/led1" android:layout_width="40dp" android:layout_height="20dp" android:gravity="center" android:text="+"/> <TextView android:id="@+id/led3" android:layout_below="@+id/led1" android:layout_toLeftOf="@+id/led1" android:layout_width="40dp" android:layout_height="20dp" android:gravity="center" android:text="LED3"/> <TextView android:id="@+id/led2" android:layout_centerHorizontal="true" android:layout_below="@+id/led3" android:layout_width="40dp" android:layout_height="20dp" android:gravity="center" android:text="LED2"/> <TextView android:id="@+id/led4" android:layout_below="@+id/led1" android:layout_toRightOf="@+id/led1" android:layout_width="40dp" android:layout_height="20dp" android:gravity="center" android:text="LED4"/> <ScrollView android:id="@+id/scroll_view" android:layout_below="@+id/led2" android:layout_above="@+id/linear_layout_bottom" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/recv_view" android:text="" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </ScrollView> <LinearLayout android:id="@+id/linear_layout_bottom" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="50dp"> <Button android:id="@+id/clear_recv_view" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="clear" /> <EditText android:id="@+id/send_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:hint="輸入框,默認(rèn)@#結(jié)尾"/> <Button android:id="@+id/send" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="send" /> </LinearLayout> </RelativeLayout>
MainActivity.java文件如下:
package com.luoxn28.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.os.Message; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; public class MainActivity extends ActionBarActivity implements View.OnClickListener { public static final int RECV_VIEW = 0; public static final int NOTICE_VIEW = 1; private BluetoothAdapter bluetoothAdapter = null; private ConnectThread connectThread = null; private ConnectedThread connectedThread = null; private TextView noticeView = null; private Button turnOnOff = null; private TextView led0, led1, led2, led3, led4; ScrollView scrollView = null; private TextView recvView = null; private Button clearRecvView = null; private EditText sendText = null; private Button send = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 獲取BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { // Device does not support Bluetooth return; } // 注冊監(jiān)聽事件 noticeView = (TextView) findViewById(R.id.notice_view); turnOnOff = (Button) findViewById(R.id.turn_on_off); led0 = (TextView) findViewById(R.id.led0); led1 = (TextView) findViewById(R.id.led1); led2 = (TextView) findViewById(R.id.led2); led3 = (TextView) findViewById(R.id.led3); led4 = (TextView) findViewById(R.id.led4); scrollView = (ScrollView) findViewById(R.id.scroll_view); recvView = (TextView) findViewById(R.id.recv_view); clearRecvView = (Button) findViewById(R.id.clear_recv_view); sendText = (EditText) findViewById(R.id.send_text); send = (Button) findViewById(R.id.send); turnOnOff.setOnClickListener(this); clearRecvView.setOnClickListener(this); send.setOnClickListener(this); if (!bluetoothAdapter.isEnabled()) { noticeView.setText("藍(lán)牙未開啟"); } else { noticeView.setText("藍(lán)牙已開啟"); } noticeView.setBackgroundColor(Color.GRAY); led0.setBackgroundColor(Color.GRAY); led1.setBackgroundColor(Color.GRAY); led2.setBackgroundColor(Color.GRAY); led3.setBackgroundColor(Color.GRAY); led4.setBackgroundColor(Color.GRAY); } private boolean isOn = false; @Override public void onClick(View view) { switch (view.getId()) { case R.id.turn_on_off: // 發(fā)送'0'或者'1'都可以 if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { Toast.makeText(this, "藍(lán)牙未開啟", Toast.LENGTH_SHORT).show(); break; } if (connectedThread == null) { Toast.makeText(this, "未連接設(shè)備", Toast.LENGTH_SHORT).show(); break; } String turn_string = "1@#"; connectedThread.write(turn_string.getBytes()); if (isOn == false) { isOn = true; // 打開了 turnOnOff.setText("OFF"); led1.setText(""); led2.setText(""); led3.setText(""); led4.setText(""); } else { isOn = false; // 關(guān)閉了 turnOnOff.setText("ON"); led1.setText("LED1"); led2.setText("LED2"); led3.setText("LED3"); led4.setText("LED4"); } break; case R.id.clear_recv_view: // 清空接收框 recvView.setText(""); break; case R.id.send: // 發(fā)送數(shù)據(jù),默認(rèn)以"@#"結(jié)尾 if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { Toast.makeText(this, "藍(lán)牙未開啟", Toast.LENGTH_SHORT).show(); return; } if (connectedThread == null) { Toast.makeText(this, "未連接設(shè)備", Toast.LENGTH_SHORT).show(); break; } String inputText = sendText.getText().toString() + "@#"; // 發(fā)送給單片機(jī)數(shù)據(jù)以"@#結(jié)尾",這樣單片機(jī)知道一條數(shù)據(jù)發(fā)送結(jié)束 //Toast.makeText(MainActivity.this, inputText, Toast.LENGTH_SHORT).show(); connectedThread.write(inputText.getBytes()); break; default: break; } } private android.os.Handler handler = new android.os.Handler() { public void handleMessage(Message msg) { Bundle bundle = null; switch (msg.what) { case RECV_VIEW: if (isOn == false) { isOn = true; turnOnOff.setText("OFF"); } bundle = msg.getData(); String recv = bundle.getString("recv"); recvView.append(recv + "\n"); scrollView.fullScroll(ScrollView.FOCUS_DOWN); // 滾動到底部 if (recv.isEmpty() || recv.contains(" ") || recv.contains("#")) { break; } int num = Integer.valueOf(recv) / 2; // 0-60s if (num <= 20) { led1.setText(""); led2.setText(""); led3.setText(""); led4.setText(""); led1.setBackgroundColor(Color.RED); led2.setBackgroundColor(Color.RED); led3.setBackgroundColor(Color.GREEN); led4.setBackgroundColor(Color.GREEN); } else if (num < 30) { int n = 30 - num; led1.setText("" + n); led2.setText("" + n); if (num < 28) { led3.setBackgroundColor(Color.GREEN); led4.setBackgroundColor(Color.GREEN); } else { led3.setBackgroundColor(Color.YELLOW); led4.setBackgroundColor(Color.YELLOW); } } else if (num <= 50) { led1.setText(""); led2.setText(""); led3.setText(""); led4.setText(""); led1.setBackgroundColor(Color.GREEN); led2.setBackgroundColor(Color.GREEN); led3.setBackgroundColor(Color.RED); led4.setBackgroundColor(Color.RED); } else { int n = 60 - num; led3.setText("" + n); led4.setText("" + n); if (num < 58) { led1.setBackgroundColor(Color.GREEN); led2.setBackgroundColor(Color.GREEN); } else { led1.setBackgroundColor(Color.YELLOW); led2.setBackgroundColor(Color.YELLOW); } } break; case NOTICE_VIEW: bundle = msg.getData(); String notice = bundle.getString("notice"); noticeView.setText(notice); break; default: break; } } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.start_bluetooth) { if (bluetoothAdapter != null) { // 開啟藍(lán)牙 int REQUEST_ENABLE_BT = 1; if (!bluetoothAdapter.isEnabled()) { Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, REQUEST_ENABLE_BT); noticeView.setText("開啟藍(lán)牙成功"); //Toast.makeText(this, "開啟藍(lán)牙成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "藍(lán)牙已開啟", Toast.LENGTH_SHORT).show(); } } return true; } else if (id == R.id.show_devices) { if (bluetoothAdapter != null) { if (!bluetoothAdapter.isEnabled()) { Toast.makeText(this, "藍(lán)牙未開啟", Toast.LENGTH_SHORT).show(); return true; } // 查詢配對設(shè)備 List<String> devices = new ArrayList<String>(); Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices(); for (BluetoothDevice device : bondedDevices) { devices.add(device.getName() + "-" + device.getAddress()); } StringBuilder text = new StringBuilder(); for (String device : devices) { text.append(device + "\n"); } Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); } return true; } else if (id == R.id.find_devices) { Toast.makeText(this, "該功能暫時不可用", Toast.LENGTH_SHORT).show(); } else if (id == R.id.connect_devices) { if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { Toast.makeText(this, "藍(lán)牙未開啟", Toast.LENGTH_SHORT).show(); return true; } // 查詢配對設(shè)備 建立連接,只能連接第一個配對的設(shè)備 List<String> devices = new ArrayList<String>(); Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices(); for (BluetoothDevice device : bondedDevices) { connectThread = new ConnectThread(device); connectThread.start(); //Toast.makeText(this, "連接成功", Toast.LENGTH_SHORT).show(); break; } } return super.onOptionsItemSelected(item); } private class ConnectThread extends Thread { private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB"; private final BluetoothSocket socket; private final BluetoothDevice device; public ConnectThread(BluetoothDevice device) { this.device = device; BluetoothSocket tmp = null; try { tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID)); } catch (IOException e) { e.printStackTrace(); } this.socket = tmp; } public void run() { bluetoothAdapter.cancelDiscovery(); try { socket.connect(); connectedThread = new ConnectedThread(socket); connectedThread.start(); } catch (IOException e) { try { socket.close(); } catch (IOException ee) { ee.printStackTrace(); } return; } //manageConnectedSocket(socket); } public void cancel() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } // 客戶端與服務(wù)器建立連接成功后,用ConnectedThread收發(fā)數(shù)據(jù) private class ConnectedThread extends Thread { private final BluetoothSocket socket; private final InputStream inputStream; private final OutputStream outputStream; public ConnectedThread(BluetoothSocket socket) { this.socket = socket; InputStream input = null; OutputStream output = null; try { input = socket.getInputStream(); output = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } this.inputStream = input; this.outputStream = output; } public void run() { StringBuilder recvText = new StringBuilder(); byte[] buff = new byte[1024]; int bytes; Bundle tmpBundle = new Bundle(); Message tmpMessage = new Message(); tmpBundle.putString("notice", "連接成功"); tmpMessage.what = NOTICE_VIEW; tmpMessage.setData(tmpBundle); handler.sendMessage(tmpMessage); while (true) { try { bytes = inputStream.read(buff); String str = new String(buff, "ISO-8859-1"); str = str.substring(0, bytes); // 收到數(shù)據(jù),單片機(jī)發(fā)送上來的數(shù)據(jù)以"#"結(jié)束,這樣手機(jī)知道一條數(shù)據(jù)發(fā)送結(jié)束 //Log.e("read", str); if (!str.endsWith("#")) { recvText.append(str); continue; } recvText.append(str.substring(0, str.length() - 1)); // 去除'#' Bundle bundle = new Bundle(); Message message = new Message(); bundle.putString("recv", recvText.toString()); message.what = RECV_VIEW; message.setData(bundle); handler.sendMessage(message); recvText.replace(0, recvText.length(), ""); } catch (IOException e) { e.printStackTrace(); break; } } } public void write(byte[] bytes) { try { outputStream.write(bytes); } catch (IOException e) { e.printStackTrace(); } } public void cancel() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
menu_main.xml文件如下:
<menu 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" tools:context=".MainActivity"> <item android:id="@+id/show_devices" android:title="@string/show_devices" android:orderInCategory="100" app:showAsAction="never" /> <item android:id="@+id/start_bluetooth" android:title="@string/start_bluetooth" android:orderInCategory="100" app:showAsAction="never" /> <item android:id="@+id/find_devices" android:title="@string/find_devices" android:orderInCategory="100" app:showAsAction="never" /> <item android:id="@+id/connect_devices" android:title="@string/connect_devices" android:orderInCategory="100" app:showAsAction="never" /> </menu>
strings.xml文件如下:
<resources> <string name="app_name">BlueTooth</string> <string name="action_settings">Settings</string> <string name="start_bluetooth">開啟藍(lán)牙</string> <string name="show_devices">查詢配對設(shè)備</string> <string name="find_devices">搜索設(shè)備</string> <string name="connect_devices">連接設(shè)備</string> </resources>
到這里整個APP已經(jīng)開發(fā)完成,親測可用,如果有什么錯誤,歡迎評論指正談?wù)揯_^。
到此,本文全部內(nèi)容就給大家介紹完了,親自測試過,代碼安全可靠,放心實(shí)用,如果有任何問題歡迎給我留言,小編會及時回復(fù)的!
- Android藍(lán)牙開發(fā)深入解析
- 詳解Android——藍(lán)牙技術(shù) 帶你實(shí)現(xiàn)終端間數(shù)據(jù)傳輸
- Android Bluetooth藍(lán)牙技術(shù)使用流程詳解
- 分享Android 藍(lán)牙4.0(ble)開發(fā)的解決方案
- Android 獲取藍(lán)牙Mac地址的正確方法
- Android手機(jī)通過藍(lán)牙連接佳博打印機(jī)的實(shí)例代碼
- android實(shí)現(xiàn)藍(lán)牙文件發(fā)送的實(shí)例代碼,支持多種機(jī)型
- Android實(shí)現(xiàn)藍(lán)牙(BlueTooth)設(shè)備檢測連接
- 詳解Android 藍(lán)牙通信方式總結(jié)
- Android學(xué)習(xí)筆記之藍(lán)牙功能
相關(guān)文章
Android 自定義imageview實(shí)現(xiàn)圖片縮放實(shí)例詳解
這篇文章主要介紹了Android 自定義imageview實(shí)現(xiàn)圖片縮放實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04android RecyclerView側(cè)滑菜單,滑動刪除,長按拖拽,下拉刷新上拉加載
本篇文章主要介紹了android RecyclerView側(cè)滑菜單,滑動刪除,長按拖拽,下拉刷新上拉加載,非常具有實(shí)用價值,需要的朋友可以參考下。2017-03-03Android 一鍵清理、內(nèi)存清理功能實(shí)現(xiàn)
這篇文章主要介紹了Android 一鍵清理、內(nèi)存清理功能實(shí)現(xiàn),非常具有實(shí)用價值,需要的朋友可以參考下。2017-01-01Android中將View的內(nèi)容保存為圖像的簡單實(shí)例
這篇文章主要介紹了Android中將View的內(nèi)容保存為圖像的簡單實(shí)例,有需要的朋友可以參考一下2014-01-01Android studio 項(xiàng)目手動在本地磁盤中刪除module后,殘留文件夾無法刪除的問題解決方法
這篇文章主要介紹了Android studio 項(xiàng)目手動在本地磁盤中刪除module后,殘留文件夾無法刪除問題,本文給出了解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03Android利用BitMap獲得圖片像素數(shù)據(jù)的方法
這篇文章主要介紹了Android利用BitMap獲得圖片像素數(shù)據(jù)的方法,結(jié)合實(shí)例對比分析了Android獲取圖片像素數(shù)據(jù)的相關(guān)技巧,需要的朋友可以參考下2016-02-02