Highlighted

Adobe AIR + Android ANE for SEND intents

Community Beginner ,
Apr 12, 2016

Copy link to clipboard

Copied

Hoping for help as I am desperately trying to get this to work since two days.

My goal is to receive text and images in my Adobe AIR app via the "Share" popup on Android.

Yes, I am aware of the documented solution with the InvokeEvent that is supposed to work but it doesn't work with android.intent.action.SEND - the  InvokeEvents are dispatched in the app but all arguments are always empty. If someone knows about a solution there please let me know.

So I have tried to implement an ANE to catch up these intents and pass them into my app. First, here is my setup:

AIR and ANE (Android) app descriptors look the same - inside of the manifest part I have this:

       <application android:enabled="true">

  <activity>

        <intent-filter>

          <action android:name="android.intent.action.MAIN"/>

          <category android:name="android.intent.category.LAUNCHER"/>

      </intent-filter>

  </activity>

  <activity android:name="com.mypackage.androidsendintent.SendIntentActivity">

     <intent-filter>

         <action android:name="android.intent.action.SEND" />

         <category android:name="android.intent.category.DEFAULT" />

         <data android:mimeType="text/plain" />

         <data android:mimeType="image/*" />

     </intent-filter>

     <intent-filter>

         <action android:name="android.intent.action.SEND_MULTIPLE" />

         <category android:name="android.intent.category.DEFAULT" />

         <data android:mimeType="image/*" />

     </intent-filter>

  </activity>

  </application>

My Activity JAVA file:

  package com.mypackage.androidsendintent;

  import java.util.ArrayList;

  import android.app.Activity;

  import android.content.Intent;

  import android.net.Uri;

  import android.os.Bundle;

  import android.util.Log;

  public class SendIntentActivity extends Activity

  {

  public static final String TAG = "SendIntentActivity";

  private AndroidSendIntentContext sendIntentContext = AndroidSendIntentContext.getInstance();

  @Override

  protected void onCreate (Bundle savedInstanceState)

  {

  super.onCreate(savedInstanceState);

     // Get intent, action and MIME type

     Intent intent = getIntent();

     String action = intent.getAction();

     String type = intent.getType(); 

    

     Log.d(TAG, "ACTIVITY");

     if (Intent.ACTION_SEND.equals(action) && type != null)

     {

         if ("text/plain".equals(type))

         {

             handleSendText(intent); // Handle text being sent

         }

         else if (type.startsWith("image/"))

         {

             handleSendImage(intent); // Handle single image being sent

         }

     }

     else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null)

     {

         if (type.startsWith("image/"))

         {

             handleSendMultipleImages(intent); // Handle multiple images being sent

         }

     }

     else

     {

         // Handle other intents, such as being started from the home screen

     }   

  }

  void handleSendText(Intent intent)

  {

     String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);

     if (sharedText != null)

     {

         // Update UI to reflect text being shared

      Log.d(TAG, "handleSendText " + sharedText);

      sendIntentContext.dispatchStatusEventAsync("SHARED_TEXT", sharedText);

     }

  }

  void handleSendImage(Intent intent)

  {

     Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);

   

     if (imageUri != null)

     {

         // Update UI to reflect image being shared

      Log.d(TAG, "handleSendImage " + imageUri);

    

      sendIntentContext.dispatchStatusEventAsync("SHARED_IMAGES", imageUri.toString());

     }

  }

  void handleSendMultipleImages(Intent intent)

  {

     ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);

    

     if (imageUris != null)

     {

         // Update UI to reflect multiple images being shared

      Log.d(TAG, "handleSendMultipleImages " + imageUris);

    

      String listString = "";

    

      for (Uri myUri : imageUris)

      {

      if(listString != "")

      listString += ",";

    

         listString += myUri.toString();

      }

    

      sendIntentContext.dispatchStatusEventAsync("SHARED_IMAGES", listString);

     }

  }

  }

It is quite working but there are two problems:

1. When i share something another (blank) screen is coming up with the name of my app but the app (that is running in background) still receiving the data, so basically I need to switch to my app to see the shared content. This sounds like something small I'm missing?

2. When the app is NOT already running in the background I'm getting an exception:

     FATAL EXCEPTION: main

java.lang.UnsatisfiedLinkError: Native method not found: com.adobe.fre.FREContext.dispatchStatusEventAsync:(Ljava/lang/String;Ljava/lang/String;)V

  at com.adobe.fre.FREContext.dispatchStatusEventAsync(Native Method)

  at com.mypackage.androidsendintent.SendIntentActivity.handleSendText(SendIntentActivity.java:61)

  at com.mypackage.androidsendintent.SendIntentActivity.onCreate(SendIntentActivity.java:33)

  at android.app.Activity.performCreate(Activity.java:5104)

  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)

  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)

  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)

  at android.app.ActivityThread.access$600(ActivityThread.java:141)

  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)

  at android.os.Handler.dispatchMessage(Handler.java:99)

  at android.os.Looper.loop(Looper.java:137)

  at android.app.ActivityThread.main(ActivityThread.java:5039)

  at java.lang.reflect.Method.invokeNative(Native Method)

  at java.lang.reflect.Method.invoke(Method.java:511)

Looks like there is some problem with the FreContent ?

I would appreciate any help, getting desperate here. Thank you for your time !

TOPICS
Development

Views

2.2K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Adobe AIR + Android ANE for SEND intents

Community Beginner ,
Apr 12, 2016

Copy link to clipboard

Copied

Hoping for help as I am desperately trying to get this to work since two days.

My goal is to receive text and images in my Adobe AIR app via the "Share" popup on Android.

Yes, I am aware of the documented solution with the InvokeEvent that is supposed to work but it doesn't work with android.intent.action.SEND - the  InvokeEvents are dispatched in the app but all arguments are always empty. If someone knows about a solution there please let me know.

So I have tried to implement an ANE to catch up these intents and pass them into my app. First, here is my setup:

AIR and ANE (Android) app descriptors look the same - inside of the manifest part I have this:

       <application android:enabled="true">

  <activity>

        <intent-filter>

          <action android:name="android.intent.action.MAIN"/>

          <category android:name="android.intent.category.LAUNCHER"/>

      </intent-filter>

  </activity>

  <activity android:name="com.mypackage.androidsendintent.SendIntentActivity">

     <intent-filter>

         <action android:name="android.intent.action.SEND" />

         <category android:name="android.intent.category.DEFAULT" />

         <data android:mimeType="text/plain" />

         <data android:mimeType="image/*" />

     </intent-filter>

     <intent-filter>

         <action android:name="android.intent.action.SEND_MULTIPLE" />

         <category android:name="android.intent.category.DEFAULT" />

         <data android:mimeType="image/*" />

     </intent-filter>

  </activity>

  </application>

My Activity JAVA file:

  package com.mypackage.androidsendintent;

  import java.util.ArrayList;

  import android.app.Activity;

  import android.content.Intent;

  import android.net.Uri;

  import android.os.Bundle;

  import android.util.Log;

  public class SendIntentActivity extends Activity

  {

  public static final String TAG = "SendIntentActivity";

  private AndroidSendIntentContext sendIntentContext = AndroidSendIntentContext.getInstance();

  @Override

  protected void onCreate (Bundle savedInstanceState)

  {

  super.onCreate(savedInstanceState);

     // Get intent, action and MIME type

     Intent intent = getIntent();

     String action = intent.getAction();

     String type = intent.getType(); 

    

     Log.d(TAG, "ACTIVITY");

     if (Intent.ACTION_SEND.equals(action) && type != null)

     {

         if ("text/plain".equals(type))

         {

             handleSendText(intent); // Handle text being sent

         }

         else if (type.startsWith("image/"))

         {

             handleSendImage(intent); // Handle single image being sent

         }

     }

     else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null)

     {

         if (type.startsWith("image/"))

         {

             handleSendMultipleImages(intent); // Handle multiple images being sent

         }

     }

     else

     {

         // Handle other intents, such as being started from the home screen

     }   

  }

  void handleSendText(Intent intent)

  {

     String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);

     if (sharedText != null)

     {

         // Update UI to reflect text being shared

      Log.d(TAG, "handleSendText " + sharedText);

      sendIntentContext.dispatchStatusEventAsync("SHARED_TEXT", sharedText);

     }

  }

  void handleSendImage(Intent intent)

  {

     Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);

   

     if (imageUri != null)

     {

         // Update UI to reflect image being shared

      Log.d(TAG, "handleSendImage " + imageUri);

    

      sendIntentContext.dispatchStatusEventAsync("SHARED_IMAGES", imageUri.toString());

     }

  }

  void handleSendMultipleImages(Intent intent)

  {

     ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);

    

     if (imageUris != null)

     {

         // Update UI to reflect multiple images being shared

      Log.d(TAG, "handleSendMultipleImages " + imageUris);

    

      String listString = "";

    

      for (Uri myUri : imageUris)

      {

      if(listString != "")

      listString += ",";

    

         listString += myUri.toString();

      }

    

      sendIntentContext.dispatchStatusEventAsync("SHARED_IMAGES", listString);

     }

  }

  }

It is quite working but there are two problems:

1. When i share something another (blank) screen is coming up with the name of my app but the app (that is running in background) still receiving the data, so basically I need to switch to my app to see the shared content. This sounds like something small I'm missing?

2. When the app is NOT already running in the background I'm getting an exception:

     FATAL EXCEPTION: main

java.lang.UnsatisfiedLinkError: Native method not found: com.adobe.fre.FREContext.dispatchStatusEventAsync:(Ljava/lang/String;Ljava/lang/String;)V

  at com.adobe.fre.FREContext.dispatchStatusEventAsync(Native Method)

  at com.mypackage.androidsendintent.SendIntentActivity.handleSendText(SendIntentActivity.java:61)

  at com.mypackage.androidsendintent.SendIntentActivity.onCreate(SendIntentActivity.java:33)

  at android.app.Activity.performCreate(Activity.java:5104)

  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)

  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)

  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)

  at android.app.ActivityThread.access$600(ActivityThread.java:141)

  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)

  at android.os.Handler.dispatchMessage(Handler.java:99)

  at android.os.Looper.loop(Looper.java:137)

  at android.app.ActivityThread.main(ActivityThread.java:5039)

  at java.lang.reflect.Method.invokeNative(Native Method)

  at java.lang.reflect.Method.invoke(Method.java:511)

Looks like there is some problem with the FreContent ?

I would appreciate any help, getting desperate here. Thank you for your time !

TOPICS
Development

Views

2.2K

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Apr 12, 2016 1
Explorer ,
Nov 08, 2016

Copy link to clipboard

Copied

posted same problem here:

Air Android - Adapt the intent filter for receiving content from other apps

Did you manage to fix the ANE code?

Put it on github, so others can also benefit

from the solution, even partially... )

Without being able to get SEND intent, is no game.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 08, 2016 0
Explorer ,
Jul 13, 2017

Copy link to clipboard

Copied

When the app is not running you should start it with intent but to pass air app parameters you should use custom scheme

for example myapp

protected void restartApp(String sharedText)

    {

        Intent launchIntent = null;

        try {

            launchIntent = Intent.parseUri("myapp://send/"+sharedText, Intent.URI_INTENT_SCHEME);

        } catch (URISyntaxException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

            Log.e(TAG, "couldn't get intent to restart app "+e.getMessage());

        }

        if(launchIntent != null) {

            launchIntent.addCategory(Intent.CATEGORY_BROWSABLE);

            launchIntent.setComponent(null);

            startActivity(launchIntent);

        } else {

            Log.e(TAG, "couldn't get intent to restart app");

        }

}

the you can get this arguments on application invoke event.

also you have to add intent filter to  adobe air application manifest xml file

<intent-filter>

     <action android:name="android.intent.action.VIEW"/>

    <category android:name="android.intent.category.BROWSABLE"/>

    <category android:name="android.intent.category.DEFAULT"/>

    <data android:scheme="myapp" />

</intent-filter>

please vote for adobe air native solution for this issue

Tracker

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Jul 13, 2017 0
Explorer ,
Sep 01, 2017

Copy link to clipboard

Copied

Hi fullflash, do you have any example of this method?

If you uploaded to github or you can send me the code, my email is goratz@gmail.com.

Thank you very much.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 01, 2017 0
Explorer ,
Sep 02, 2017

Copy link to clipboard

Copied

add you custom activity inside application tag in the android manifest xml

<activity android:name="com.yourapp.activity.SendIntentActivity">

                    <intent-filter>

                        <action android:name="android.intent.action.SEND" />

                        <category android:name="android.intent.category.DEFAULT" />

                        <data android:mimeType="text/plain" />

                    </intent-filter>

</activity>

register you custom scheme in the android manifest xml this wil be used in activity below to restart you air app if it is not running

if app is running pass the data via dispatchStatusEventAsync

  1. <intent-filter>  
  2. <action android:name="android.intent.action.VIEW"/>  
  3. <category android:name="android.intent.category.BROWSABLE"/>  
  4. <category android:name="android.intent.category.DEFAULT"/>  
  5. <data android:scheme="myapp" /> 
  6. </intent-filter>

define an activity in your ane

package com.yourapp.activity;

...........

public class SendIntentActivity extends Activity {

    public static final String TAG = "SendIntentActivity";

//    protected String airPackageName;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

      

       

        super.onCreate(savedInstanceState);

       

        Intent intent = getIntent();

        String action = intent.getAction();

        String type = intent.getType();

     

        if (Intent.ACTION_SEND.equals(action) && type != null) {

             handleSendText(intent); // Handle text being sent

        }

    }

   

    private void handleSendText(Intent intent) {

        String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);

        if (sharedText != null){

            if(MyAneExtension.context==null){

                Log.d(TAG, "context is null restarting air app");

                restartApp(sharedText);

            }else{

                //app is running just send data ,dispatch event

             

                MyAneExtension.context.dispatchStatusEventAsync("SHARED_TEXT",sharedText);

            }

        }

    }

  1. protected void restartApp(String sharedText) 
  2.     { 
  3.         Intent launchIntent = null; 
  4.         try { 
  5.             launchIntent = Intent.parseUri("myapp://send/"+sharedText, Intent.URI_INTENT_SCHEME); 
  6.         } catch (URISyntaxException e) { 
  7.             // TODO Auto-generated catch block 
  8.             e.printStackTrace(); 
  9.             Log.e(TAG, "couldn't get intent to restart app "+e.getMessage()); 
  10.         } 
  11.         if(launchIntent != null) { 
  12.             launchIntent.addCategory(Intent.CATEGORY_BROWSABLE); 
  13.             launchIntent.setComponent(null); 
  14.             startActivity(launchIntent); 
  15.         } else { 
  16.             Log.e(TAG, "couldn't get intent to restart app"); 
  17.         } 

}

in air app just read e.arguments[0] of invokeEvent and you will get string starting with you curstom scheme myapp://

override protected function onAppInvoke(e:InvokeEvent):void {

if you app is running you will get data from activity below via just add a listener with SHARED_TEXT  value

you can read adobe docs about how to read data from plugin via dispatchStatusEventAsync

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 02, 2017 0
Explorer ,
Sep 04, 2017

Copy link to clipboard

Copied

First of all thanks for your response and help. I have some questions:

1. Which manifest I have to edit, I normally do the APP Manifest but I don't know if I have to edit the ANE Manifest.

Solved

2. Can I send a bytearray somehow when my APP isn't runing? In your example I can only send text with URI.

Thank you very much.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 04, 2017 0
Explorer ,
Sep 04, 2017

Copy link to clipboard

Copied

1- main application manifest file not ane

2- save bytearray to a file via filestream and just pass  file url like myapp://send/file:///filepath

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 04, 2017 0