6

Tôi đang sử dụng Thư viện báo hiệu của Android. Kể từ Marshmallow, tôi thấy lỗi sau, như mong đợi và được ghi lại.Nhắc cho phép vị trí khi KHÔNG theo dõi ở chế độ nền?

Permission từ chối: Cần ACCESS_COARSE_LOCATION hoặc cho phép ACCESS_FINE_LOCATION để có được kết quả quét

Tôi có mã khác nhau, tôi trong một Fragment, và RuntimeException được ném khi Fragment là trên màn hình, như mong đợi như tôi m không nhắc cho phép. Nếu tôi nhấn nút Home, Pause được gọi, và tôi đang bẻ khóa beaconManager, và ngoại lệ không còn bị ném nữa, như mong đợi. Quay trở lại Hoạt động từ danh sách ứng dụng trước đó, RuntimeException được ném lại mỗi lần quét.

Tại sao ngoại lệ được ném khi ở nền trước mặc dù tôi đã thêm quyền vào AndroidManifest?

Theo tài liệu HERE, bạn chỉ cần nhắc người dùng cho phép vị trí nếu bạn đang thực hiện quét trong nền?

bạn sẽ nhận được lỗi sau trong LogCat khi bạn cố gắng để làm một bluetooth quét ở chế độ nền, và không có cảnh báo sẽ được phát hiện

Điều này có nghĩa CHỈ một nền quét, hoặc Tôi có hiểu sai tài liệu và bạn phải nhắc không? Tôi muốn tránh thêm (off-đặt có lẽ để người sử dụng thần kinh) nhắc cho phép bên trong ứng dụng nếu tránh được !!

My Manifest chứa -

<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/> 

đang snipped của tôi từ Fragment là -

public class NearMeNowFragment extends Fragment implements BeaconConsumer { 

//Beacon manager stuff 
private BeaconManager beaconManager; 

<SNIP> 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    beaconManager = BeaconManager.getInstanceForApplication(getActivity()); 
    beaconManager.getBeaconParsers().add(new BeaconParser(). 
      setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View rootView = inflater.inflate(R.layout.near_me_now, container, false); 

    //Set up beacon stuff if Bluetooth available 
    if (verifyBluetooth(false)) { 
     beaconManager.bind(this); 
    } 

    <SNIP> 

    return rootView; 
} 


/*************************** 
Beacon config methods 
**************************** 
*/ 

@Override 
public void onBeaconServiceConnect() { 
    //update all scan periods 
    beaconManager.setForegroundScanPeriod(1100l); 
    beaconManager.setForegroundBetweenScanPeriod(8900l); 
    beaconManager.setAndroidLScanningDisabled(true); 
    try { 
     beaconManager.updateScanPeriods(); 
    } catch (RemoteException e) { 
     e.printStackTrace(); 
    } 

    beaconManager.setRangeNotifier(new RangeNotifier() { 
     @Override 
     public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { 
      if (beacons.size() > 0) { 
       <SNIP> 
       //handling beacons here 
       ... 
      } else { 
       Log.i(TAG, "ZERO BEACONS IN SCAN"); 
      } 
     } 
    }); 

    try { 
     beaconManager.startRangingBeaconsInRegion(new Region(TAG, null, null, null)); 
    } catch (RemoteException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
public Context getApplicationContext() { 
    return getActivity().getApplicationContext(); 
} 

@Override 
public void unbindService(ServiceConnection serviceConnection) { 
    getActivity().unbindService(serviceConnection); 
} 

@Override 
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int mode) { 
    return getActivity().bindService(intent, serviceConnection, mode); 
} 


@Override 
public void onPause() { 
    super.onPause(); 

    if(beaconManager.isBound(this)){ 
     beaconManager.unbind(this); 
    } 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    beaconManager.bind(this); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    if(beaconManager.isBound(this)){ 
     beaconManager.unbind(this); 
    } 
} 

}

lỗi Logcat thực tế của tôi là

W/Binder: Bắt một RuntimeException từ stub binder i thực hiện. java.lang.SecurityException: Cần ACCESS_COARSE_LOCATION hoặc cho phép ACCESS_FINE_LOCATION để có được kết quả quét

Trả lời

20

Để làm rõ yêu cầu là khác nhau tùy thuộc vào việc bạn thiết lập targetSdkVersion 23 trong tập tin build.gradle của bạn.

Nếu bạn nhắm mục tiêu SDK 23 (Marshmallow):

  • Bạn phải khai báo android.permission.ACCESS_COARSE_LOCATION hoặc android.permission.ACCESS_FINE_LOCATION trong biểu hiện của bạn.
  • Bạn phải nhắc người dùng cho phép như được mô tả trong bài đăng trên blog của tôi here.
  • Người dùng phải chấp nhận quyền này và không tắt.
  • Nếu bất kỳ yêu cầu nào ở trên không được đáp ứng, bạn sẽ không thể phát hiện đèn hiệu ở nền trước hoặc nền sau.

Nếu bạn KHÔNG nhắm mục tiêu SDK 23 (Marshmallow):

  • Bạn có thể tùy chọn bố android.permission.ACCESS_COARSE_LOCATION hoặc android.permission.ACCESS_FINE_LOCATION trong biểu hiện của bạn.
  • Người dùng có thể bật hoặc tắt quyền bằng cách chuyển đến cài đặt.
  • Nếu một trong các quyền không được cấp, bạn sẽ vẫn có thể phát hiện đèn hiệu ở mặt trước chứ không phải ở chế độ nền.

Xem herehere để biết thêm chi tiết.

+0

Tuyệt vời! Tôi hiện đang sử dụng lời nhắc và nhận quyền. Tôi chỉ muốn tránh điều này nếu tôi thiếu điều gì đó hiển nhiên. Có thể đáng cập nhật đoạn đầu tiên của tài liệu "requested_permission" để bao gồm không có cảnh báo trong nền HOẶC tiền cảnh? – WallyHale

+0

Tôi chỉ đọc kết luận trong bài đăng trên blog của bạn, nó mâu thuẫn với những gì bạn đã nói ở trên? QUOTE - "Nếu bạn có ứng dụng đèn hiệu chỉ cần làm việc ở mặt trước, không cần thay đổi. Nếu bạn có ứng dụng đèn hiệu cần làm việc ở chế độ nền, bạn cần cập nhật ứng dụng để yêu cầu quyền vị trí thích hợp như được mô tả trong phần đầu tiên. Ứng dụng của tôi chỉ hoạt động ở mặt trước phải không ?? – WallyHale

+1

Tôi không được tự giải thích rõ ràng. :) Nếu tôi thay đổi câu lệnh thành "Nếu bạn có ứng dụng đèn hiệu hiện tại chưa nhắm mục tiêu SDK 23 và chỉ cần làm việc ở nền trước, không cần thay đổi". điều này làm cho mâu thuẫn cảm nhận biến mất? – davidgyoung

1

Tôi gặp vấn đề tương tự với ứng dụng của mình khi thử nghiệm trên thiết bị Marshmallow. Để tránh nhắc người dùng cho phép, tôi chỉ thay đổi targetSdkVersion thành 22. CompileSdkVersion có thể vẫn ở 23. Sau khi bạn thay đổi build.gradle, bạn có thể cần chạy Tools> Android> Sync Project với Gradle Files. Nếu bạn sử dụng Eclipse, targetSdkVersion nằm trong tệp kê khai.

+0

Có bạn có thể nhắm mục tiêu SDK thấp hơn, nhưng đây không phải là giải pháp cho những ai muốn ở cạnh chảy máu. Để luôn được cập nhật với phiên bản/thiết bị mới nhất, bạn cần phải nhắc truy cập. – WallyHale

+0

Tôi chỉ muốn cung cấp tùy chọn để tránh nhắc người dùng. Một số ứng dụng không cần được nhắm mục tiêu đến SDK mới nhất. Bạn phải sử dụng bản án của bạn. –

Các vấn đề liên quan