จะแชร์ไฟล์รูปภาพไปยัง WhatsApp และ Viber บน Android 7.1.1 ได้อย่างไร

สิ่งที่ฉันพยายามและพบ

คล้ายกับปัญหาที่ฉันเคยพบเกี่ยวกับการแชร์/เปิดไฟล์ 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.ฉันได้รับแจ้งแล้ว (ที่นี่) เพื่อพยายามแบ่งปันโดยใส่ 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 หรือไม่?

พื้นหลัง

ปัญหา


person android developer    schedule 07.02.2017    source แหล่งที่มา
comment
@AviParshan ลิงก์ที่คุณให้ไว้ใช้สำหรับส่งข้อความเท่านั้น ถามเรื่องส่งไฟล์ภาพครับ เกี่ยวกับการอนุญาตพื้นที่เก็บข้อมูล เริ่มต้นจากเวอร์ชัน Android เฉพาะ (API 19 - Kitkat) คุณไม่จำเป็นต้องมีสิทธิ์ในการจัดเก็บข้อมูลเพื่อเขียนไฟล์ลงในที่จัดเก็บข้อมูลภายนอกเฉพาะของแอปของคุณเอง (อ่านที่นี่: developer.android.com/reference/android/ ) แอปสามารถเขียนและอ่านจากไฟล์นี้ได้อย่างสมบูรณ์แบบ และฉันเห็นได้ผ่านตัวจัดการไฟล์ว่าทำได้สำเร็จ ฉันพยายามเพิ่ม&ให้สิทธิ์นี้เผื่อไว้ มันไม่ได้ช่วยอะไร   -  person Avi Parshan    schedule 07.02.2017
comment
ฉันสามารถทำได้ค่อนข้างง่ายสำหรับแอปสร้างมีมที่ฉันสร้างขึ้น ฉันจะโพสต์รหัสในคำตอบในวันนี้ โดยพื้นฐานแล้วจะส่งความตั้งใจในการแชร์ ส่งรูปภาพ และข้อความบางส่วน (ไม่บังคับ) ไปด้วย ฉันสามารถโพสต์ไปที่ Whatsapp ได้ มันแปลกที่มันทำงานกับรูปภาพ แต่ไม่ใช่แอพอื่น ๆ คุณสามารถแบ่งปันภาพความตั้งใจในการแบ่งปันได้หรือไม่?   -  person Avi Parshan    schedule 07.02.2017
comment
@AviParshan ดูรหัส แอปตัวอย่างสร้างรูปภาพแบบไดนามิก ฉันได้เขียนโค้ดที่ใช้งานได้เหมือนกันใน #7 (ซึ่งฉันคิดว่าเป็นสิ่งที่คุณอาจใช้) แต่ต้องใช้ทั้ง WhatsApp และ Viber เพื่อขออนุญาตพื้นที่เก็บข้อมูล ในขณะที่เดิมทีพวกเขาไม่ต้องการมันหากใช้วิธีมาตรฐานเท่านั้น แบ่งปันเนื้อหา   -  person android developer    schedule 07.02.2017
comment
@androiddeveloper คุณลองแชร์โดยตรงกับ whatsup.. _1_ หรือไม่?   -  person Avi Parshan    schedule 07.02.2017
comment
@sunilsunny ใช่ครับ ฉันทำ. มันไม่ได้ช่วยอะไร   -  person android developer    schedule 07.02.2017
comment
ขอบคุณสำหรับการทำวิจัยมาก ฉันจะแจ้งให้คุณทราบหากฉันพบสิ่งใด   -  person sunil sunny    schedule 07.02.2017
comment
com.commonsware.cwac.provider.StreamProvider จาก ProcessRecord{9405e93 12914:com.whatsapp/u0a210} (pid=12914, uid=10210) ที่ไม่ได้ส่งออกจาก uid 10123 ที่ android.os.Parcel.readException(Parcel.java: 1684) ที่ android.os.Parcel.readException(Parcel.java:1637) ที่ android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4213) ที่ android.app.ActivityThread.acquireProvider(ActivityThread.java:5526) ที่ android app.contextimpl $ applicationcontentresolver.acquireunstableprovider (contextimpl.java:2239) ที่ Android.content.contentresolver.acquireunstableprovider (ContentResolver.java:1517) Android.content.contentresolver .openAssetFileDescriptor(ContentResolver.java:984) ที่ android.content.ContentResolver.openInputStream(ContentResolver.java:704) ที่ com.whatsapp.util.ah.b(MediaFileUtils.java:1290) ที่ com.whatsapp.util.ah a(MediaFileUtils.java:1498) ที่ com.whatsapp.util.ah.a(MediaFileUtils.java:1543) ที่ com.whatsapp.gallerypicker.ImagePreview$b$1.a(ImagePreview.java:901) ที่ com.whatsapp gallerypicker.ImagePreview$b$1.doInBackground(ImagePreview.java:896) ที่ android.os.AsyncTask$2.call(AsyncTask.java:305) ที่ java.util.concurrent.FutureTask.run(FutureTask.java:237) ที่ Android .os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) ที่ java.util.concurrent ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)   -  person android developer    schedule 07.02.2017
comment
02-07 10:21:19.285 24043-24043/com.viber.voip W/Bundle: คีย์ android.intent.extra.STREAM คาดหวัง ArrayList แต่ค่าเป็น android.net.Uri$HierarchicalUri ค่าเริ่มต้นถูกส่งคืน 02-07 10:21:19.285 24043-24043/com.viber.voip 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.viber.voip.util.af.f(SourceFile:156) ที่ com viber.voip.util.af.a(SourceFile:106) ที่ com.viber.voip.HomeActivity.i(SourceFile:487) ที่ com.viber.voip.HomeActivity.onCreate(SourceFile:317) ที่ 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.invoid(Native Method) ที่ com.android.internal .os. ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) ที่ com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)   -  person sbaar    schedule 22.03.2017


คำตอบ (1)


หาก Viber ยังไม่อนุญาต ก็จะแสดงหน้าจอสีดำ

ลองดูที่: whatsapp.com/faq/en/android/28000012

คุณใช้ที่จัดเก็บข้อมูลภายนอกและคุณได้ขออนุญาตใช้หรือไม่

person android developer    schedule 07.02.2017