web-dev-qa-db-ja.com

Androidでwhatsappを介してPDFとテキストを共有する方法は?

以下のコードで試しましたが、pdfファイルが添付されていません。

Intent sendIntent = new Intent();
        sendIntent.setAction(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_TEXT, message);
        sendIntent.setType("text/plain");
        if (isOnlyWhatsApp) {
            sendIntent.setPackage("com.whatsapp");

        }

        Uri uri = Uri.fromFile(attachment);
        sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
        activity.startActivity(sendIntent);
12

アセットフォルダーからpdfファイルを開こうとしたときにこの問題が発生し、機能しませんでしたが、ダウンロードフォルダー(たとえば)から開こうとすると実際に機能しました。その例を次に示します。

File outputFile = new File(Environment.getExternalStoragePublicDirectory
    (Environment.DIRECTORY_DOWNLOADS), "example.pdf");
Uri uri = Uri.fromFile(outputFile);

Intent share = new Intent();
share.setAction(Intent.ACTION_SEND);
share.setType("application/pdf");
share.putExtra(Intent.EXTRA_STREAM, uri);
share.setPackage("com.whatsapp");

activity.startActivity(share);      
25
KHALED

TargetSdkVersionが24以上の場合、他のアプリからアクセスできるようにするために、FileProviderクラスを使用して特定のファイルまたはフォルダーへのアクセスを許可する必要があることに注意してください。

手順1: AndroidManifest.xmlのアプリケーションタグの下にFileProviderタグを追加します。

<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>

ステップ2:

次に、resフォルダーの下のxmlフォルダーにprovider_paths.xmlファイルを作成します。フォルダが存在しない場合は、作成する必要があります。ファイルの内容を以下に示します。これは、external_filesという名前でルートフォルダー(path = "。")の外部ストレージへのアクセスを共有することを示しています。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <external-path name="external_files" path="."/>
</paths>

手順3:最後の手順は、以下のコード行を変更することです

Uri photoURI = Uri.fromFile(outputFile);

Uri uri = FileProvider.getUriForFile(PdfRendererActivity.this, PdfRendererActivity.this.getPackageName() + ".provider", outputFile);

ステップ4(オプション)

インテントを使用してシステムにファイルを開かせる場合は、次のコード行を追加する必要がある場合があります。

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

これが役立つことを願っています:)

16
Idris Bohra
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                pdfUri = FileProvider.getUriForFile(this, this.getPackageName() + ".provider", pdfFile);
            } else {
                pdfUri = Uri.fromFile(pdfFile);
            }
            Intent share = new Intent();
            share.setAction(Intent.ACTION_SEND);
            share.setType("application/pdf");
            share.putExtra(Intent.EXTRA_STREAM, pdfUri);
            startActivity(Intent.createChooser(share, "Share"));

If you are using Intent.createChooser then always open chooser 
2
Dishant Kawatra

ACTION_VIEWはファイルを表示するためのものです。 ACTION_VIEWは、リスト内のPDFファイルを処理できるアプリを開きます。

startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(reportFile), "application/pdf")));

ACTION_SENDの意図は「他のアプリに送信する」ことを意味し、「どこか他の場所に送信する」ことを意味するとは思いませんでした。

1
Rahul Khurana

FileProviderを使用したのは、より優れたアプローチだからです。

最初に、プライベートパス設定でxml/file_provider_pathsリソースを追加する必要があります。

<paths>
    <files-path name="files" path="/"/>
</paths>

次に、providermanifestsに追加する必要があります

<provider
    Android:name="androidx.core.content.FileProvider"
    Android:authorities="cu.company.app.provider"
    Android:exported="false"
    Android:grantUriPermissions="true">
    <meta-data
        Android:name="Android.support.FILE_PROVIDER_PATHS"
        Android:resource="@xml/file_provider_paths" />
</provider>

そして最後にあなたのKotlinコード

fun Context.shareFile(file: File) {

    val context = this

    val intent = Intent(Intent.ACTION_SEND).apply {


        //file type, can be "application/pdf", "text/plain", etc
        type = "*/*"

        //in my case, I have used FileProvider, thats is a better approach
        putExtra(
            Intent.EXTRA_STREAM, FileProvider.getUriForFile(
                context, "cu.company.app.provider",
                file
            )
        )

        //only whatsapp can accept this intente
        //this is optional
        setPackage("com.whatsapp")

    }

    try {
        startActivity(Intent.createChooser(intent, getString(R.string.share_with)))
    } catch (e: Exception) {
        Toast.makeText(this, "We can't find WhatsApp", Toast.LENGTH_SHORT).show()
    }

}

次のコードで試してください

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());

File pdfFile = new File(Environment.getExternalStoragePublicDirectory
                       (Environment.DIRECTORY_DOWNLOADS), "Your file");
Uri uri = Uri.fromFile(pdfFile);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("application/pdf");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(shareIntent, "Share via")); 
0
ARAVIND RAJ

次のようにIntent.setTypeを追加してみてください:-

    Intent sendIntent = new Intent();
    sendIntent.setAction(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT, message);
    // sendIntent.setType("text/plain");
    if (isOnlyWhatsApp) {
        sendIntent.setPackage("com.whatsapp");
    }

    Uri uri = Uri.fromFile(attachment);
    sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
    sendIntent.setType("application/pdf");
    activity.startActivity(sendIntent);
0

テキストの共有については、以下の例をご覧ください。必要に応じて、特定の番号でテキストを共有できます。

public static void openWhatsAppConversation(Activity activity, String number) {
    boolean isWhatsappInstalled = isAppInstalled(activity, "com.whatsapp");
    if (isWhatsappInstalled) {
        Uri uri = Uri.parse("smsto:" + number);
        Intent sendIntent = new Intent(Intent.ACTION_SENDTO, uri);
        sendIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        sendIntent.setPackage("com.whatsapp");
        activity.startActivity(sendIntent);
    } else {
        ToastHelper.show(activity, "WhatsApp is not Installed!");
        openMarket(activity, "com.whatsapp");
    }
}
0
KHALED