สิ่งที่ฉันพยายามและพบ
คล้ายกับปัญหาที่ฉันเคยพบเกี่ยวกับการแชร์/เปิดไฟล์ APK (ที่นี่, ที่นี่ และที่นี่) ตอนนี้ฉันมีปัญหาในการส่งไฟล์ภาพ (ในเนื้อหา ความละเอียด/ดิบ หรือแม้แต่จาก URL) ไปยังแอปเฉพาะ: WhatsApp และ Viber
ฉันต้องสามารถแชร์ไฟล์รูปภาพไปยังแอปทั้งหมดได้ โดยเฉพาะแอปยอดนิยมอย่าง WhatsApp และ Viber
คำถาม
ทั้ง WhatsApp และ Viber มีปัญหาเมื่อฉันพยายามแชร์ไฟล์รูปภาพบน Andorid 7.1.1 มันทำงานได้ดีในแอปอื่นๆ และ Android เวอร์ชันก่อนหน้า
พวกมันแสดงหน้าจอสีดำ (ไม่มีภาพ) หรือปิดตัวเองในการทดสอบทั้งหมดที่ฉันได้ลอง
สำหรับตอนนี้ ฉันจะใช้โซลูชัน #7 แต่ยังไม่สมบูรณ์แบบ เนื่องจากต้องใช้ทั้งแอป Viber และ WhatsApp เพื่อให้สิทธิ์ในการจัดเก็บข้อมูล (แก่ตนเอง) ก่อนจึงจะสามารถเข้าถึงไฟล์ได้
1. ฉันเริ่มแชร์ไฟล์จากโฟลเดอร์ทรัพย์สินของแอป โดยใช้ไลบรารีชื่อ "cwac -ผู้ให้บริการ" มันทำงานได้ดีกับทุกแอป ยกเว้น WhatsApp และ Viber
ใน WhatsApp ฉันได้รับบันทึกนี้ (ซึ่งคล้ายกับที่ฉันได้รับจาก Viber มาก):
02-06 17:05:04.379 24590-24590/com.whatsapp W/Bundle: คีย์ android.intent.extra.STREAM คาดหวัง ArrayList แต่ค่าเป็น android.net.Uri$HierarchicalUri ค่าเริ่มต้นถูกส่งคืน 02-06 17:05:04.382 24590-24590/com.whatsapp W/Bundle: ความพยายามในการส่งที่สร้างข้อยกเว้นภายใน: java.lang.ClassCastException: android.net.Uri$HierarchicalUri ไม่สามารถส่งไปยัง java.util.ArrayList ที่ Android .os.Bundle.getParcelableArrayList(Bundle.java:916) ที่ android.content.Intent.getParcelableArrayListExtra(Intent.java:6357) ที่ com.whatsapp.ContactPicker.k(ContactPicker.java:618) ที่ com.whatsapp.ContactPicker onCreate(ContactPicker.java:360) ที่ android.app.Activity.performCreate(Activity.java:6688) ที่ android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) ที่ android.app.ActivityThread.performLaunchActivity(ActivityThread.java :2633) ที่ android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2741) ที่ android.app.ActivityThread.-wrap12(ActivityThread.java) ที่ android.app.ActivityThread$H.handleMessage(ActivityThread.java:1488) ที่ android.os.Handler.dispatchMessage(Handler.java:102) ที่ android.os.Looper.loop(Looper.java:154) ที่ android.app.ActivityThread.main(ActivityThread.java:6169) ที่ java.lang.reflect .Method.inurge(Native Method) ที่ com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) ที่ com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
2.ฉันได้รับแจ้งแล้ว (ที่นี่ a>) เพื่อพยายามแบ่งปันโดยใส่ ArrayList<Uri>
ลงใน EXTRA_STREAM
:
ArrayList<Uri> uriArrayList=new ArrayList<>();
uriArrayList.add(getUri());
share.putExtra(Intent.EXTRA_STREAM, uriArrayList);
มันใช้งานไม่ได้ และบันทึกของ WhatsApp แสดงให้เห็นว่า:
Caused by: java.lang.SecurityException: Permission Denial: opening provider
3.ฉันยังพยายามเปลี่ยนการกระทำของเจตนาเป็น
ACTION_SEND_MULTIPLE
:at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761)
แต่มันก็ไม่ได้ช่วยอะไรเช่นกัน โดยแสดงบันทึกนี้สำหรับ Viber (ไม่เห็นอะไรพิเศษสำหรับ WhatsApp):
Intent share = new Intent(Intent.ACTION_SEND_MULTIPLE);
...
ArrayList<Uri> uriArrayList=new ArrayList<>();
uriArrayList.add(getUri());
share.putExtra(Intent.EXTRA_STREAM, uriArrayList);
02-07 09:54:07.084 926-10718/system_process W/ActivityManager: การปฏิเสธสิทธิ์: เปิดผู้ให้บริการ com.commonsware.cwac.provider.StreamProvider จาก ProcessRecord {adbb1ed 5565:com.viber.voip/u0a175} (pid=5565, uid=10175) ที่ไม่ได้ส่งออกจาก uid 10123 02-07 09:54:07.087 926-10717/system_process W/ActivityManager: การปฏิเสธสิทธิ์: การเปิดผู้ให้บริการ com.commonsware.cwac.provider.StreamProvider จาก ProcessRecord {adbb1ed 5565:com viber.voip/u0a175} (pid=5565, uid=10175) ที่ไม่ได้ส่งออกจาก uid 10123 02-07 09:54:07.091 926-946/system_process W/ActivityManager: การปฏิเสธการอนุญาต: ผู้ให้บริการเปิด com.commonsware.cwac provider.StreamProvider จาก ProcessRecord{adbb1ed 5565:com.viber.voip/u0a175} (pid=5565, uid=10175) ที่ไม่ได้ส่งออกจาก uid 10123
4. สิ่งที่แปลกก็คือสำหรับ WhatsApp ในความพยายามทั้งหมดข้างต้น มันขออนุญาตจากพื้นที่เก็บข้อมูล แม้ว่าจะไม่ควรทำเช่นนั้นก็ตาม (เพราะว่าแอปจัดเตรียมเนื้อหาด้วยตัวเองอยู่แล้ว)
5.ที่แปลกอีกอย่างที่ฉันเจอคือ แอป Google Photos ทำงานได้ดีกับการแชร์รูปภาพไปยังแอปเหล่านั้น แม้ว่ารูปภาพนั้นจะมาจากเซิร์ฟเวอร์ก็ตาม มันจะดาวน์โหลดไฟล์ที่ไหนสักแห่งและแชร์มัน ฉันไม่สามารถดูว่ามันดาวน์โหลดไฟล์ที่ไหน ฉันคิดว่ามันจะอยู่ในเส้นทางที่จัดเก็บข้อมูลภายนอกของแอป ("/.../Android/data/com.google.android.apps.photos/...") แต่ไม่มีอยู่
6. ฉันพยายามสร้าง POC ของการแชร์ไฟล์จากที่จัดเก็บข้อมูลภายนอกโดยใช้ FileProvider ของไลบรารีการสนับสนุน (ตามที่ฉันรู้วิธีใช้จากการแชร์ไฟล์ APK):
แสดงออกมา
res/xml/provider_paths.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
รหัส:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
แต่มันใช้ได้กับ WhatsApp เท่านั้น ไม่ใช่ Viber ซึ่งแสดงบันทึก
final File bitmapFile = new File(getExternalFilesDir(null), "test.jpg");
if (!bitmapFile.exists()) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), android.R.drawable.sym_def_app_icon);
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(bitmapFile));
}
Intent intent = new Intent(Intent.ACTION_SEND);
Uri fileUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", bitmapFile);
intent.setType(MimeTypeMap.getSingleton().getMimeTypeFromExtension("jpg"));
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
ฉันพยายามทำสิ่งที่ฉันทำใน #2 และ #3 แต่ก็ยังใช้งานไม่ได้กับ Viber
7. ฉันพยายามแบ่งปันไฟล์จากที่จัดเก็บข้อมูลภายนอกโดยใช้วิธีเดิมซึ่งควรจะเลิกใช้แล้วและแทนที่ด้วย FileProvider :
ใช้งานได้กับทั้งสองแอป แต่จะใช้งานได้ก็ต่อเมื่อทั้งคู่ได้รับอนุญาตจากพื้นที่เก็บข้อมูลเท่านั้น สำหรับ Viber หากไม่มีสิทธิ์ในการจัดเก็บข้อมูล ก็จะแสดงภาพสีดำ และสำหรับ WhatsApp จะขอให้ผู้ใช้อนุญาต
เหตุใดข้อใดข้อหนึ่งข้างต้นจึงไม่ทำงาน
startActivityForResult(Intent.createChooser(prepareIntentToSharePhoto(bitmapFile.getAbsolutePath(), "title",
"body"), "choose"), 1);
public static Intent prepareIntentToSharePhoto(String imagePath, String title, String body) {
Intent sharingIntent = new Intent(Intent.ACTION_SEND).setType("image/*")
.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + imagePath)).putExtra(android.content.Intent.EXTRA_SUBJECT, title)
.putExtra(android.content.Intent.EXTRA_TEXT, body);
return sharingIntent;
}
ฉันจะแชร์ไฟล์รูปภาพไปยังแอปเหล่านั้นอย่างถูกต้องได้อย่างไร มีอะไรผิดปกติแม้จะแชร์ผ่าน FileProvider เหตุใดแอป Google Photos จึงทำงานได้ดี
น่าเศร้าที่ฉันคิดว่าต้องได้รับอนุญาตจากแอปทั้งหมดในตัวเลือก
มีวิธีแก้ไขปัญหานี้หรือไม่?
มันเป็นปัญหาในแอพเองหรือบน Android หรือไม่?
พื้นหลัง
ปัญหา