【问题标题】:Share file uri from ACTION_PICK从 ACTION_PICK 共享文件 uri
【发布时间】:2018-12-14 22:49:33
【问题描述】:

我正在尝试制作一个应用程序,它会要求用户选择一个图像文件,然后通过意图将其发送到另一个应用程序(在这种情况下是 Whatsapp,但这应该适用于其他应用程序)

我这样做是为了请求文件:

 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);

    try {
        startActivityForResult(
                Intent.createChooser(intent, "Select a File to Upload"),
                FILE_SELECT_CODE);
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(this, "Please install a File Manager.", Toast.LENGTH_SHORT).show();
    }

这会返回一个“content://”URI,但是当通过意图发送它时:

 if (isPackageExisted(whatsAppPackage)) {
        Intent sendIntent = new Intent();
        sendIntent.setAction(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_TEXT, "Some text");
        sendIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
        sendIntent.setType("image/*");
        sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        sendIntent.setPackage(whatsAppPackage);
        startActivity(sendIntent);
    }else{
        goToGooglePlay(whatsAppPackage);
    }

Whatsapp 显示一个 toast 说文件格式不受支持,我可以在 logcat 上看到堆栈跟踪

java.lang.ClassCastException: android.net.Uri$StringUri cannot be cast to java.util.ArrayList
                                         at android.os.Bundle.getParcelableArrayList(Bundle.java:838)
                                         at android.content.Intent.getParcelableArrayListExtra(Intent.java:5405)
                                         at com.whatsapp.ContactPicker.c(ContactPicker.java:12)
                                         at com.whatsapp.ContactPicker.onCreate(ContactPicker.java:526)
                                         at android.app.Activity.performCreate(Activity.java:6251)
                                         at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                         at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                         at android.os.Handler.dispatchMessage(Handler.java:102)
                                         at android.os.Looper.loop(Looper.java:148)
                                         at android.app.ActivityThread.main(ActivityThread.java:5417)
                                         at java.lang.reflect.Method.invoke(Native Method)
                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

...

我不确定我是否可以与另一个应用程序共享“选择器应用程序”uri,这与权限有关吗?

这样做的正确方法是什么?我需要制作文件的副本以便我的应用能够共享它吗?

编辑:

这适用于 Gmail 等其他应用程序,但不适用于 whatsapp,因此有可能拥有适用于所有或大多数应用程序的解决方案吗?我不在乎我是否必须制定单独的分享方法,但必须使用whatsapp。

【问题讨论】:

  • 如果用户选择了电子邮件应用程序?
  • @greenapps 我直接针对 whatsapp 包,我没有使用选择器,这意味着仅适用于 whatsapp
  • 没关系。对于测试进行更改,以便用户可以选择电子邮件应用程序。
  • @greenapps 你一定是对的,使用 gmail 应用程序,图像已正确附加,但这不适用于 whatsapp,所以权限问题不存在?
  • 你可以尝试只分享图片然后分享我读过的文字,但我不确定你不能同时分享文字和图片

标签: android android-intent whatsapp android-sharing


【解决方案1】:

代码在真实设备上运行良好,但在安卓模拟器上却无法运行。

我没想到,我在手机里试过以防万一。

【讨论】:

    【解决方案2】:

    这个sn-p代码在模拟器和真机上都能正常工作

        private val FILE_SELECT_CODE = 101
        private val whatsAppPackage = "com.whatsapp"
    
           fun sharePicture() {
             val intent = Intent(Intent.ACTION_GET_CONTENT)
             intent.type = "image/*"
             intent.addCategory(Intent.CATEGORY_OPENABLE)
             if (intent.resolveActivity(packageManager) != null){
             startActivityForResult(
                    Intent.createChooser(intent, "Select a File to Upload"),
                    FILE_SELECT_CODE)
             }else{
                 Toast.makeText(this, "Please install a File Manager.", 
                 Toast.LENGTH_SHORT).show()
             }
          }
    
    
          override fun onActivityResult(requestCode: Int, resultCode: Int,                                       
          data: Intent?) {
             super.onActivityResult(requestCode, resultCode, data)
    
             if (resultCode == Activity.RESULT_OK) {
                 when (requestCode) {
                     FILE_SELECT_CODE -> {
                            val sendIntent = Intent()
                            sendIntent.action = Intent.ACTION_SEND
                            sendIntent.putExtra(Intent.EXTRA_TEXT, "Some text")
                            sendIntent.putExtra(Intent.EXTRA_STREAM, data!!.data)
                            sendIntent.type = "image/*"
                            sendIntent.addFlags(
                                                Intent.FLAG_GRANT_READ_URI_PERMISSION)
                            sendIntent.`package` = whatsAppPackage
                         if (sendIntent.resolveActivity(packageManager) != null) {
                            startActivity(sendIntent)
                         } else {
                              goToGooglePlay(whatsAppPackage)
                         }
                   }
                }
             } 
          }
    
    
           fun goToGooglePlay(appPackageName: String) {
             val playIntent = Intent(Intent.ACTION_VIEW, 
                              Uri.parse("market://details?id=$appPackageName"))
    
             if (playIntent.resolveActivity(packageManager) != null){
                 startActivity(playIntent)
             }else
                 startActivity(Intent(Intent.ACTION_VIEW, 
                            Uri.parse("https://play.google.com/store/apps/details? id=$appPackageName")))
            }
    
    
           fun isPackageExisted(packageName: String): Boolean {
               val pm = packageManager
               val isInstalled: Boolean
               isInstalled = try {
                   pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
                   true
               } catch (e: PackageManager.NameNotFoundException) {
                   false
               }
    
              return isInstalled
           }
    

    【讨论】:

    • 如果知道有包已经存在,最好使用“intent.resolveActivity(packageManager)”而不是“try-catch”
    • 这是我使用的相同代码,在模拟器 whatsapp 中说不支持图像格式
    【解决方案3】:

    正如您的代码日志所说,您不能将 uri 转换为 String Arraylist

    所以尝试将 StringURI 转换为 ArrayListURI 像这样

    ArrayList<Uri> tempURI = new ArrayList<>();
    tempURI.add(imageUri); //Your String URI
    

    现在有意识地传递tempURI

    sendIntent.putExtra(Intent.EXTRA_STREAM, tempURI);
    

    试试这个并检查它是否在模拟器上运行..

    也读过这个

    ACTION_SEND 支持EXTRA_STREAM,但仅适用于单个 UriACTION_SEND_MULTIPLE 支持 EXTRA_STREAMArrayList&lt;Uri&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      • 2016-03-05
      相关资源
      最近更新 更多