วิธีหยุด Android เพื่อขออนุญาตก่อนอนุญาตการเข้าถึงอุปกรณ์ USB


19

ฉันมีแอปพลิเคชันที่ทำงานบนแท็บเล็ต Android ที่ไม่มีชื่อที่รูทซึ่งรัน ICS 4.0.3 ซึ่งควบคุมอุปกรณ์ USB ผ่านทางอินเตอร์เฟสโหมดโฮสต์ USB ไฟล์ android.hardware.usb.host.xml มีอยู่ใน / system / etc / permission และทุกอย่างทำงานได้อย่างยอดเยี่ยม ยกเว้น...

เมื่อฉันเรียกใช้แอพเป็นครั้งแรกหลังจากรีบูทจากนั้นเสียบอุปกรณ์ USB ฉันได้รับหน้าต่างป๊อปอัพที่ระบุว่า "อนุญาตให้แอป APPNAME เข้าถึงอุปกรณ์ USB ได้หรือไม่ [] ใช้เป็นค่าเริ่มต้นสำหรับอุปกรณ์ USB นี้ยกเลิกตกลง" และ ฉันต้องแตะตกลงก่อนจึงจะสามารถเริ่มใช้อุปกรณ์ได้

ฉันต้องปิดการยืนยันของผู้ใช้เพื่อให้แอปสามารถใช้อุปกรณ์ได้ทันที ฉันจะทำสิ่งนี้ได้อย่างไร ฉันดูคำแนะนำบางอย่างเกี่ยวกับการใช้ตัวสร้างปุ่มกดเพื่อจำลองผู้ใช้แตะปุ่มบนหน้าจอ แต่ฉันต้องการหลีกเลี่ยงวิธีการแบบนั้นและตั้งค่าต่างๆเพื่อที่ว่าคำขอการยืนยันจะไม่เกิดขึ้น

ฉันอาจไม่ได้รับซัพพลายเออร์ที่จะสร้างเคอร์เนลที่กำหนดเองสำหรับฉัน แต่ฉันควรจะได้รับคีย์การลงนามเฟิร์มแวร์จากพวกเขาเพื่อที่ฉันจะสามารถลงชื่อแอพของฉันเป็นแอประบบได้

ปัญหาที่เกี่ยวข้องอย่างหนึ่ง: การทำเครื่องหมายในช่อง "ใช้เป็นค่าเริ่มต้นสำหรับอุปกรณ์ USB นี้" ไม่ปรากฏขึ้นหากฉันถอดและถอดปลั๊กอุปกรณ์แล้วฉันจะได้รับข้อความแจ้งยืนยันอีกครั้ง ฉันสังเกตเห็นในสถานการณ์นี้ว่าหมายเลขอุปกรณ์ใน / dev / bus / usb / 001 / เปลี่ยนแปลงทุกครั้งที่ฉันถอดปลั๊กและเสียบใหม่ (001, 002, 003 เป็นต้น) ซึ่งอาจอธิบายปัญหานี้โดยเฉพาะ


จะเกิดอะไรขึ้นหากคุณปรับใช้แอปใน / system / แอพ คุณสามารถลองใช้งานได้โดยไม่ต้องลงชื่อระบบ ฉันเขียนสิ่งนี้เป็นความคิดเห็นเพราะ (a) ฉันไม่ได้ลองและ (b) ฉันไม่รู้ว่ารูปแบบการปรับใช้นี้มีให้สำหรับคุณหรือไม่
Rob Pridham

คำตอบ:


10

คำถามและคำตอบนี้เป็นข้อมูลซ้ำซ้อนของ
/programming//a/15151075/588476
ดูลิงก์ด้านบนสำหรับโปรแกรมตัวอย่างและการสนทนาเชิงลึกเพิ่มเติม

เท่าที่ฉันรู้มีสองวิธีในการรับป๊อปอัพกล่องอนุญาต USB:

  1. ขอสิทธิ์อย่างชัดเจนจากแอปพลิเคชันของคุณโดยใช้ UsbManager.requestPermission (... )
  2. ลงทะเบียนตัวกรองการเจตนาบนอุปกรณ์เสริมของคุณและให้ระบบขออนุญาตเมื่อมีการแนบอุปกรณ์

ในกรณีของ 1 ฉันได้พบว่าช่องทำเครื่องหมายในป๊อปอัพที่จะจำได้ว่าการอนุญาตไม่มีผล

สำหรับฉันฉันลบรหัสทั้งหมดที่เกี่ยวข้องกับการอนุญาตจากซอฟต์แวร์ของฉันและเพียงใส่ตัวกรองเจตนาในรายการของฉัน เมื่อเสียบอุปกรณ์ USB หากยังไม่ได้รับการอนุญาตกล่อง USB จะปรากฏขึ้น หากผู้ใช้คลิกตกลงโดยไม่ทำเครื่องหมายในช่องจดจำกล่องจะปรากฏขึ้นอีกครั้งในครั้งต่อไปที่อุปกรณ์เชื่อมต่อ อย่างไรก็ตามหากผู้ใช้ทำเครื่องหมายที่กล่องและกดตกลงจากนั้นกล่องจะไม่แสดงอีกครั้ง (เว้นแต่จะมีการถอนการติดตั้งซอฟต์แวร์และติดตั้งใหม่)

ฉันไม่แน่ใจว่ามีข้อผิดพลาดบางอย่างที่เกี่ยวข้องกับอุปกรณ์ของคุณแสดงเป็น / dev / bus / usb / 001 และ 002 เป็นต้น - ให้ฉันรู้ว่าคุณกำลังใช้ตัวกรองเจตนาโดยไม่ต้องมีช่องทำเครื่องหมายจำจะ ไม่ทำอะไร.

ฉันไม่ทราบวิธีการใด ๆ ที่คุณสามารถหลีกเลี่ยงการอนุญาตป๊อปอัปโดยสิ้นเชิง ฉันสงสัยว่าไม่มีวิธีที่จะทำโดยไม่ต้องขุดลงในรหัส Android เช่นที่คุณพูด


1
คุณแน่ใจไหม? ฉันยังคงเห็นคำขออนุญาตเมื่อถอดปลั๊กอุปกรณ์และเชื่อมต่อใหม่แล้ว ลักษณะการทำงานนี้มีความสอดคล้องกับเอกสารในdeveloper.android.com/guide/topics/connectivity/usb/host.html ส่วน "การใช้ตัวกรองเจตนา" ระบุว่า "หากผู้ใช้ยอมรับแอปพลิเคชันของคุณจะได้รับอนุญาตให้เข้าถึงอุปกรณ์โดยอัตโนมัติจนกว่าอุปกรณ์จะถูกตัดการเชื่อมต่อ"
kbro

ฉันสามารถรับรอง Nexus 7, Galaxy S3 และ Galaxy Note ได้เฉพาะบนอุปกรณ์เหล่านั้นฉันต้องยอมรับการอนุญาตเพียงครั้งเดียว (อุปกรณ์ Android กำลังทำงานในโหมดโฮสต์) - หากฉันเปิดใช้งานช่องทำเครื่องหมายเพื่อจดจำการตัดสินใจ คุณใช้อุปกรณ์ / รุ่นของ Android ฉันรู้สึกว่ามันเป็นอุปกรณ์ที่กำหนดเอง / OEM?
Wayne Uroda

มันเป็นแท็บเล็ต OEM ขนาด 7 นิ้วที่ใช้ WonderMedia WM8850 กลาง SOM ที่ใช้ Android 4.0.3
kbro

Intent-filters ใช้งานได้สำหรับเซสชันการบูตปัจจุบันเท่านั้น ใช่ฉันเสียบอุปกรณ์ usb เข้ากับโทรศัพท์และได้รับอนุญาตโดยอัตโนมัติ
user924

7

นอกจากความคิดเห็นของฉันฉันได้ดูรหัส Android พื้นฐาน

ฉันมีคำตอบที่เป็นไปได้ แต่มีข้อแม้และอุปสรรคที่สำคัญไม่น้อยกว่าสี่ข้อ:

  1. ฉันยังไม่ได้ลองเพราะฉันไม่มีอุปกรณ์ USB ที่เหมาะสม
  2. คุณต้องได้รับอนุญาตใหม่
  3. การอนุญาตจำเป็นต้องให้คุณเป็นแอพระบบ
  4. รหัสต้องมีการเข้าถึงบางสิ่งที่ไม่ได้อยู่ใน API สาธารณะ

ลืมเรื่องนี้ไปได้เลยถ้าใช้แอพ after-market ธรรมดา!

ข้อกำหนดเบื้องต้นแรกคือคุณได้MANAGE_USBรับอนุญาต ที่อธิบายไว้ที่นี่

อย่างไรก็ตามในทางกลับกันสิ่งที่จำเป็นต้องมีสำหรับสิ่งที่คุณลงชื่อด้วยรหัสระบบและคุณติดตั้งแอปของคุณลงใน / system / app

อย่างไรก็ตามหากคุณตกลงกับที่นี่รหัสบางส่วน:

   IBinder b = ServiceManager.getService(USB_SERVICE);
   IUsbManager service = IUsbManager.Stub.asInterface(b);
   service.grantDevicePermission(mDevice, uid);

mDevice เป็นอุปกรณ์จากก่อน

uidเป็น UID ของแอปของคุณเองและคุณสามารถค้นหาได้ ตัวอย่างของวิธีการที่จะทำคือคำตอบแรกที่นี่

ทั้งหมดดี? ไม่ServiceManagerเป็นandroid.os.ServiceManagerและไม่ใช่ API สาธารณะ ในตัวอย่างนี้เป็นวิธีในการรับIUsbManagerบริการ (อาจมีเส้นทางอื่น) ตอนนี้การไปถึงที่อยู่นอกเหนือขอบเขตของคำตอบของฉัน; ในอดีตคุณสามารถใช้การไตร่ตรอง แต่ฉันไม่รู้ว่าคุณยังทำได้

หลังจากผู้ที่อยู่ในกลุ่มเหล่านี้ทั้งหมดดูเหมือนว่าคุณไม่จำเป็นต้องขออนุญาตอีกต่อไปและถ้าคุณทำก็จะกลับมาทันทีโดยไม่มีกล่องโต้ตอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.