├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── co │ │ └── carlosandresjimenez │ │ └── android │ │ └── myshareimageexample │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── co │ │ │ └── carlosandresjimenez │ │ │ └── android │ │ │ └── myshareimageexample │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-hdpi │ │ └── ic_insert_photo_white_48dp.png │ │ ├── drawable-mdpi │ │ └── ic_insert_photo_white_48dp.png │ │ ├── drawable-xhdpi │ │ └── ic_insert_photo_white_48dp.png │ │ ├── drawable-xxhdpi │ │ └── ic_insert_photo_white_48dp.png │ │ ├── drawable-xxxhdpi │ │ └── ic_insert_photo_white_48dp.png │ │ ├── layout │ │ ├── activity_main.xml │ │ └── content_main.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── co │ └── carlosandresjimenez │ └── android │ └── myshareimageexample │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The code in this example is mostly taken from the examples provided by Google on the 2 | following links: 3 | 4 | https://developer.android.com/training/camera/index.html 5 | https://developer.android.com/training/camera/photobasics.html 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.1" 6 | defaultConfig { 7 | applicationId "co.carlosandresjimenez.android.myshareimageexample" 8 | minSdkVersion 21 9 | targetSdkVersion 24 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:24.2.1' 28 | compile 'com.android.support:design:24.2.1' 29 | testCompile 'junit:junit:4.12' 30 | } 31 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/carlosjimenez/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/co/carlosandresjimenez/android/myshareimageexample/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package co.carlosandresjimenez.android.myshareimageexample; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("co.carlosandresjimenez.android.myshareimageexample", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/co/carlosandresjimenez/android/myshareimageexample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package co.carlosandresjimenez.android.myshareimageexample; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapFactory; 7 | import android.net.Uri; 8 | import android.os.Build; 9 | import android.os.Bundle; 10 | import android.support.design.widget.FloatingActionButton; 11 | import android.support.design.widget.Snackbar; 12 | import android.support.v4.app.ShareCompat; 13 | import android.support.v7.app.AppCompatActivity; 14 | import android.support.v7.widget.Toolbar; 15 | import android.util.Log; 16 | import android.view.Menu; 17 | import android.view.MenuItem; 18 | import android.view.View; 19 | import android.view.ViewTreeObserver; 20 | import android.widget.ImageView; 21 | import android.widget.TextView; 22 | 23 | import java.io.FileNotFoundException; 24 | import java.io.IOException; 25 | import java.io.InputStream; 26 | 27 | /* 28 | * The code in this example is mostly taken from the examples provided by Google on the 29 | * following links: 30 | * 31 | * https://developer.android.com/training/camera/index.html 32 | * https://developer.android.com/training/camera/photobasics.html 33 | */ 34 | 35 | public class MainActivity extends AppCompatActivity { 36 | 37 | private static final String LOG_TAG = MainActivity.class.getSimpleName(); 38 | 39 | private static final int PICK_IMAGE_REQUEST = 0; 40 | private static final int SEND_MAIL_REQUEST = 1; 41 | 42 | private static final String STATE_URI = "STATE_URI"; 43 | 44 | private ImageView mImageView; 45 | private TextView mTextView; 46 | private FloatingActionButton mFab; 47 | 48 | private Uri mUri; 49 | 50 | @Override 51 | protected void onCreate(Bundle savedInstanceState) { 52 | super.onCreate(savedInstanceState); 53 | setContentView(R.layout.activity_main); 54 | 55 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 56 | setSupportActionBar(toolbar); 57 | 58 | mTextView = (TextView) findViewById(R.id.image_uri); 59 | mImageView = (ImageView) findViewById(R.id.image); 60 | 61 | mFab = (FloatingActionButton) findViewById(R.id.fab); 62 | mFab.setOnClickListener(new View.OnClickListener() { 63 | @Override 64 | public void onClick(View view) { 65 | openImageSelector(); 66 | } 67 | }); 68 | } 69 | 70 | @Override 71 | protected void onSaveInstanceState(Bundle outState) { 72 | super.onSaveInstanceState(outState); 73 | 74 | if (mUri != null) 75 | outState.putString(STATE_URI, mUri.toString()); 76 | } 77 | 78 | @Override 79 | protected void onRestoreInstanceState(Bundle savedInstanceState) { 80 | super.onRestoreInstanceState(savedInstanceState); 81 | 82 | if (savedInstanceState.containsKey(STATE_URI) && 83 | !savedInstanceState.getString(STATE_URI).equals("")) { 84 | mUri = Uri.parse(savedInstanceState.getString(STATE_URI)); 85 | mTextView.setText(mUri.toString()); 86 | 87 | ViewTreeObserver viewTreeObserver = mImageView.getViewTreeObserver(); 88 | viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 89 | @Override 90 | public void onGlobalLayout() { 91 | mImageView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 92 | mImageView.setImageBitmap(getBitmapFromUri(mUri)); 93 | } 94 | }); 95 | } 96 | } 97 | 98 | @Override 99 | public boolean onCreateOptionsMenu(Menu menu) { 100 | // Inflate the menu; this adds items to the action bar if it is present. 101 | getMenuInflater().inflate(R.menu.menu_main, menu); 102 | return true; 103 | } 104 | 105 | @Override 106 | public boolean onOptionsItemSelected(MenuItem item) { 107 | // Handle action bar item clicks here. The action bar will 108 | // automatically handle clicks on the Home/Up button, so long 109 | // as you specify a parent activity in AndroidManifest.xml. 110 | int id = item.getItemId(); 111 | 112 | //noinspection SimplifiableIfStatement 113 | if (id == R.id.action_sendmail) { 114 | sendEmail(); 115 | return true; 116 | } 117 | 118 | return super.onOptionsItemSelected(item); 119 | } 120 | 121 | public void openImageSelector() { 122 | Intent intent; 123 | 124 | if (Build.VERSION.SDK_INT < 19) { 125 | intent = new Intent(Intent.ACTION_GET_CONTENT); 126 | } else { 127 | intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); 128 | intent.addCategory(Intent.CATEGORY_OPENABLE); 129 | } 130 | 131 | intent.setType("image/*"); 132 | startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST); 133 | } 134 | 135 | @Override 136 | public void onActivityResult(int requestCode, int resultCode, Intent resultData) { 137 | // The ACTION_OPEN_DOCUMENT intent was sent with the request code READ_REQUEST_CODE. 138 | // If the request code seen here doesn't match, it's the response to some other intent, 139 | // and the below code shouldn't run at all. 140 | 141 | if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK) { 142 | // The document selected by the user won't be returned in the intent. 143 | // Instead, a URI to that document will be contained in the return intent 144 | // provided to this method as a parameter. Pull that uri using "resultData.getData()" 145 | 146 | if (resultData != null) { 147 | mUri = resultData.getData(); 148 | Log.i(LOG_TAG, "Uri: " + mUri.toString()); 149 | 150 | mTextView.setText(mUri.toString()); 151 | mImageView.setImageBitmap(getBitmapFromUri(mUri)); 152 | } 153 | } else if (requestCode == SEND_MAIL_REQUEST && resultCode == Activity.RESULT_OK) { 154 | 155 | } 156 | } 157 | 158 | public Bitmap getBitmapFromUri(Uri uri) { 159 | 160 | if (uri == null || uri.toString().isEmpty()) 161 | return null; 162 | 163 | // Get the dimensions of the View 164 | int targetW = mImageView.getWidth(); 165 | int targetH = mImageView.getHeight(); 166 | 167 | InputStream input = null; 168 | try { 169 | input = this.getContentResolver().openInputStream(uri); 170 | 171 | // Get the dimensions of the bitmap 172 | BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 173 | bmOptions.inJustDecodeBounds = true; 174 | BitmapFactory.decodeStream(input, null, bmOptions); 175 | input.close(); 176 | 177 | int photoW = bmOptions.outWidth; 178 | int photoH = bmOptions.outHeight; 179 | 180 | // Determine how much to scale down the image 181 | int scaleFactor = Math.min(photoW / targetW, photoH / targetH); 182 | 183 | // Decode the image file into a Bitmap sized to fill the View 184 | bmOptions.inJustDecodeBounds = false; 185 | bmOptions.inSampleSize = scaleFactor; 186 | bmOptions.inPurgeable = true; 187 | 188 | input = this.getContentResolver().openInputStream(uri); 189 | Bitmap bitmap = BitmapFactory.decodeStream(input, null, bmOptions); 190 | input.close(); 191 | return bitmap; 192 | 193 | } catch (FileNotFoundException fne) { 194 | Log.e(LOG_TAG, "Failed to load image.", fne); 195 | return null; 196 | } catch (Exception e) { 197 | Log.e(LOG_TAG, "Failed to load image.", e); 198 | return null; 199 | } finally { 200 | try { 201 | input.close(); 202 | } catch (IOException ioe) { 203 | 204 | } 205 | } 206 | } 207 | 208 | private void sendEmail() { 209 | if (mUri != null) { 210 | String subject = "URI Example"; 211 | String stream = "Hello! \n" 212 | + "Uri example" + ".\n" 213 | + "Uri: " + mUri.toString() + "\n"; 214 | 215 | Intent shareIntent = ShareCompat.IntentBuilder.from(this) 216 | .setStream(mUri) 217 | .setSubject(subject) 218 | .setText(stream) 219 | .getIntent(); 220 | 221 | // Provide read access 222 | shareIntent.setData(mUri); 223 | shareIntent.setType("message/rfc822"); 224 | shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 225 | 226 | if (Build.VERSION.SDK_INT < 21) { 227 | shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 228 | } else { 229 | shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); 230 | } 231 | 232 | 233 | startActivityForResult(Intent.createChooser(shareIntent, "Share with"), SEND_MAIL_REQUEST); 234 | 235 | } else { 236 | Snackbar.make(mFab, "Image not selected", Snackbar.LENGTH_LONG) 237 | .setAction("Select", new View.OnClickListener() { 238 | @Override 239 | public void onClick(View view) { 240 | openImageSelector(); 241 | } 242 | }).show(); 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_insert_photo_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/drawable-hdpi/ic_insert_photo_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_insert_photo_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/drawable-mdpi/ic_insert_photo_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_insert_photo_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/drawable-xhdpi/ic_insert_photo_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_insert_photo_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/drawable-xxhdpi/ic_insert_photo_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_insert_photo_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/drawable-xxxhdpi/ic_insert_photo_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 20 | 21 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crlsndrsjmnz/MyShareImageExample/dade9134b3ff62330273be2b88510e1d6d49e88c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MyShareImageExample 3 | Send Mail 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 |