zoukankan      html  css  js  c++  java
  • Android位置权限以及数组寻找索引的坑

    填坑与求解惑来的。

    一、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 大神写的这个二分法寻找索引的代码暂时没看懂。

  • 相关阅读:
    POJ 1003 解题报告
    POJ 1004 解题报告
    POJ-1002 解题报告
    vi--文本编辑常用快捷键之光标移动
    常用图表工具
    September 05th 2017 Week 36th Tuesday
    September 04th 2017 Week 36th Monday
    September 03rd 2017 Week 36th Sunday
    September 02nd 2017 Week 35th Saturday
    September 01st 2017 Week 35th Friday
  • 原文地址:https://www.cnblogs.com/joy99/p/9374931.html
Copyright © 2011-2022 走看看