Cách yêu cầu quyền từ một Dịch vụ trong Android Marshmallow


101

Trong Android Marshmallow, các quyền phải được yêu cầu trong thời gian chạy khi cần, thay vì tất cả cùng một lúc khi một ứng dụng được cài đặt. Tuy nhiên, dường như tôi chỉ có thể yêu cầu quyền từ một Hoạt động, đây là một vấn đề vì ứng dụng của tôi chỉ chứa Dịch vụ. (Bạn có thể hỏi tại sao lại như vậy? Ứng dụng có mặt đồng hồ Android Wear đi kèm bên trong và tất cả những gì điện thoại làm là tìm kiếm ảnh gần đó để gửi đến đồng hồ - không cần Hoạt động. Nhưng nó yêu cầu quyền vị trí.)

Vì vậy, có cách nào để yêu cầu quyền từ một Dịch vụ không? Hoặc bằng cách nào đó buộc các quyền được cấp tại thời điểm cài đặt như trong quá khứ?


vấn đề này cũng lớp ứng dụng bên trong
itzhar

Hãy thử điều này nó có thể làm việc stackoverflow.com/a/41221852/5488468
Bipin Bharti

Thư viện của tôi để xử lý quyền thời gian chạy dễ dàng từ bất kỳ Ngữ cảnh nào và cũng xử lý "Đừng hỏi lại". github.com/nabinbhandari/Android-Permissions
Nabin Bhandari

Câu trả lời:


47

requestPermission()chỉ có thể được gọi từ an Activityvà không phải a Service(không giống như checkPermission()chỉ yêu cầu PackageManager). Vì vậy, bạn cần phải làm thêm một số công việc để giải quyết vấn đề đó; bạn cần cung cấp một Activitytrong ứng dụng của mình và chẳng hạn, bạn Servicecó thể kiểm tra các quyền mà ứng dụng cần và nếu chúng chưa được cấp, nó có thể tạo một thông báo và có thể thông báo cho người dùng bằng một thông báo ngắn mô tả về lý do tại sao có thông báo và những gì cần xảy ra khi họ nhấp vào thông báo, v.v.


Đây là giải pháp mà Benjamin Poiesz đã đề xuất. Bạn có thể nghe podcast này từ 23:40
xiaomi

Bạn cũng có thể gọi requestPermission () bên trong phân mảnh.
Misagh Emamverdi

3
Giải pháp nào cho trường hợp dịch vụ nền đang chạy kiểm tra định kỳ các bản cập nhật vị trí và tôi chỉ tắt quyền vị trí trong cài đặt. Vì không có hoạt động nào, điều này khiến dịch vụ của tôi gặp sự cố khi tôi mở lại ứng dụng
stud91

1
@ stud91 Ít nhất, hãy nắm bắt các ngoại lệ bảo mật hoặc quyền truy vấn mỗi khi bạn yêu cầu cập nhật vị trí. Điều này sẽ ngăn ứng dụng của bạn gặp sự cố (mặc dù bạn sẽ không nhận được bất kỳ vị trí nào nếu quyền đã bị thu hồi). Tốt hơn nữa: hãy kiểm tra quyền và nếu quyền đó bị thiếu, hãy hiển thị thông báo đưa người dùng đến Hoạt động chỉ là phần giữ chỗ cho hộp thoại quyền.
user149408

8
Đây là cách tôi giải quyết nó: github.com/mvglasow/satstat/blob/master/src/com/vonglasow/… Nó có thể được gọi từ bất kỳ Contextcái nào cũng được thực hiện OnRequestPermissionsResultCallback. Chức năng tương tự như tiêu chuẩn requestPermission().
user149408

15

Tôi đồng ý, điều này rất rắc rối cho các dịch vụ, tôi nghĩ bạn nên báo cáo sự cố trên trang Xem trước dành cho nhà phát triển Android về việc này.

Hiện tại, tôi nghĩ giải pháp tốt nhất là kiểm tra quyền trên dịch vụ và hiển thị thông báo nếu thiếu quyền. Tốt hơn nữa, hãy tạo DialogActivity để yêu cầu quyền khi người dùng nhấn vào thông báo.


7

Hãy xem thư viện PermissionEverywhere . Nó cho phép bạn yêu cầu quyền từ bất kỳ ngữ cảnh nào.

Nó tạo ra một thông báo khi nhấp vào đó, nó sẽ mở ra một hoạt động yêu cầu một quyền.

Mã mẫu từ trang github của thư viện: -

@Override
  protected Boolean doInBackground(Void... params) {
      PermissionResponse response = PermissionEverywhere.getPermission(getApplicationContext(), 
      new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
              REQ_CODE,
              "Notification title", 
              "This app needs  a write permission", 
              R.mipmap.ic_launcher)
              .call();
      //waits..
      boolean isGranted = response.isGranted();

      if(isGranted){ //changed from isGrante to isGranted
      // Do stuff
      }
  }

1
Tôi đã thử phiên bản không đồng bộ trong một Dịch vụ và nó không hoạt động. onComplete chưa bao giờ được gọi là
Leo Droidcoder

Ý tưởng tốt, nhưng nó không có sẵn trong kho
naXa

2
Gói này đã làm việc cho tôi, cảm ơn vì lời đề nghị. Tuy nhiên, tôi sẽ lưu ý rằng tôi đã không thử phiên bản không đồng bộ. Ngoài ra, đối với những người đang gặp sự cố khi sử dụng PermissionEverywhere, hãy đảm bảo rằng bạn khai báo hoạt động của trình trợ giúp trong tệp kê khai của mình VÀ đảm bảo rằng khi bạn khai báo, hoạt động đó được gắn với đúng gói (nếu bạn đang sử dụng PermissionEverywheredưới dạng gói riêng). Tôi đã mất một thời gian dài để nhận ra rằng tôi không thực sự chỉ định PermissionEverywheregói trong tệp kê khai.
user3570982 28/12/16

Tôi đã chạy PermissionEverywhereứng dụng demo của nó và nó không hoạt động.
Ixx

2

Có một thư viện rất đơn giản cho phép thực hiện chính xác điều này. Bạn có thể kiểm tra quyền từ mọi nơi (ngay cả từ một dịch vụ), dựa trên việc ứng dụng đang ở chế độ nền hay nền, nó sẽ hiển thị hộp thoại bình thường hoặc tạo thông báo yêu cầu quyền. Mã này thực sự dễ hiểu và nó cũng thực sự dễ sử dụng.

Hãy dùng thử: Quyền của Android


-2

Bạn có thể sử dụng ResultReceiverđể tạo bộ nhận câu trả lời của người dùng, sau đó chuyển nó dưới dạng gọi lại Hoạt động, thông qua thông báo PendingIntent. Tài liệu tham khảo

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.