Android位置許可權以及數組尋找索引的坑

來源:互聯網
上載者:User

標籤:manager   compareto   null   service   點擊   arrays   位置   else   ast   

填坑與求解惑來的。

一、Android 危險許可權,來自官方文檔的坑???

Android開發人員都知道,Android 6.0 之前,許可權申請只需要在 AndroidManifest.xml 檔案中聲明就可以。Android 6.0 開始,許可權申請發生了變化,危險許可權需要在應用中動態申請,之前寫過一篇 Android 動態申請危險許可權的筆記,詳情參考: Android 6.0 動態申請危險許可權。
先截個圖,看看Android官方的說明:

再看危險許可權的分組情況:

意思是,對危險許可權進行了分組,同一組中,只要有有一個許可權被授權了,同組中其它許可權也就預設授權了。比如,我授權應用有讀儲存卡的許可權之後,應用也就有了寫儲存卡的許可權,事實上也確實如此。
然而問題來了,利用 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();          }      }}

通過官方的危險許可權組,我們也能看到:Location 許可權組裡包含:ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION 兩個許可權,按照上面的說明,兩個許可權只要有一個申請授權成功,即可成功擷取經緯度。——然鵝,當成功申請了 ACCESS_COARSE_LOCATION 許可權後,程式依然會崩,錯誤資訊提示,需要獲得 ACCESS_FINE_LOCATION 許可權

二、Spinner 的 setSelection() 方法,源於自己想當然的坑!!!

Android 中的下拉式清單控制項 spinner 有一個方法 setSelection(int position) ,顯示第幾項。此方法可能沒有效果???總是顯示第一項???

------------------------------------分割線----------------------------------

當在做兩個spinner聯動時,spinner2依據spinner1的選擇填充資料,然後使用setSeletion(2)來設定預設項。結果發現:spinner2顯示的總是第一項,但是實際選擇的確實已經是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重新整理資料    spinner.setSelection(2);

那麼,這到底是什麼原因造成的?我認為這是一個bug 。這種情況通常發生在重新填充資料之後,除此之外,使用setSelection(int position)都能得到正確的顯示。

setSelection(int position, boolean animate)和setSelection(int position) 實現機制有較大區別,當調用前者時重新layout,立即觸發onItemSelected函數,作用相當於用手直接點擊。而後者設定了下次選擇位置:setNextSelectedPositionInt(position); 然後請求Layout;,而requestLayout並非立即執行,僅僅是一個schedule。但是後者可能在重新裝載資料然後Layout時丟失了某些狀態。

以上分割線中內容系轉載:原文連結:https://www.xuebuyuan.com/672724.html

-------------------------------------分割線------------------------------------------

然鵝,我要說的坑不是這樣,我沒有兩個 Spinner 聯動,我出現的問題是這樣的,上代碼
布局檔案:

<?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);    }}

運行結果:

what???
為什麼會這樣呢? spinner 表示這個鍋它不背,其實這個坑怪我自己想當然了,原因在於錯誤地使用了 Arrays.binarySearch(Object[] a , Object key) 這個方法,想當然地認為了傳回值為尋找到數組的 index。代碼中, index 的實際值是 -2 。

網上找了一下資料:
binarySearch(int[] a, int key) 此方法的規則是這樣的:

  • 1、如果找到關鍵字,則傳回值為關鍵字在數組中的位置索引,且索引從0開始
  • 2、如果沒有找到關鍵字,傳回值為負的插入點值,所謂插入點值就是第一個比關鍵字大的元素在數組中的位置索引,而且這個位置索引從1開始。

binarySearch(Object[] a, Object key) 最終調用方法的源碼如下:

    // 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.    }

關於 Object 類型,Oracle 大神寫的這個二分法尋找索引的代碼暫時沒看懂。

Android位置許可權以及數組尋找索引的坑

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.