-1

I'm trying to send a JSON object and an associated thumbnail to Google+. But I'm having trouble getting it to work. I get, for instance, the response:

05-30 22:38:16.819: E/AndroidRuntime(11643): FATAL EXCEPTION: main
05-30 22:38:16.819: E/AndroidRuntime(11643): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.SEND typ=application/json flg=0x80000 pkg=com.google.android.apps.plus (has extras) }
05-30 22:38:16.819: E/AndroidRuntime(11643):    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1409)

which tells me the Google+ libraries aren't finding the proper way to handle the "application/json" MIME type. My code (relevant part) runs like this (I obtained most of it from the Google+ examples):

PlusShare.Builder builder = new PlusShare.Builder(this, plusClient);

// Set call-to-action metadata.
builder.addCallToAction("VIEW_ITEM", callToActionUrl, callToActionDeepLinkId);
File thumbnailFile = generateThumbnail();
builder.setStream(Uri.fromFile(outputJSON()));
builder.setType("application/json");
thumbnailFile!=null?Uri.fromFile(thumbnailFile):null);

and if I avoid setting the stream to the JSON type, it seems to be working all right. The JSON I'm generating is like this:

{"INSTRUMENTS":
      [{"MINOR":false,"CHANNEL":0,"MAJOR":false,"HIGH_RANGE":-8012206,
        "PROGRAM":1,"MAX_KEY":70,"NOTE_LENGTH":150,"LOW_RANGE":-16217748,
        "MIN_VELOCITY":60,"MIN_KEY":40},
       {"MINOR":false,"CHANNEL":2,"MAJOR":true,"HIGH_RANGE":-2790500,
        "PROGRAM":8,"MAX_KEY":90,"NOTE_LENGTH":150,"LOW_RANGE":-12114977,
        "MIN_VELOCITY":60,"MIN_KEY":70}]}

I've seen different APIs which tell how to send JSON objects like these with Bitmaps and what-have-you but the Android API documentations is slightly... sparse. Anyone out there who knows how I can manage to do the same stuff in Android?

Ideally, once done correctly, the post should contain:

  1. A thumbprint of an image
  2. JSON data which, when an user clicks on the post from an Android device, will be used by my app through deep-linking
  3. Text/title written by the user
DigCamara
  • 5,540
  • 4
  • 36
  • 47
  • Could you post more complete code. Its not clear how you are defining your 'builder' variable. Also, could you indicate what you are hoping the resulting post will look like - ie. how are you intending that Google+ will handle application/json mime types? – Lee May 31 '13 at 09:19
  • @Lee : I added the code that shows the builder's instantiation. I also added an explanation as to what I'm trying to accomplish. – DigCamara May 31 '13 at 13:16

2 Answers2

2

You cannot attach images or JSON data to an interactive post. So there is no simple answer to your question.

One option would be to use a normal post instead of an interactive post to share your thumbnail like this - http://googleplusplatform.blogspot.co.uk/2012/05/sharing-rich-content-from-your-android.html, but you will not be able to attach your JSON data to this post either.

A second alternative approach using an interactive post would be to set a publicly visible URL which is the content of the post with builder.setContentUrl(Uri). If you create a page which contained the following, for example:

<body itemscope itemtype="http://schema.org/WebPage">

<div itemscope itemtype="http://schema.org/Thing">

<img itemprop="image" src="http://example.com/path/to/thumbnail.jpg" />
<span itemprop="name">Name of your thing</span> 

<div class="data">{"INSTRUMENTS":
  [{"MINOR":false,"CHANNEL":0,"MAJOR":false,"HIGH_RANGE":-8012206,
    "PROGRAM":1,"MAX_KEY":70,"NOTE_LENGTH":150,"LOW_RANGE":-16217748,
    "MIN_VELOCITY":60,"MIN_KEY":40},
   {"MINOR":false,"CHANNEL":2,"MAJOR":true,"HIGH_RANGE":-2790500,
    "PROGRAM":8,"MAX_KEY":90,"NOTE_LENGTH":150,"LOW_RANGE":-12114977,
    "MIN_VELOCITY":60,"MIN_KEY":70}]}</div>

</div>
</body>

And made it available at http://example.com/item1, then you would be able to create an interactive post like this:

PlusShare.Builder builder = new PlusShare.Builder(this, plusClient);

// Set call-to-action metadata.
builder.setContentUrl(Uri.parse("http://example.com/thing1"));
builder.addCallToAction("VIEW_ITEM", Uri.parse("http://example.com/thing1"), deepLinkId);

This would mean however that you had to load and parse the page to retrieve your JSON data, which might be better hosted at a different URL.

You could put your JSON data in the deepLinkId itself, but beware that deepLinkId is limited to 512 characters because it is not intended to carry data - only to identify a resource.

Lee
  • 3,972
  • 22
  • 17
  • Yeah... that's pretty where I thought I'd have to go. Do you know why they have methods like 'setStream()' and 'setType()'? They seem pretty useless to me. – DigCamara Jun 04 '13 at 12:09
  • I'm sure setStream and addStream are intended to mirror the usage in http://developer.android.com/reference/android/support/v4/app/ShareCompat.IntentBuilder.html but they don't seem to work in the same way. – Lee Jun 04 '13 at 12:20
  • Seems like it. I think your answer is right, but since there is no good official documentation that describes the "real" way this should work, I'll leave the question open for a while yet. – DigCamara Jun 04 '13 at 12:32
0

Another approach to Lee's that might work but you could potentially pass the JSON data as the deep link ID for a post. You'd probably want to base64 encode the data, use it as the deep link ID, and then when you capture the incoming deep link, unencode the data and parse it.

You'd have to ensure that the encoded JSON data stayed under 512 characters. Your current JSON snippet comes in at 524 characters when encoded though.

byte[] data = jsonData.getBytes("UTF-8");
String base64Json = Base64.encodeToString(data, Base64.DEFAULT);

if (base64.length() <= 512) {
Intent shareIntent = new PlusShare.Builder(this)
        .setText("Lemon Cheesecake recipe")
        .setType("text/plain")
        .setContentDeepLinkId(base64Json, /** Deep-link identifier */
                "Lemon Cheesecake recipe", /** Snippet title */
                "A tasty recipe for making lemon cheesecake.", /** Snippet description */
                Uri.parse("http://example.com/static/lemon_cheesecake.png"))
        .getIntent();

startActivityForResult(shareIntent, 0);
} else {
  // Do something different such as regular share, or try to get encoded length under 512
}

For the incoming link to your app, you would read an unencode this data and make use of it. You'd need to be very careful about validating the data.

BrettJ
  • 6,801
  • 1
  • 23
  • 26