问题
So I have a Share button that will share an image and a body of text.
On Nougat (API 25) and Oreo (API 26), it works absolutely perfectly. But when it comes to a couple older version it doesn't work as expected.
Marshmallow (API 23): Inserts the image just fine but no body of text. Lollipop (API 22): Crashes when you push the Share button with popup error "Unfortunately, Messaging has stopped." LOGCAT isn't showing me any errors when this happens.
Here is my share button code:
if (id == R.id.action_shareWine) {
Intent intentShare = new Intent(Intent.ACTION_SEND);
intentShare.putExtra(intentShare.EXTRA_STREAM, imageURI);
intentShare.setType("image/*");
intentShare.putExtra(Intent.EXTRA_TEXT, "body of text goes here");
if (intentShare.resolveActivity(getPackageManager()) != null) {
startActivity(intentShare);
}
return true;
}
Here is a picture to give a visual idea of whats going on:
Anyone have any ideas what could be going on here?
UPDATE 1
Here is the crash log for the Lollipop emulator:
FATAL EXCEPTION: Mms-1
Process: com.android.mms, PID: 7570
java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
Which I'm not sure why it is happening because the cursor is loading the image just fine in an ImageView in that same activity.
回答1:
Call addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
on the ACTION_SEND
Intent
, to allow third parties the ability to read the content identified by the Uri
.
Also, since the image would appear to be a JPEG (based on the file extension), the MIME type is image/jpeg
, not image/*
or image/png
.
回答2:
For More Details
working in Oreo and Marshmallow Version Read this
https://developer.android.com/reference/android/support/v4/content/FileProvider.html
Source Code
https://drive.google.com/open?id=1vfO43dMSt096CMp6nrOJNl3fJAf6MPwG
create xml folder inside providers_path.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.holostik.sharescreenshotexample">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.holostik.sharescreenshotexample.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
package com.holostik.sharescreenshotexample;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.holostik.sharescreenshotexample.share.ScreenshotType;
import com.holostik.sharescreenshotexample.share.ScreenshotUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
int n;
String photoPath;
LinearLayout rootContent;
ImageView iv_share;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootContent = (LinearLayout) findViewById(R.id.rootContent);
iv_share = (ImageView) findViewById(R.id.iv_share);
iv_share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
Log.e("MainActivity ", "P granted");
takeScreenshot(ScreenshotType.FULL);
} else {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 1);
}
} else {
Log.e("MainActivity", "Lower Than MarshMallow");
takeScreenshot(ScreenshotType.FULL);
}
}
});
}
/* Method which will take screenshot on Basis of Screenshot Type ENUM */
private void takeScreenshot(ScreenshotType screenshotType) {
Bitmap b = null;
switch (screenshotType) {
case FULL:
b = ScreenshotUtils.getScreenShot(rootContent);
break;
case CUSTOM:
//If Screenshot type is CUSTOM
break;
}
//If bitmap is not null
if (b != null) {
// showScreenShotImage(b);//show bitmap over imageview
Log.e("keshav", "bitmap is -- > " + b);
SaveImage(b);
shareScreenshot();
/* File saveFile = ScreenshotUtils.getMainDirectoryName(MainActivity.this);//get the path to save screenshot
File file = ScreenshotUtils.store(b, "screenshot" + screenshotType + ".jpg", saveFile);//save the screenshot to selected path
shareScreenshot(file);//finally share screenshot
Log.e("file Path", String.valueOf(file));
*/
} else
//If bitmap is null show toast message
Toast.makeText(MainActivity.this, R.string.screenshot_take_failed, Toast.LENGTH_SHORT).show();
}
private void SaveImage(Bitmap finalBitmap)
{
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/* TODO Show screenshot Bitmap */
// private void showScreenShotImage(Bitmap b) {
// imageView.setImageBitmap(b);
// }
private void shareScreenshot()
{
photoPath = Environment.getExternalStorageDirectory() + "/saved_images" + "/Image-" + n + ".jpg";
File F = new File(photoPath);
//Uri U = Uri.fromFile(F);
// Uri U = FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".my.package.name.provider", F);
// TODO your package name as well add .fileprovider
Uri U = FileProvider.getUriForFile(MainActivity.this.getApplicationContext(), "com.holostik.sharescreenshotexample.fileprovider", F);
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("image/png");
i.putExtra(Intent.EXTRA_STREAM, U);
startActivityForResult(Intent.createChooser(i, "Email:"), 1);
}
// TODO Share Screen SHOT End ..............
}
来源:https://stackoverflow.com/questions/46736968/why-is-my-action-send-working-on-api-25-perfectly-but-messes-up-on-previous-ap