เชื่อว่าผู้ที่หลงเข้ามาอ่านบทความนี้ก็เพราะชื่อบทความที่เจ้าของบล็อกตั้งดักไว้ XD ซึ่งบทความนี้ก็เป็นอีกเรื่องหนึ่งที่ผู้ที่หลงเข้ามาอ่านหลายๆคนประสบปัญหากัน เนื่องจากทำแอปพลิเคชันไม่ว่าจะถ่ายรูปหรือวาดรูปหรือโหลดภาพก็ตาม เมื่อบันทึกลงในเครื่องแล้วปรากฏว่าเปิดหาใน Gallery ของเครื่องไม่เจอซะงั้น
ผู้ที่หลงเข้ามาอ่านก็เป็นหนึ่งในนั้นที่ประสบปัญหาหรือว่าเคยประสบปัญหาล่ะสิ เพราะงั้นอ่านบทความนี้ต่อได้เลย~
ก่อนจะบอกวิธีแก้ปัญหานี้ก็ต้องมาทำความเข้าใจกันเสียก่อนว่าทำไมถึงเป็นเช่นนี้ (ไม่งั้นบทความเจ้าของบล็อกก็อ่านไม่เพลินน่ะสิ) เมื่อเข้าใจการทำงานแล้วก็จะสามารถเข้าใจการแก้ปัญหาได้ว่าทำไมต้องทำเช่นนั้น
ต้องเข้าใจก่อนว่า การแสดงรูปภาพทั้งหมดในหน่วยความจำเครื่องนั้น การมานั่งแสกนทีละโฟลเดอร์เพื่อค้นหาว่ามีไฟล์ภาพอยู่ที่ไหนบ้างมันดูเหมือนจะดีก็จริง แต่ในความจริงมันเสียเวลาเป็นอย่างยิ่ง นึกภาพเครื่องที่ใช้หน่วยความจำซัก 3GB แล้วต้องมานั่งใช้คำสั่งคุ้ยทีละโฟลเดอร์เพื่อหา นั่นไม่ต่างอะไรกับการสแกนไฟล์ในเครื่องเลย ไฟล์ในเครื่องยิ่งเยอะก็ยิ่งช้าขึ้นเท่านั้น
แล้วจะทำยังไงให้มันไวกว่าวิธีดังกล่าว?
นั่นก็คือสแกนไฟล์เพียงแค่ครั้งแรกเท่านั้น (นั่นก็คือตอนเปิดเครื่อง) แล้วบันทึกเก็บตำแหน่งไฟล์ภาพทั้งหมดไว้ว่าอยู่ตำแหน่งใดในเครื่องบ้าง เจ้าสิ่งที่ทำหน้านี้ที่มีชื่อเรียกว่า Media Scanner นั่นเอง โดย Gallery ก็จะอิงตำแหน่งไฟล์ภาพทั้งหมดจาก Media Scanner (เอา Path มาทำเป็นภาพ Thumbnail เพื่อแสดงผลอีกที) ดังนั้นหัวใจสำคัญจะอยู่ที่ Media Scanner
ถ้าภาพมีการย้ายตำแหน่งล่ะ?
ก็จะเกิดคำถามต่อว่าผู้ใช้ย้ายตำแหน่งภาพด้วยอะไรล่ะ? นั่นก็คือย้ายภาพด้วยแอปพลิเคชันนั่นเอง ซึ่งหัวใจสำคัญส่วนหนึ่งก็อยู่ที่แอปพลิเคชันนี่ล่ะ ที่จะบอกว่าภาพถูกย้ายไปที่ไหน ดังนั้นเมื่อภาพถูกย้ายด้วยแอปพลิเคชันใดๆ แอปพลิเคชันนั้นๆก็จะบอกกับ Media Scanner ด้วยว่าภาพย้ายไปไว้ที่ไหน ส่วนตำแหน่งเดิมไว้เวลาที่ Media Scanner ทำงานก็จะรู้เองว่าภาพไม่อยู่ที่ตำแหน่งนั้นแล้ว รวมไปถึงการย้ายภาพจาก MTP ด้วยเช่นกัน
หัวใจสำคัญอยู่ที่แอปพลิเคชัน
แอปพลิเคชันจะต้องเป็นตัวบอกกับ Media Scanner ดังนั้นจึงเป็นเหตุผลว่าทำไมผู้ที่หลงเข้ามาอ่านต้องเขียนโค๊ดเพิ่มเข้าไปว่าไฟล์ภาพดังกล่าวถูกสร้างขึ้นที่ไหนหรือถูกย้ายไปไว้ที่ไหนนั่นเอง เมื่อไม่ได้มีการแจ้งไปที่ Media Scanner ก็จะทำให้ Media Scanner ไม่รู้ว่ามีภาพเพิ่มเข้ามาที่ตำแหน่งนั้นๆ พอ Gallery เรียกไฟล์ภาพทั้งหมดที่มีจาก Media Scanner ก็ทำให้หาภาพดังกล่าวไม่เจอนั่นเอง
ส่วนการสั่งงานดังกล่าวจะใช้ Intent เข้ามากำหนดไฟล์ที่ต้องการอัปเดตแล้วส่งค่าด้วยคำสั่ง sendBroadcast ดังตัวอย่างข้างล่างนี้
public void updateImage(String path) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(path);
intent.setData(Uri.fromFile(f));
sendBroadcast(intent);
}
String filePath = ..
updateImage(filePath);
...
จากตัวอย่างข้างบนคือฟังก์ชันที่เอาไว้อัปเดตไฟล์ให้กับ Media Scanner เพียงแค่กำหนด Path ของไฟล์ที่ต้องการอัปเดตก็ได้แล้ว ง่ายล่ะสิ!
หรือถ้าใช้งานคลาส File อยู่แล้ว ก็ทำแบบนี้ได้เช่นกัน จะได้ไม่ต้องมาดึง String ให้เสียเวลา
public void updateImage(File file) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);
}
File file = ...
updateImage(file);
...
หรือใช้งานเป็นคลาส Uri ก็ใส่ uri ตรงไปตรงๆได้เช่นกัน ไม่ต้องแปลงเป็นคลาส File ให้เสียเวลา
public void updateImage(Uri uri) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uri);
sendBroadcast(intent);
}
Uri uri = ...
updateImage(uri);
...
โดยให้ทำการอัปเดตทุกครั้งเมื่อมีไฟล์เพิ่มเข้ามา อารมณ์แบบว่าเพิ่มไฟล์ปุปใช้คำสั่งนี้ทันทีเลยก็ได้ จะได้ไม่ลืมกัน และลองทดสอบดูก็จะพบว่าไฟล์ถูกอัปเดตเพื่อแสดงใน Gallery เป็นที่เรียบร้อยแล้ว