Sunday, August 5, 2012

Share with photo using ShareActionProvider

Last exercise demonstrate how to "send email with photo by starting activity with Intent of ACTION_SEND". In this exercise, we will do the same thing using ShareActionProvider.

ShareActionProvider was introduced since API Level 14. This is a provider for a share action. It is responsible for creating views that enable data sharing and also to show a sub menu with sharing activities if the hosting item is placed on the overflow menu.

Share with photo using ShareActionProvider


Modify /res/menu/activity_main.xml to define the android:actionProviderClass attribute for the corresponding in your menu resource file.

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_item_share"
        android:showAsAction="ifRoom"
        android:title="Share"
        android:actionProviderClass="android.widget.ShareActionProvider" />
</menu>


In order for ShareActionProvider to function, you must provide it a share intent. Find the corresponding MenuItem while inflating your menu resource in your Activity or Fragment. Next, call MenuItem.getActionProvider() to retreive an instance of ShareActionProvider. Use setShareIntent() to update the share intent associated with that action item. ~ refer to onCreateOptionsMenu(Menu menu) in the code.

When you need to update the content to be shared (ex. EditText changed, photo attached), call setShareIntent(shareIntent) again to update the intent. ~ refer setShareIntent(Intent shareIntent) in the code.
package com.example.androidsharephoto;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ShareActionProvider;
import android.widget.TextView;

public class MainActivity extends Activity {
 
 private ShareActionProvider myShareActionProvider;
 
 EditText edittextEmailAddress;
    EditText edittextEmailSubject;
    EditText edittextEmailText;
    TextView textImagePath;
    Button buttonSelectImage;
    
    final int RQS_LOADIMAGE = 0;
    
    Uri imageUri = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        edittextEmailAddress = (EditText)findViewById(R.id.email_address);
        edittextEmailSubject = (EditText)findViewById(R.id.email_subject);
        edittextEmailText = (EditText)findViewById(R.id.email_text);
        edittextEmailAddress.addTextChangedListener(commonTextWatcher);
        edittextEmailSubject.addTextChangedListener(commonTextWatcher);
        edittextEmailText.addTextChangedListener(commonTextWatcher);
        
        textImagePath = (TextView)findViewById(R.id.imagepath);
        
        buttonSelectImage = (Button)findViewById(R.id.selectimage);
        buttonSelectImage.setOnClickListener(buttonSelectImageOnClickListener);
    }
    
    TextWatcher commonTextWatcher
    = new TextWatcher(){

  @Override
  public void afterTextChanged(Editable s) {
   // TODO Auto-generated method stub
   setShareIntent(createShareIntent());
  }

  @Override
  public void beforeTextChanged(CharSequence s, int start, int count,
    int after) {
   // TODO Auto-generated method stub
   
  }

  @Override
  public void onTextChanged(CharSequence s, int start, int before,
    int count) {
   // TODO Auto-generated method stub
   
  }};
    
    OnClickListener buttonSelectImageOnClickListener
    = new OnClickListener(){

  @Override
  public void onClick(View arg0) {
   Intent intent = new Intent(Intent.ACTION_PICK,
     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
   startActivityForResult(intent, RQS_LOADIMAGE);
  }};
  
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  // TODO Auto-generated method stub
  super.onActivityResult(requestCode, resultCode, data);
   
  if (resultCode == RESULT_OK){
   switch(requestCode){
   case RQS_LOADIMAGE:
    imageUri = data.getData();
    textImagePath.setText(imageUri.toString());
    setShareIntent(createShareIntent());
    break; 
   }  
  }
 }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        
        MenuItem item = menu.findItem(R.id.menu_item_share);
        myShareActionProvider = (ShareActionProvider)item.getActionProvider();
        myShareActionProvider.setShareHistoryFileName(
          ShareActionProvider.DEFAULT_SHARE_HISTORY_FILE_NAME);
        myShareActionProvider.setShareIntent(createShareIntent());
        return true;
    }
    
    

 private Intent createShareIntent() {
     String emailAddress = edittextEmailAddress.getText().toString();
  String emailSubject = edittextEmailSubject.getText().toString();
  String emailText = edittextEmailText.getText().toString();
  String emailAddressList[] = {emailAddress};
  
  Intent shareIntent = new Intent(Intent.ACTION_SEND); 
  
  shareIntent.putExtra(Intent.EXTRA_EMAIL, emailAddressList);  
  shareIntent.putExtra(Intent.EXTRA_SUBJECT, emailSubject); 
  shareIntent.putExtra(Intent.EXTRA_TEXT, emailText); 
  
  if(imageUri != null){
   shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
   shareIntent.setType("image/png");
  }else{
   shareIntent.setType("plain/text");
  }
  
     return shareIntent; 
    }
 
 private void setShareIntent(Intent shareIntent) {
  if (myShareActionProvider != null) {
   myShareActionProvider.setShareIntent(shareIntent); 
  } 
 }

    
}


Layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="@string/hello_world"
   />
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Enter email address:"
   />
<EditText 
   android:id="@+id/email_address"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:inputType="textEmailAddress"
   />
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Enter email Subject:"
   />
<EditText 
   android:id="@+id/email_subject"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:inputType="textEmailSubject"
   />
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Enter Text:"
   />
<EditText 
   android:id="@+id/email_text"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   />
<TextView
    android:id="@+id/imagepath"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    />
<Button
    android:id="@+id/selectimage"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Select image"
    />
</LinearLayout>


Download the files.


5 comments:

Unknown said...

sorry, my code does not work, when you launch the Activity sends me error "resource not found" any solution, I need to finish my app

Unknown said...

How can I share an online image with actionshareprovider? You can easily set the uri how can I do that?

Erik said...

hello Said Tahsin Dane,

that means you want to share the link, same as share text.

Refer: Implement ShareActionProvider for Android 4.

angel Solis said...

How can i set share intent in a fragment with viewpager? Thanks in Advance.

Anonymous said...

Your tutorials are really helpful thanks a lot!