0

This question is related to this previously answered question Share Image on Android Application from Unity Game

My question is this:

Is there a way to share the image WITHOUT using a file? I'd like to remove the sd card read/write permission on Android. I'm not a Java programmer, so I'm having a heck of a time getting it working. None of my attempts have yielded anything.

"Programmer" answered the previous question with the below code, which works great for me. I basically want to use the variable imageBytes instead of the file. Is this even possible?

void takeScreenShotAndShare()
{
    StartCoroutine(takeScreenshotAndSave());
}

private IEnumerator takeScreenshotAndSave()
{
    string path = "";
    yield return new WaitForEndOfFrame();

    Texture2D screenImage = new Texture2D(Screen.width, Screen.height);

    //Get Image from screen
    screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    screenImage.Apply();

    //Convert to png
    byte[] imageBytes = screenImage.EncodeToPNG();


    System.IO.Directory.CreateDirectory(Application.persistentDataPath + "/GameOverScreenShot");
    path = Application.persistentDataPath + "/GameOverScreenShot" + "/DiedScreenShot.png";
    System.IO.File.WriteAllBytes(path, imageBytes);

    StartCoroutine(shareScreenshot(path));
}

private IEnumerator shareScreenshot(string destination)
{
    string ShareSubject = "Picture Share";
    string shareLink = "Test Link" + "\nhttps://stackoverflow.com/questions/36512784/share-image-on-android-application-from-unity-game";
    string textToShare = "Text To share";

    Debug.Log(destination);


    if (!Application.isEditor)
    {

        AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent");
        AndroidJavaObject intentObject = new AndroidJavaObject("android.content.Intent");
        intentObject.Call<AndroidJavaObject>("setAction", intentClass.GetStatic<string>("ACTION_SEND"));
        AndroidJavaClass uriClass = new AndroidJavaClass("android.net.Uri");
        AndroidJavaObject uriObject = uriClass.CallStatic<AndroidJavaObject>("parse", "file://" + destination);

        intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_STREAM"), uriObject);
        intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), textToShare + shareLink);
        intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_SUBJECT"), ShareSubject);
        intentObject.Call<AndroidJavaObject>("setType", "image/png");
        AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
        currentActivity.Call("startActivity", intentObject);
    }
    yield return null;
}

Unity3d share image on android

Community
  • 1
  • 1

1 Answers1

0

You can directly pass the byte array, no need to convert it to file -> uri -> string

Below are java code, but you can easily translate this to JNI wrapper calls

Bundle bundle = new Bundle();
bundle.putByteArray("byteArr", imageBytes); //put byte array to bundle!!!
Intent intent = new Intent(...);
intent.putExtra(bundle );

To retrieve the image byte array in another activity, use below code:

getIntent().getByteArrayExtra("byteArr");

If you wrap each above function calls into a corresponding JNI function, it would be very tedious. You can on the other hand:

  • Create an android library project
  • Add two static java functions, one is saveByteArrayToBundle(...), and the other is getByteArrayFromBundle(...)
  • Compile the android library into an aar file;
  • then put the aar file into the Assets/ folder (actually any subfolders will do)
  • Then call the two static java functions as you have done in the OP

Refer to below tutorials if you need to go through step-by-step:

David
  • 15,894
  • 22
  • 55
  • 66