本人總結(jié)的一些android的小知識(shí)點(diǎn),會(huì)一直持續(xù)更新的,忘關(guān)注!
PS:由于簡書上不支持markdown 的[TOC]語法,所以沒法顯示目錄,
android 常用小知識(shí)點(diǎn) tips (一)
android 常用小知識(shí)點(diǎn) tips (二)
[TOC]
1、android 6.0 權(quán)限申請(qǐng)
/**
* android 6.0 申請(qǐng)權(quán)限
*/
private void requestLocalPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED
) {
//申請(qǐng)WRITE_EXTERNAL_STORAGE權(quán)限
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
},
0);
}
}
/**
* 申請(qǐng)權(quán)限完成后回調(diào)
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
2、URLDecoder
URLDecoder.decode(value, "utf-8");
URLEncoder.encode(value, "utf-8");
-----------------------------------java端另一種解決方法--------------------------------------------
jsp頁面上有一個(gè)文本框:
<input type="text" name="companyName" value='<%=request.getAttribute("companyName") %>'/>
當(dāng)文本框內(nèi)容是漢字或者日文的時(shí)候,servlet中獲得此文本框內(nèi)容時(shí)是亂碼:
request.getParameter("companyName");
解決:
String str = request.getParameter("companyName");
當(dāng)文本框是中文時(shí):
new String(str.getBytes("ISO-8859-1"), "GB2312");
當(dāng)文本框是日文時(shí):
new String(str.getBytes("ISO8859-1"), "UTF-8");
3、Url 解析
// https://www.baidu.com?action=jump&target_page=ZZ1103¤t_page=ZZ11000;
private void dispatchUriTest(Uri uri) {
try {
String domain = uri.getAuthority();
String buffer = uri.getQueryParameter("action");
String page = uri.getQueryParameter("target_page");
String cur_page = uri.getQueryParameter("current_page");
Toast.makeText(this, type + " " + buffer, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e(TAG, "Uri Parse Error");
}
}
PS:url地址中不能有#號(hào),如有的話,請(qǐng)主動(dòng)替換掉。
4、activity 和 fragment 里面數(shù)據(jù)備份
//fragment
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("requestDate", requestDate);
outState.putParcelableArrayList("dates", dates);
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if(savedInstanceState!=null)
{
requestDate = savedInstanceState.getString("requestDate");
dates = savedInstanceState.getParcelableArrayList("dates");
}
}
//Activity
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("matchId", matchId);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
matchId = savedInstanceState.getString("matchId");
}
}
5、gradle 打包命令
gradlew assembleReleaseA8FlavorReleaseA8
gradlew assemble+ flavor + buildType 的格式組成的
6、android 藍(lán)牙開發(fā)
Android 藍(lán)牙編程的基本步驟:
獲取藍(lán)牙適配器BluetoothAdapter blueadapter=BluetoothAdapter.getDefaultAdapter();
如果BluetoothAdapter 為null,說明android手機(jī)沒有藍(lán)牙模塊。
判斷藍(lán)牙模塊是否開啟,blueadapter.isEnabled() true表示已經(jīng)開啟,false表示藍(lán)牙并沒啟用。
啟動(dòng)配置藍(lán)牙可見模式,即進(jìn)入可配對(duì)模式Intent in=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);
startActivity(in); ,200就表示200秒。
獲取藍(lán)牙適配器中已經(jīng)配對(duì)的設(shè)備Set<BluetoothDevice> device=blueadapter.getBondedDevices();
還需要在androidManifest.xml中聲明藍(lán)牙的權(quán)限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
接下來就是根據(jù)自己的需求對(duì)BluetoothAdapter 的操作了。
7、gps 獲取經(jīng)緯度
/************************* GPS定位 相關(guān) end *****************************/
/**
* android 6.0 申請(qǐng)權(quán)限
*/
private void requestLocalPermission() {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
) {
//申請(qǐng)WRITE_EXTERNAL_STORAGE權(quán)限
ActivityCompat.requestPermissions(getActivity(), new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
},
0);
}
}
/**
* 申請(qǐng)權(quán)限完成后回調(diào)
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
getLocation(context);
}
private LocationManager locationManager;
private String locationProvider; //位置提供器
private String locationStr = "";
private void getLocation(Context context) {
//1.獲取位置管理器
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//2.獲取位置提供器,GPS或是NetWork
List<String> providers = locationManager.getProviders(true);
if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
//如果是網(wǎng)絡(luò)定位
locationProvider = LocationManager.NETWORK_PROVIDER;
} else if (providers.contains(LocationManager.GPS_PROVIDER)) {
//如果是GPS定位
locationProvider = LocationManager.GPS_PROVIDER;
} else {
Toast.makeText(context, "沒有可用的位置提供器", Toast.LENGTH_SHORT).show();
return;
}
//3.獲取上次的位置,一般第一次運(yùn)行,此值為null
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = locationManager.getLastKnownLocation(locationProvider);
if (location!=null){
showLocation(location);
}else{
// 監(jiān)視地理位置變化,第二個(gè)和第三個(gè)參數(shù)分別為更新的最短時(shí)間minTime和最短距離minDistace
locationManager.requestLocationUpdates(locationProvider, 0, 0,mListener);
}
}
private void showLocation(Location location){
locationStr = location.getLatitude()+","+location.getLongitude();
Log.i(TAG, "gps : " + locationStr);
}
LocationListener mListener = new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
// 如果位置發(fā)生變化,重新顯示
@Override
public void onLocationChanged(Location location) {
showLocation(location);
}
};
/************************* GPS定位 相關(guān) end *****************************/
8、ibeacon 藍(lán)牙設(shè)備
/************************* 藍(lán)牙ibeacon 相關(guān) begin *****************************/
private BluetoothAdapter mBluetoothAdapter;
private void initBlueTooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
scanBLE();
openRemoveTimeOutDevicesTimer();
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
public void scanBLE() {
mBluetoothAdapter.startLeScan(mLeScanCallback);
}
@SuppressLint("NewApi")
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
final iBeaconClass.iBeacon ibeacon = iBeaconClass.fromScanData(device, rssi, scanRecord);
addDevicesToMap(ibeacon);
}
};
Timer mRemoveTimeOutDevicesTimer;
private void openRemoveTimeOutDevicesTimer() {
mRemoveTimeOutDevicesTimer = new Timer();
mRemoveTimeOutDevicesTimer.schedule(new TimerTask() {
@Override
public void run() {
if (mBleDeviceMaps.size() == 0) {
scanBLE();
}
}
}, 1000, 1000);
}
private void stopTimer() {
mRemoveTimeOutDevicesTimer.cancel();
}
private ConcurrentHashMap<String, iBeaconClass.iBeacon> mBleDeviceMaps = new ConcurrentHashMap<String, iBeaconClass.iBeacon>();
// private ConcurrentHashMap<String, Long> mBlePutTime = new ConcurrentHashMap<String, Long>();
private ConcurrentHashMap<String, Integer> mBleRssi = new ConcurrentHashMap<String, Integer>();
private void addDevicesToMap(iBeaconClass.iBeacon device) {
if (device == null) {
Log.d("TAG", "device==null ");
return;
}
// 只搜索與我們自己布置的iBeacon // TODO 章魚彩票測試的時(shí)候,可以先把這段代碼去掉
if (device.getProximityUuid() != null) {
if (!(device.getProximityUuid().equals(ConstantUtil.HH_IBEACON_UUID))) {
return;
}
} else {
return;
}
// 鍵值對(duì)存起來
// 接收到一個(gè)信號(hào),如果沒有,就存入
// 通過address比較
// 如果已有就更新
// 如果長時(shí)間不更新,就刪除
// 用另一個(gè)map記錄時(shí)間
// 如果3秒沒有信號(hào)
// 刪除兩個(gè)map中的數(shù)據(jù)
mBleDeviceMaps.put(device.bluetoothAddress, device);
// mBlePutTime.put(device.bluetoothAddress, System.currentTimeMillis());
mBleRssi.put(device.bluetoothAddress, device.rssi);
}
//---------------------------工具函數(shù)------------------------------------
public String[] sortMapvalues(ConcurrentHashMap map) {
// 排序hashmap的值
List<Map.Entry<String, Integer>> retArray = null;
retArray = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Collections.sort(retArray, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if (o2.getValue() != null && o1.getValue() != null && o2.getValue().compareTo(o1.getValue()) > 0) {
return 1;
} else {
return -1;
}
}
});
// 按順序取出另個(gè)集合中的iBeacon列表
String ret[] = new String[retArray.size()];
for (int i = 0; i < retArray.size(); i++) {
iBeaconClass.iBeacon iB = mBleDeviceMaps.get(retArray.get(i).getKey());
if (iB != null) {
ret[i] = iB.getBluetoothAddress();
}
}
return ret;
}
private JSONObject makeJsonParam() {
String retJson = null;
String[] objects = sortMapvalues(mBleRssi); // 按信號(hào)遠(yuǎn)近進(jìn)行排序
JSONObject ibeacon = new JSONObject();
JSONArray iBeaconList = new JSONArray();
for (int i = 0; i < objects.length; i++) {
// 最多四條
if (i > 3) {
continue;
}
// 生成每條內(nèi)容
try {
iBeaconClass.iBeacon ibe = mBleDeviceMaps.get(objects[i]);
ibeacon.put("name", ibe.name);
ibeacon.put("uuid", ibe.proximityUuid);
ibeacon.put("address", ibe.bluetoothAddress);
ibeacon.put("major", ibe.major);
ibeacon.put("minor", ibe.minor);
ibeacon.put("txPower", ibe.txPower);
ibeacon.put("rssi", ibe.rssi);
} catch (JSONException e3) {
e3.printStackTrace();
}
iBeaconList.put(ibeacon);
ibeacon = new JSONObject();
}
JSONObject paramObj = new JSONObject();
try {
JSONObject location = new JSONObject();
location.put("iBeacons", iBeaconList);
location.put("gps", locationStr);
paramObj.put("locationInfo", location);
paramObj.put("clientInfo", JsonUtil.getInstance().converData2String(getFilledClientInfoWrapper(context)));
} catch (JSONException e1) {
e1.printStackTrace();
}
return paramObj;
}
/***
* 填充公共參數(shù)clientInfo
*
* @param context
* @return
*/
protected RequestClientInfoWrapper getFilledClientInfoWrapper(Context context) {
RequestClientInfoWrapper wrapper = new RequestClientInfoWrapper();
RequestClientInfoWrapper.fillInfo(context, wrapper);
return wrapper;
}
/************************* 藍(lán)牙ibeacon 相關(guān) end *****************************/
9、獲取android簽名文件的信息
以管理員方式打開cd到對(duì)應(yīng)目錄,輸入命令:keytool -list -v -keystore debug.keystore
10、android:windowSoftInputMode屬性
熟悉利用配置文件,可以減少很多不必要的麻煩,下面附上android:windowSoftInputMode屬性:
stateUnspecified:軟鍵盤的狀態(tài)并沒有指定,系統(tǒng)將選擇一個(gè)合適的狀態(tài)或依賴于主題的設(shè)置
stateUnchanged:當(dāng)這個(gè)activity出現(xiàn)時(shí),軟鍵盤將一直保持在上一個(gè)activity里的狀態(tài),無論是隱藏還是顯示
stateHidden:用戶選擇activity時(shí),軟鍵盤總是被隱藏
stateAlwaysHidden:當(dāng)該Activity主窗口獲取焦點(diǎn)時(shí),軟鍵盤也總是被隱藏的
stateVisible:軟鍵盤通常是可見的
stateAlwaysVisible:用戶選擇activity時(shí),軟鍵盤總是顯示的狀態(tài)
adjustUnspecified:默認(rèn)設(shè)置,通常由系統(tǒng)自行決定是隱藏還是顯示
adjustResize:該Activity總是調(diào)整屏幕的大小以便留出軟鍵盤的空間
adjustPan:當(dāng)前窗口的內(nèi)容將自動(dòng)移動(dòng)以便當(dāng)前焦點(diǎn)從不被鍵盤覆蓋和用戶能總是看到輸入內(nèi)容的部分