您好,登錄后才能下訂單哦!
小編給大家分享一下Android位置權(quán)限以及數(shù)組尋找索引的坑有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
一、Android 危險權(quán)限,來自官方文檔的坑
Android開發(fā)者都知道,Android 6.0 之前,權(quán)限申請只需要在 AndroidManifest.xml 文件中聲明就可以。Android 6.0 開始,權(quán)限申請發(fā)生了變化,危險權(quán)限需要在應(yīng)用中動態(tài)申請,之前寫過一篇 Android 動態(tài)申請危險權(quán)限的筆記,詳情參考: Android 6.0 動態(tài)申請危險權(quán)限。
先截個圖,看看Android官方的說明:
再看危險權(quán)限的分組情況:
意思是,對危險權(quán)限進(jìn)行了分組,同一組中,只要有有一個權(quán)限被授權(quán)了,同組中其它權(quán)限也就默認(rèn)授權(quán)了。比如,我授權(quán)應(yīng)用有讀存儲卡的權(quán)限之后,應(yīng)用也就有了寫存儲卡的權(quán)限,事實上也確實如此。
然而問題來了,利用 GPS 獲取位置信息的代碼:
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){ if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission (MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){ // request permissions // ... // ... }else{ Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER; if(location != null){ double latitude = location.getLatitude(); double longitude = location.getLongitude(); } } }
通過官方的危險權(quán)限組,我們也能看到:Location 權(quán)限組里包含:ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 兩個權(quán)限,按照上面的說明,兩個權(quán)限只要有一個申請授權(quán)成功,即可成功獲取經(jīng)緯度?!基Z,當(dāng)成功申請了 ACCESS_COARSE_LOCATION 權(quán)限后,程序依然會崩,錯誤信息提示,需要獲得 ACCESS_FINE_LOCATION 權(quán)限 。
二、Spinner 的 setSelection() 方法,源于自己想當(dāng)然的坑
Android 中的下拉列表控件 spinner 有一個方法 setSelection(int position) ,顯示第幾項。此方法可能沒有效果???總是顯示第一項???
當(dāng)在做兩個spinner聯(lián)動時,spinner2依據(jù)spinner1的選擇填充數(shù)據(jù),然后使用setSeletion(2)來設(shè)置默認(rèn)項。結(jié)果發(fā)現(xiàn):spinner2顯示的總是第一項,但是實際選擇的確實已經(jīng)是position 2的位置 。
解決方法:
舊代碼:
spinner.setAdapter(adapter); spinner.setSelection(2);
解決方案有二:
(1)
spinner.setAdapter(adapter); spinner.setSelection(2,true); //spinner會重新layout
(2) 推薦
spinner.setAdapter(adapter);![](https://images2018.cnblogs.com/blog/758949/201807/758949-20180726224508174-131546620.jpg) adapter.notifyDataSetChanged(); //通知spinner刷新數(shù)據(jù) spinner.setSelection(2);
那么,這到底是什么原因造成的?我認(rèn)為這是一個bug 。這種情況通常發(fā)生在重新填充數(shù)據(jù)之后,除此之外,使用setSelection(int position)都能得到正確的顯示。
setSelection(int position, boolean animate)和setSelection(int position) 實現(xiàn)機(jī)制有較大區(qū)別,當(dāng)調(diào)用前者時重新layout,立即觸發(fā)onItemSelected函數(shù),作用相當(dāng)于用手直接點擊。而后者設(shè)置了下次選擇位置:setNextSelectedPositionInt(position); 然后請求Layout;,而requestLayout并非立即執(zhí)行,僅僅是一個schedule。但是后者可能在重新裝載數(shù)據(jù)然后Layout時丟失了某些狀態(tài)。
然鵝,我要說的坑不是這樣,我沒有兩個 Spinner 聯(lián)動,我出現(xiàn)的問題是這樣的,上代碼
布局文件:
<?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="match_parent" tools:context="com.example.sharpcj.helloworld.MainActivity"> <Spinner android:id="@+id/sp_test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true"> </Spinner> </RelativeLayout>
java 代碼:
package com.example.sharpcj.helloworld; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.Spinner; import java.util.Arrays; public class MainActivity extends AppCompatActivity { private Spinner mSpTest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String[] strs = new String[20]; for (int i = 0; i < strs.length; i++) { strs[i] = "第" + i + "項"; } mSpTest = findViewById(R.id.sp_test); mSpTest.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, strs)); int index = Arrays.binarySearch(strs, "第11項"); mSpTest.setSelection(index); } }
運行結(jié)果:
what???
為什么會這樣呢? spinner 表示這個鍋它不背,其實這個坑怪我自己想當(dāng)然了,原因在于錯誤地使用了 Arrays.binarySearch(Object[] a , Object key) 這個方法,想當(dāng)然地認(rèn)為了返回值為查找到數(shù)組的 index。代碼中, index 的實際值是 -2 。
網(wǎng)上找了一下資料:
binarySearch(int[] a, int key) 此方法的規(guī)則是這樣的:
1、如果找到關(guān)鍵字,則返回值為關(guān)鍵字在數(shù)組中的位置索引,且索引從0開始
2、如果沒有找到關(guān)鍵字,返回值為負(fù)的插入點值,所謂插入點值就是第一個比關(guān)鍵字大的元素在數(shù)組中的位置索引,而且這個位置索引從1開始。
而binarySearch(Object[] a, Object key) 最終調(diào)用方法的源碼如下:
// Like public version, but without range checks. private static int binarySearch0(Object[] a, int fromIndex, int toIndex, Object key) { int low = fromIndex; int high = toIndex - 1; while (low <= high) { int mid = (low + high) >>> 1; @SuppressWarnings("rawtypes") Comparable midVal = (Comparable)a[mid]; @SuppressWarnings("unchecked") int cmp = midVal.compareTo(key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found. }
以上是“Android位置權(quán)限以及數(shù)組尋找索引的坑有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。