A Simple example application to capture image/ selecting image from gallery.
This application includes sd card permission checking and FileUrilExposedException issue fix..
Step 1:
=========
Create an Activity like below
package org.pratap.cameraexample; import android.Manifest; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.provider.MediaStore; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.content.FileProvider; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import com.bumptech.glide.Glide; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class MainActivity extends AppCompatActivity { final int REQUEST_PERMISSIONS = 1001; final int DELAY_TIME = 1000; private static int NEW_IMAGE = 0; private static int EXISTING_IMAGE = 1; Button btn_capture_image, btn_galley_image; ImageView img_photo; String imageFilePath = ""; int imageType = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_capture_image = (Button) findViewById(R.id.btn_capture_image); btn_galley_image = (Button) findViewById(R.id.btn_galley_image); img_photo = (ImageView) findViewById(R.id.img_photo); img_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewImage(); } }); btn_capture_image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkPermissions(); // for camera image imageType = 0; } }); btn_galley_image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkPermissions(); // for gallery image imageType = 1; } }); } private void checkPermissions() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { mHandler.sendEmptyMessageDelayed(1, DELAY_TIME); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSIONS); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_PERMISSIONS) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted mHandler.sendEmptyMessageDelayed(1, DELAY_TIME); } else { // permission denied, boo! } } } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 1) { // code goes here after getting permission if (imageType == 0) { takePictureFromCamera(); } else if (imageType == 1) { pictureFromGallery(); } } } }; public void takePictureFromCamera() { imageFilePath = ""; File imageFile = createFileName(); imageFilePath = imageFile.getAbsolutePath(); Uri outputFileUri = null; // if you are running nougat and above there is chance to crash if (Build.VERSION.SDK_INT >= 24) { outputFileUri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", imageFile); } else { outputFileUri = Uri.fromFile(imageFile); } if (outputFileUri != null) { Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(cameraIntent, NEW_IMAGE); } else { Toast.makeText(this, "URI not found", Toast.LENGTH_SHORT).show(); } } public void pictureFromGallery() { try { Intent i = new Intent( Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(i, EXISTING_IMAGE); } catch (ActivityNotFoundException anfe) { // display an error message String errorMessage = "Your device doesn't have gallery"; Toast toast = Toast .makeText(this, errorMessage, Toast.LENGTH_SHORT); toast.show(); } } public void viewImage() { if (imageFilePath.length() != 0) { try { File file = new File(imageFilePath); String documentType = getFileExtension(file); Uri uri = null; Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT >= 24) { uri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", file); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { uri = Uri.fromFile(file); } if (documentType.equalsIgnoreCase("jpg")) { intent.setDataAndType(uri, "image/jpeg"); startActivity(intent); } else if (documentType.equalsIgnoreCase("png")) { intent.setDataAndType(uri, "image/png"); startActivity(intent); } else { intent.setDataAndType(uri, "*/*"); startActivity(intent); } } catch (ActivityNotFoundException e) { e.printStackTrace(); } } else { Toast.makeText(MainActivity.this, "Image not selected.Please Select Image First", Toast.LENGTH_SHORT).show(); } } public File createFileName() { final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/CameraEx/Images/"; File newDir = new File(dir); if (!newDir.exists()) { newDir.mkdirs(); } String newFilename = ""; Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); newFilename = sdf.format(date); String filePath = dir + newFilename + ".jpg"; File newFile = new File(filePath); try { newFile.createNewFile(); } catch (IOException e) { } return newFile; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == EXISTING_IMAGE && resultCode == RESULT_OK && null != data) { try { Uri selectedImage = data.getData(); String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); imageFilePath = picturePath; if (imageFilePath.length() != 0) { // set ImageView with File Path setImage(MainActivity.this, imageFilePath, img_photo); Toast.makeText(MainActivity.this, "Image Saved : " + imageFilePath, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "Image not selected.Please try again", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { } } else if (requestCode == NEW_IMAGE && resultCode == RESULT_OK) { if (imageFilePath.length() != 0) { // set ImageView with File Path setImage(MainActivity.this, imageFilePath, img_photo); Toast.makeText(MainActivity.this, "Image Saved : " + imageFilePath, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "Image not selected.Please try again", Toast.LENGTH_SHORT).show(); } } } public void setImage(Context ctx, String filePath, ImageView imgView) { File actualImage = new File(filePath); if (actualImage.exists()) { Glide.with(ctx) .load(actualImage) .centerCrop() .into(imgView); } else { Toast.makeText(ctx, "No File exists", Toast.LENGTH_SHORT).show(); } } public String getFileExtension(File file) { String name = file.getName(); try { return name.substring(name.lastIndexOf(".") + 1); } catch (Exception e) { return ""; } } }
XML Layout for the Activity
activity_main.xml
==============
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context="org.pratap.cameraexample.MainActivity"> <ImageView android:id="@+id/img_photo" android:layout_width="250dp" android:layout_height="250dp" android:background="#c9c9c9" android:scaleType="centerCrop" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="24dp" android:orientation="horizontal"> <Button android:id="@+id/btn_capture_image" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Capture Image" /> <Button android:id="@+id/btn_galley_image" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Galley Image" /> </LinearLayout> </LinearLayout>
ScreenShot for Preview:
Step 2:
=========
Add the following code in AndroidManifest.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
like below
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.pratap.cameraexample"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider> </application> </manifest>
Step 3:
=====
create provider_paths xml file under xml folder
path should be like this
res/xml/provider_path.xml
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="."/> </paths>
Some useful methods to convert Files to ByteArray or Base64 Encoded String
public static String getEncodedString(String filePath) throws FileNotFoundException, IOException { String encodedDocument = ""; File file = new File(filePath); byte[] binaryFile = new byte[(int) file.length()]; InputStream fis = new FileInputStream(file); fis.read(binaryFile); fis.close(); encodedDocument = Base64.encodeToString(binaryFile, Base64.DEFAULT); return encodedDocument; } public static byte[] getFileByteArray(String filePath) throws FileNotFoundException, IOException { File file = new File(filePath); FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[(int) file.length()]; try { for (int readNum; (readNum = fis.read(buf)) != -1; ) { bos.write(buf, 0, readNum); } } catch (IOException ex) { Log.d("error", "error"); } byte[] imagebytes = bos.toByteArray(); return imagebytes; }
No comments:
Post a Comment