Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正确地将可绘制图像共享到其他应用程序(如果没有FileProvider,将PNG共享到Whatsapp将失败)_Java_Android_Android Studio_Android Intent_Whatsapp - Fatal编程技术网

Java 正确地将可绘制图像共享到其他应用程序(如果没有FileProvider,将PNG共享到Whatsapp将失败)

Java 正确地将可绘制图像共享到其他应用程序(如果没有FileProvider,将PNG共享到Whatsapp将失败),java,android,android-studio,android-intent,whatsapp,Java,Android,Android Studio,Android Intent,Whatsapp,我正在创建一个Android应用程序,用户可以从几个图像中选择一个共享(存储在drawable文件夹中),该应用程序会打开一个标准的ACTION\u SEND chooser,允许他们将其共享到任何支持PNG的应用程序,如: Uri imageUri = Uri.parse("android.resource://com.owlswipe.imagesharer/" + getImage()); Intent sendIntent = new Intent(); sendIntent.setA

我正在创建一个Android应用程序,用户可以从几个图像中选择一个共享(存储在
drawable
文件夹中),该应用程序会打开一个标准的ACTION\u SEND chooser,允许他们将其共享到任何支持PNG的应用程序,如:

Uri imageUri = Uri.parse("android.resource://com.owlswipe.imagesharer/" + getImage());

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
sendIntent.setType("image/png");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(sendIntent, "share to an app"));

public int getImage() {
return R.drawable.firstimage;
}
// create file from drawable image
Bitmap bm = BitmapFactory.decodeResource(this.getResources(), R.drawable.yourbeautifulimage);

File filesDir = getApplicationContext().getFilesDir();
File imageFile = new File(filesDir, "ABeautifulFilename.png");

OutputStream os;
try {
    os = new FileOutputStream(imageFile);
    bm.compress(Bitmap.CompressFormat.PNG, 100, os); // 100% quality
    os.flush();
    os.close();
} catch (Exception e) {
    Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
}
但是,如果用户选择将其共享给Whatsapp,它将无法正常工作:它不会将其解释为图像(如您通常将照片共享给Whatsapp),而是认为它是一个名为“无标题”的文档,不会显示为图像

在计算机上打开此无标题文档显示其名为
DOC-20180721-WA0012。
无文件扩展名!手动将
png
添加到文件名的末尾将显示正确的图像

让这个问题变得更奇怪(但肯定是可以解决的!):

  • 例如,如果用户选择在SMS应用程序中打开图像,图像将正常显示

  • 这在多台设备上都发生过(p beta版的Pixel 2和7.1.1版的Nokia 2)

  • 这个问题在其他应用程序中不会发生,在其他应用程序中,PNG可以像普通图像一样通过Whatsapp发送(尽管它们似乎被Whatsapp自动转换为JPEG)



如何确保Whatsapp将我的图像视为正确的PNG文件?或者,我如何正确地共享应用程序中预加载的图像,以便每个应用程序都能正确地解释它?

我通过正确地实现一个文件提供程序来解决这个问题,但我会在这里做一个简短的总结

在清单的
应用程序
标记中,开始声明新的文件提供程序,如下所示:

<provider
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="${applicationId}">

    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider_paths"/>

</provider>
// create new Intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);

// set flag to give temporary permission to external app to use your FileProvider
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// generate URI, I defined authority as the application ID in the Manifest, the last param is file I want to open
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, imageFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);

// Set type to only show apps that can open your PNG file
intent.setType("image/png");

// start activity!
startActivity(Intent.createChooser(intent, "send"));
最后,在您的主要活动或其他类似活动中使用它:

<provider
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="${applicationId}">

    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider_paths"/>

</provider>
// create new Intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);

// set flag to give temporary permission to external app to use your FileProvider
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// generate URI, I defined authority as the application ID in the Manifest, the last param is file I want to open
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, imageFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);

// Set type to only show apps that can open your PNG file
intent.setType("image/png");

// start activity!
startActivity(Intent.createChooser(intent, "send"));
要从我的
drawable
目录中的图像中获取该
imageFile
,我首先将其转换为位图,然后转换为文件对象,如下所示:

Uri imageUri = Uri.parse("android.resource://com.owlswipe.imagesharer/" + getImage());

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
sendIntent.setType("image/png");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(sendIntent, "share to an app"));

public int getImage() {
return R.drawable.firstimage;
}
// create file from drawable image
Bitmap bm = BitmapFactory.decodeResource(this.getResources(), R.drawable.yourbeautifulimage);

File filesDir = getApplicationContext().getFilesDir();
File imageFile = new File(filesDir, "ABeautifulFilename.png");

OutputStream os;
try {
    os = new FileOutputStream(imageFile);
    bm.compress(Bitmap.CompressFormat.PNG, 100, os); // 100% quality
    os.flush();
    os.close();
} catch (Exception e) {
    Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
}
完成后,每个应用程序现在都可以看到您的共享图像