My Photo Editor Android application has some issue. After capturing the image from the 20MegaPixel (5184x3880) camera through the app, I am resizing the image through Bitmap to 15MegaPixel (4477 x 3351) and then saving the image in the Gallery/Photos folder in the phone
Following is the HomeActivity code:
package com.saashtechs.photoeditor;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.support.annotation.NonNull;
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.util.Log;
import android.view.View;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Objects;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class HomeActivity extends AppCompatActivity {
private static final String TAG = "HomeActivity";
private static final int GALLERY_RESULT = 1;
private static final int CAMERA_RESULT = 2;
private static final String FILE_PROVIDER_AUTHORITY = "com.saashtechs.photoeditor";
private static final int CAMERA_PERMISSION_REQ_CODE = 1001;
private static final int STORAGE_PERMISSION_REQ_CODE = 1002;
private Uri imageToUploadUri;
private String mCapturedImagePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}
public void openCamera(View view) {
// check for camera permission if not granted before
if (ContextCompat.checkSelfPermission(this, CAMERA) != PERMISSION_GRANTED) {
String[] cameraPermission = {CAMERA};
ActivityCompat.requestPermissions(this, cameraPermission, CAMERA_PERMISSION_REQ_CODE);
} else {
dispatchImageCaptureIntent();
}
}
public void openGallery(View view) {
// check for storage permission if not granted before
if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
String[] storagePermissions = {READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE};
ActivityCompat.requestPermissions(this, storagePermissions, STORAGE_PERMISSION_REQ_CODE);
} else {
dispatchGalleryIntent();
}
}
private void dispatchGalleryIntent() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, GALLERY_RESULT);
}
private void dispatchImageCaptureIntent() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
Uri photoFileUri = FileProvider.getUriForFile(this, FILE_PROVIDER_AUTHORITY, photoFile);
Log.d(TAG, "dispatchImageCaptureIntent:photoFileUri: " + photoFile.toString());
//Add URI to imageToUploadUri. You forgot to add it.
imageToUploadUri = photoFileUri;
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri);
startActivityForResult(cameraIntent, CAMERA_RESULT);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case CAMERA_PERMISSION_REQ_CODE:
if (grantResults[0] == PERMISSION_GRANTED) {
dispatchImageCaptureIntent();
} else {
Toast.makeText(this, "Required camera permission not granted", Toast.LENGTH_SHORT).show();
}
break;
case STORAGE_PERMISSION_REQ_CODE:
if (grantResults[0] == PERMISSION_GRANTED) {
dispatchGalleryIntent();
} else {
Toast.makeText(this, "Required storage permission not granted", Toast.LENGTH_SHORT)
.show();
}
break;
default:
throw new IllegalArgumentException("Unexpected request code");
}
}
private File createImageFile() throws IOException {
String timeStamp = DateFormat.getDateTimeInstance().format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
mCapturedImagePath = image.getAbsolutePath();
Log.d(TAG, "createImageFile: " + mCapturedImagePath);
return image;
}
private Bundle uriToBundle(Uri imageUri) {
Bundle bundle = new Bundle();
bundle.putString(MainActivity.IMAGE_URI, imageUri.toString());
return bundle;
}
public Bitmap resizeBitmap(Bitmap getBitmap, int maxSize) {
int width = getBitmap.getWidth();//5184
int height = getBitmap.getHeight();//3880
double resized_image;
if (width >= height && width > maxSize) {
resized_image = width / height;
width = maxSize;
height = (int) (maxSize / resized_image);
} else if (height >= width && height > maxSize) {
resized_image = height / width;
height = maxSize;
width = (int) (maxSize / resized_image);
}
return Bitmap.createScaledBitmap(getBitmap, width, height, false);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == GALLERY_RESULT) {
Uri imageUri = data.getData();
startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageUri))));
} else if (requestCode == CAMERA_RESULT) {
File imageFile = new File(mCapturedImagePath);
Bitmap image = BitmapFactory.decodeFile(mCapturedImagePath);
image = Bitmap.createScaledBitmap(image, 4477, 3351, false);
image = resizeBitmap(image, 4477);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
try {
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "filename.jpg");
boolean result;
result = file.createNewFile();
if (result) {
FileOutputStream fo = new FileOutputStream(imageFile);
fo.write(bytes.toByteArray());
fo.close();
}
} catch(IOException ie) {
ie.printStackTrace();
}
startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageToUploadUri))));
}
} else {
Toast.makeText(this, "Image not loaded.", Toast.LENGTH_SHORT).show();
}
}
public static Intent getIntent(Context context) {
return new Intent(context, HomeActivity.class);
}
}
Following is the MainActivity code:
package com.saashtechs.photoeditor;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import com.adobe.creativesdk.aviary.AdobeImageIntent;
public class MainActivity extends AppCompatActivity {
public static final String IMAGE_URI = "IMAGE_URI_KEY";
private static final String TAG = "MainActivity";
private static final int IMAGE_EDITOR_RESULT = 1;
private ImageView mEditedImageView;
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditedImageView = (ImageView) findViewById(R.id.edited_image_view);
Bundle extras = getIntent().getExtras();
if (extras != null) {
Uri imageUri = Uri.parse(getIntent().getExtras().getString(IMAGE_URI));
Intent imageEditorIntent = new AdobeImageIntent.Builder(this).setData(imageUri).build();
startActivityForResult(imageEditorIntent, IMAGE_EDITOR_RESULT);
finish();
}
}
#Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case IMAGE_EDITOR_RESULT:
Uri editedImageUri = data.getParcelableExtra(AdobeImageIntent.EXTRA_OUTPUT_URI);
Log.d(TAG, "editedImageUri: " + editedImageUri.toString());
Bundle extra = data.getExtras();
if (extra != null) {
boolean changed = extra.getBoolean(AdobeImageIntent.EXTRA_OUT_BITMAP_CHANGED);
Log.d(TAG, "Image edited: " + changed);
if (changed) {
mEditedImageView.setImageURI(editedImageUri);
}
}
break;
default:
throw new IllegalArgumentException("Unexpected request code");
}
}
}
public static Intent getIntent(Context context, Bundle bundle) {
Intent intent = new Intent(context, MainActivity.class);
if (bundle != null) {
intent.putExtras(bundle);
}
return intent;
}
}
So when I capture the image and then when the user is taken to edit the application, it doesn't, it takes me back to Home page again after capturing the image
Error log is:
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor bitmap.size: 5184x3880
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor resize(15)
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor bitmap MP: 20, max MP: 15
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor Image must be resized! 20MP -> 15MP
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor target: 15MP = (4477x3351), max size: 4477
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor original: 20MP = (5184x3880)
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor maxWidth: 4477, maxHeight: 3351
Can you please tell me where am I going wrong ?
Thanks in advance
if (extras != null) {
Uri imageUri = Uri.parse(getIntent().getExtras().getString(IMAGE_URI));
Intent imageEditorIntent = new AdobeImageIntent.Builder(this).setData(imageUri).build();
startActivityForResult(imageEditorIntent, IMAGE_EDITOR_RESULT);
// below line of code is not possible. your trying to receive result over
//here.
// . but your finishing it before it receives result
finish();
}
use below method close activity once data received. Pass data with set result method and then close. so your activity will have edited data.
better solution - you dont need this intermediate activity.
#Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case IMAGE_EDITOR_RESULT:
Uri editedImageUri = data.getParcelableExtra(AdobeImageIntent.EXTRA_OUTPUT_URI);
Log.d(TAG, "editedImageUri: " + editedImageUri.toString());
Bundle extra = data.getExtras();
if (extra != null) {
boolean changed = extra.getBoolean(AdobeImageIntent.EXTRA_OUT_BITMAP_CHANGED);
Log.d(TAG, "Image edited: " + changed);
if (changed) {
mEditedImageView.setImageURI(editedImageUri);
}
}
break;
default:
throw new IllegalArgumentException("Unexpected request code");
}
}
}
As guidance -- below code is very bad practise in android
public static Intent getIntent(Context context, Bundle bundle) {
Intent intent = new Intent(context, MainActivity.class);
if (bundle != null) {
intent.putExtras(bundle);
}
return intent;
}
Good practise.
private void navigateToPhotoEditActivity(Context context, Bundle bundle)
{
Intent intent = new Intent(context, MainActivity.class);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
}
Related
This code makes the file "amirLight.txt" and saves the data to it. However, I am trying to create more files in the app and save the data to the new file. This doesn't work. Even though the file name selected and the variable "currentProject" correctly gets the value and shown correctly in Log.e but the actual data never saves to the new file. It only works when the default file of "amirLight.txt" is used.
package com.jorc.lightamir;
import static android.util.Log.e;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mLight;
private float currentLux = 0;
private float rotationVal = 0;
private TextView lightValue;
private TextView gpsX;
private TextView gpsY;
private TextView gpsZ;
private TextView rotation;
public Uri uriFile;
public String currentProject ="amirLight.txt";
//Location
private FusedLocationProviderClient mFusedLocationClient;
private double wayLatitude = 0.0, wayLongitude = 0.0;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
private boolean isContinue = true;
private boolean isGPS = false;
private String testData = "TestData";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lightValue = findViewById(R.id.lightText);
gpsX = findViewById(R.id.gpsX);
gpsY = findViewById(R.id.gpsY);
gpsZ = findViewById(R.id.gpsZ);
rotation = findViewById(R.id.rotationText);
lightValue.setText( "currentLux" );
this.mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
this.mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
mSensorManager.registerListener((SensorEventListener) this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
//Location
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10 * 1000); // 10 seconds
locationRequest.setFastestInterval(5 * 1000); // 5 seconds
new GpsUtils(this).turnGPSOn(new GpsUtils.onGpsListener() {
#Override
public void gpsStatus(boolean isGPSEnable) {
// turn on GPS
isGPS = isGPSEnable;
}
});
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
if (location != null) {
wayLatitude = location.getLatitude();
wayLongitude = location.getLongitude();
if (!isContinue) {
gpsX.setText(String.format(Locale.US, "%s - %s", wayLatitude));
gpsY.setText(String.format(Locale.US, "%s - %s", wayLongitude));
} else {
}
if (!isContinue && mFusedLocationClient != null) {
mFusedLocationClient.removeLocationUpdates(locationCallback);
}
}
}
}
};
isContinue = true;
//End Location
Button buttonSave = (Button) findViewById(R.id.button_save);
Button projectSave = (Button) findViewById(R.id.project_save);
Button projectOpen = (Button) findViewById(R.id.project_open);
buttonSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
getLocation();
e("RecordSaved", "RecordSaved" );
}
});
projectSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
createFile();
}
});
projectOpen.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//createFile();
openFile();
}
});
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_LIGHT) {
currentLux = (float) sensorEvent.values[0];
NumberFormat formatter = new DecimalFormat("#0");
lightValue.setText( formatter.format(currentLux) );
/* Logs */
//Log.e("LightMeter", "currentLux = " + formatter.format(currentLux));
}
if (sensorEvent.sensor.getType() == Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR)
{
rotationVal = (float) sensorEvent.values[2];
NumberFormat formatter = new DecimalFormat("#0");
rotation.setText(formatter.format(rotationVal));
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
if (sensor.getType() == Sensor.TYPE_LIGHT) {
}
}
//Location Additional
private void getLocation() {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
AppConstants.LOCATION_REQUEST);
} else {
mFusedLocationClient.getLastLocation().addOnSuccessListener(MainActivity.this, location -> {
if (location != null) {
wayLatitude = location.getLatitude();
wayLongitude = location.getLongitude();
Toast.makeText(this, wayLatitude+"this", Toast.LENGTH_SHORT).show();
// Write to a file
writeToFile("Lux "+currentLux+" Y "+wayLatitude+" X "+wayLongitude,currentProject,getApplicationContext());
// End write to a file
gpsX.setText(String.valueOf(wayLatitude));
gpsY.setText(String.valueOf(wayLongitude));
} else {
mFusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
}
});
}
}
// create text file
private void createFile() {
// when you create document, you need to add Intent.ACTION_CREATE_DOCUMENT
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
// filter to only show openable items.
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Create a file with the requested Mime type
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TITLE, "typeProjectName.txt");
startActivityForResult(intent, 2);
}
private void openFile() {
// when you create document, you need to add Intent.ACTION_CREATE_DOCUMENT
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
// filter to only show openable items.
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Create a file with the requested Mime type
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TITLE, currentProject);
startActivityForResult(intent, 3);
}
#SuppressLint("MissingPermission")
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1000: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (isContinue) {
mFusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
} else {
mFusedLocationClient.getLastLocation().addOnSuccessListener(MainActivity.this, location -> {
if (location != null) {
wayLatitude = location.getLatitude();
wayLongitude = location.getLongitude();
gpsX.setText(String.format(Locale.US, "%s - %s", wayLatitude));
gpsY.setText(String.format(Locale.US, "%s - %s", wayLongitude));
} else {
mFusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
}
});
}
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == AppConstants.GPS_REQUEST) {
isGPS = true; // flag maintain before get location
}
}
//Open File
if (requestCode == 3){
if (data != null){
if (data.getData() != null){
//Get file extension here.
// e("OpenFile", "OpenFile = " );
uriFile = data.getData();
currentProject=getFileName(uriFile);
Log.e("data", "FilePath2 = "+currentProject );
}
}
}
//End Open FIle
//Create File
if (requestCode == 2){
if (resultCode == RESULT_OK){
if (data != null){
if (data.getData() != null){
uriFile = data.getData();
currentProject=getFileName(uriFile);
//Get file extension here.
e("CreateFIle", "CreateFIle = "+currentProject );
}
}
}
}
//End of Create FIle
}
//Get File URI
public String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
}
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
//Write to File
private void writeToFile(String data,String currentProject, Context context) {
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
// if (currentProject == "1") {
//Toast.makeText(this, "Please choose a project first");
//Log.e("FileWrite", "No currentProject");
// } else {
File file = new File(dir, currentProject);
Log.e("FileWrite", currentProject);
//Write to file
try (FileWriter fileWriter = new FileWriter(file, true)) {
Log.e("FileWrite", "Trying to write to file");
fileWriter.append(data);
fileWriter.write(System.lineSeparator());
//file=null;
} catch (IOException e) {
//Handle exception
}
// }
}
//}
//End of Write
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
}
Context:
I used a template of an android app from https://github.com/pramod722445/Custom_Object_Detection_App
and added java files to detect images from a video. I trained the model on Google Colab and converted it to a tflite file and renamed it as bline_model.tflite with a text folder with the label bline_label.txt in Android Studio. When I run the application, it stops/crashes after the video to image phase is done. I think the error originates from either objectDetectorClass.java or PreviewImageActivity.java. How do I fix it?
CODE
MainActivity.java
package bline.detector.com.ffmpegvideoeditor.activity;
import android.Manifest;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
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.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandler;
import com.github.hiteshsondhi88.libffmpeg.FFmpeg;
import com.github.hiteshsondhi88.libffmpeg.LoadBinaryResponseHandler;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException;
import org.florescu.android.rangeseekbar.RangeSeekBar;
import org.opencv.android.OpenCVLoader;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import bline.detector.com.ffmpegvideoeditor.R;
public class MainActivity extends AppCompatActivity {
static {
if (!OpenCVLoader.initDebug())
Log.d("ERROR", "Unable to load OpenCV");
else
Log.d("SUCCESS", "OpenCV loaded");
}
private Button uploadVideo;
private Button extractImages;
private VideoView videoView;
private String filePath;
private static final String FILEPATH = "filepath";
private Uri selectedVideoUri;
private FFmpeg ffmpeg;
private static final int REQUEST_TAKE_GALLERY_VIDEO = 100;
private static final String TAG = "amirah";
private int choice = 0;
private ProgressDialog progressDialog;
private RangeSeekBar rangeSeekBar;
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
uploadVideo = (Button) findViewById(R.id.uploadVideo);
extractImages = (Button) findViewById(R.id.extractImages);
videoView = (VideoView) findViewById(R.id.videoView);
rangeSeekBar = (RangeSeekBar) findViewById(R.id.rangeSeekBar);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle(null);
progressDialog.setCancelable(false);
rangeSeekBar.setEnabled(false);
loadFFMpegBinary();
uploadVideo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 23)
getPermission();
else
uploadVideo();
}
});
extractImages.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
choice = 1;
if (selectedVideoUri != null) {
extractImagesVideo(rangeSeekBar.getSelectedMinValue().intValue() * 1000, rangeSeekBar.getSelectedMaxValue().intValue() * 1000);
} else
Toast.makeText(MainActivity.this, "Please Upload a Video", Toast.LENGTH_LONG).show();
}
});
}
private void getPermission() {
String[] params = null;
String writeExternalStorage = Manifest.permission.WRITE_EXTERNAL_STORAGE;
String readExternalStorage = Manifest.permission.READ_EXTERNAL_STORAGE;
int hasWriteExternalStoragePermission = ActivityCompat.checkSelfPermission(this, writeExternalStorage);
int hasReadExternalStoragePermission = ActivityCompat.checkSelfPermission(this, readExternalStorage);
List<String> permissions = new ArrayList<String>();
if (hasWriteExternalStoragePermission != PackageManager.PERMISSION_GRANTED)
permissions.add(writeExternalStorage);
if (hasReadExternalStoragePermission != PackageManager.PERMISSION_GRANTED)
permissions.add(readExternalStorage);
if (!permissions.isEmpty()) {
params = permissions.toArray(new String[permissions.size()]);
}
if (params != null && params.length > 0) {
ActivityCompat.requestPermissions(MainActivity.this,
params,
100);
} else
uploadVideo();
}
/**
* Handling response for permission request
*/
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 100: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
uploadVideo();
}
}
break;
}
}
private void uploadVideo() {
try {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_VIDEO);
} catch (Exception e) {
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_TAKE_GALLERY_VIDEO) {
selectedVideoUri = data.getData();
videoView.setVideoURI(selectedVideoUri);
videoView.start();
}
}
}
private void loadFFMpegBinary() {
try {
if (ffmpeg == null) {
ffmpeg = FFmpeg.getInstance(this);
}
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
#Override
public void onFailure() { showUnsupportedExceptionDialog();
}
#Override
public void onSuccess() {
Log.d(TAG, "ffmpeg: successfully Loaded");
}
});
} catch (FFmpegNotSupportedException e) {
showUnsupportedExceptionDialog();
} catch (Exception e) {
Log.d(TAG, "exception: " + e);
}
}
private void showUnsupportedExceptionDialog() {
new AlertDialog.Builder(MainActivity.this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Not Supported")
.setMessage("Device Not Supported")
.setCancelable(false)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
MainActivity.this.finish();
}
})
.create()
.show();
}
private void extractImagesVideo(int startMs, int endMs) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
);
String filePrefix = "extract_picture";
String fileExtn = ".jpg";
String yourRealPath = getPath(MainActivity.this, selectedVideoUri);
File dir = new File(moviesDir, "VideoEditor");
int fileNo = 0;
while (dir.exists()) {
fileNo++;
dir = new File(moviesDir, "VideoEditor" + fileNo);
}
dir.mkdir();
filePath = dir.getAbsolutePath();
File dest = new File(dir, filePrefix + "%03d" + fileExtn);
Log.d(TAG, "startTrim: src: " + yourRealPath);
Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());
String[] complexCommand = {"-y", "-i", yourRealPath, "-an", "-r", "1", "-ss", "" + startMs / 1000, "-t", "" + (endMs - startMs) / 1000, dest.getAbsolutePath()};
execFFmpegBinary(complexCommand);
}
//-y overwrite output files without asking
//-i ffmpeg reads from an arbitrary number of input "files" specified by the -i option
//-an disable audio recordings
//-r 1/2 will extract one image frame from every 2 second of video
//-r 1/2 will extract one image frame from every 2 second of video.Similarly, -r 1 will extract one image frame from every second of the video.
//remove -r option if u want to extract all video frames as images from the specified time duration
//-ss seeks to position
//-t limit the duration of data read from the input file
private void execFFmpegBinary(final String[] command) {
try {
ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
#Override
public void onFailure(String message) {
Log.d(TAG, "FAILED with output: " + message);
}
#Override
public void onSuccess(String s) {
Log.d(TAG, "SUCCESS with output: " + s);
Intent intent = new Intent(MainActivity.this, PreviewImageActivity.class);
intent.putExtra(FILEPATH, filePath);
startActivity(intent);
}
#Override
public void onProgress(String s) {
Log.d(TAG, "Started command : ffmpeg " + command);
if (choice == 1)
progressDialog.setMessage("progress: " + s);
Log.d(TAG, "progress : " + s);
}
#Override
public void onStart() {
Log.d(TAG, "Started command : ffmpeg " + command);
progressDialog.setMessage("Processing...");
progressDialog.show();
}
#Override
public void onFinish() {
Log.d(TAG, "Finished command : ffmpeg " + command);
if (choice == 1) {
progressDialog.dismiss();
}
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
// do nothing for now
}
}
public static boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
if (children != null) {
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
}
return dir.delete();
}
private String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri.
*/
private String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
}
objectDetectorClass.java
package bline.detector.com.ffmpegvideoeditor.activity;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.tensorflow.lite.Interpreter;
import org.tensorflow.lite.gpu.GpuDelegate;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class objectDetectorClass {
// used to load model and predict
private Interpreter interpreter;
// store all label in array
private List<String> labelList;
private int INPUT_SIZE;
private int PIXEL_SIZE=3; // for RGB
private int IMAGE_MEAN=0;
private float IMAGE_STD=255.0f;
// use to initialize gpu in app
private GpuDelegate gpuDelegate;
private int height=0;
private int width=0;
objectDetectorClass(AssetManager assetManager,String modelPath, String labelPath,int inputSize) throws IOException{
INPUT_SIZE=inputSize;
// use to define gpu or cpu // no. of threads
Interpreter.Options options=new Interpreter.Options();
gpuDelegate=new GpuDelegate();
options.addDelegate(gpuDelegate);
options.setNumThreads(4); // set it according to your phone
// loading model
interpreter=new Interpreter(loadModelFile(assetManager,modelPath),options);
// load labelmap
labelList=loadLabelList(assetManager,labelPath);
}
private List<String> loadLabelList(AssetManager assetManager, String labelPath) throws IOException {
// to store label
List<String> labelList=new ArrayList<>();
// create a new reader
BufferedReader reader=new BufferedReader(new InputStreamReader(assetManager.open(labelPath)));
String line;
// loop through each line and store it to labelList
while ((line=reader.readLine())!=null){
labelList.add(line);
}
reader.close();
return labelList;
}
private ByteBuffer loadModelFile(AssetManager assetManager, String modelPath) throws IOException {
// use to get description of file
AssetFileDescriptor fileDescriptor=assetManager.openFd(modelPath);
FileInputStream inputStream=new FileInputStream(fileDescriptor.getFileDescriptor());
FileChannel fileChannel=inputStream.getChannel();
long startOffset =fileDescriptor.getStartOffset();
long declaredLength=fileDescriptor.getDeclaredLength();
return fileChannel.map(FileChannel.MapMode.READ_ONLY,startOffset,declaredLength);
}
public Mat recognizeVideo(Mat mat_image){
Bitmap bitmap=null;
bitmap=Bitmap.createBitmap(mat_image.cols(),mat_image.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mat_image,bitmap);
height=bitmap.getHeight();
width=bitmap.getWidth();
// scale the bitmap to input size of model
Bitmap scaledBitmap=Bitmap.createScaledBitmap(bitmap,INPUT_SIZE,INPUT_SIZE,false);
// convert bitmap to bytebuffer as model input should be in it
ByteBuffer byteBuffer=convertBitmapToByteBuffer(scaledBitmap);
// defining output
Object[] input=new Object[1];
input[0]=byteBuffer;
Map<Integer,Object> output_map=new TreeMap<>();
// create treemap of three array (boxes,score,classes)
float[][][]boxes =new float[1][10][4];
// 10: top 10 objects detected
// 4: coordinates in image
float[][] scores=new float[1][10];
// stores scores of 10 object
float[][] classes=new float[1][10];
// stores class of object
// add it to object_map;
output_map.put(0,boxes);
output_map.put(1,classes);
output_map.put(2,scores);
// now predict
interpreter.runForMultipleInputsOutputs(input,output_map);
Object value=output_map.get(0);
Object Object_class=output_map.get(1);
Object score=output_map.get(2);
// loop through each object
// as output has only 10 boxes
for (int i=0;i<10;i++){
float class_value=(float) Array.get(Array.get(Object_class,0),i);
float score_value=(float) Array.get(Array.get(score,0),i);
// define threshold for score
// Here you can change threshold according to your model
if(score_value>0.8){
Object box1=Array.get(Array.get(value,0),i);
// multiply it with Original height and width of frame
float top=(float) Array.get(box1,0)*height;
float left=(float) Array.get(box1,1)*width;
float bottom=(float) Array.get(box1,2)*height;
float right=(float) Array.get(box1,3)*width;
// draw rectangle in Original frame // starting point //ending point of box //color of box thickness
Imgproc.rectangle(mat_image,new Point(left,top),new Point(right,bottom),new Scalar(0, 255, 0, 255),2);
// write text on frame
// string of class name of object // starting point // color of text // size of text
Imgproc.putText(mat_image,labelList.get((int) class_value),new Point(left,top),3,1,new Scalar(255, 0, 0, 255),2);
}
}
return mat_image;
}
private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {
ByteBuffer byteBuffer;
int quant=1;
int size_images=INPUT_SIZE;
if(quant==0){
byteBuffer=ByteBuffer.allocateDirect(1*size_images*size_images*3);
}
else {
byteBuffer=ByteBuffer.allocateDirect(4*1*size_images*size_images*3);
}
byteBuffer.order(ByteOrder.nativeOrder());
int[] intValues=new int[size_images*size_images];
bitmap.getPixels(intValues,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
int pixel=0;
for (int i=0;i<size_images;++i){
for (int j=0;j<size_images;++j){
final int val=intValues[pixel++];
if(quant==0){
byteBuffer.put((byte) ((val>>16)&0xFF));
byteBuffer.put((byte) ((val>>8)&0xFF));
byteBuffer.put((byte) (val&0xFF));
}
else {
byteBuffer.putFloat((((val >> 16) & 0xFF))/255.0f);
byteBuffer.putFloat((((val >> 8) & 0xFF))/255.0f);
byteBuffer.putFloat((((val) & 0xFF))/255.0f);
}
}
}
return byteBuffer;
}
}
PreviewImageActivity.java
package bline.detector.com.ffmpegvideoeditor.activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import bline.detector.com.ffmpegvideoeditor.R;
public class PreviewImageActivity extends AppCompatActivity {
private static final String FILEPATH = "filepath";
private objectDetectorClass objectDetectorClass;
private ImageSwitcher imageSwitcher;
private Button prev;
private Button next;
int placement = 0;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview_image);
TextView tvInstruction = (TextView) findViewById(R.id.tvInstruction);
imageSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
prev = findViewById(R.id.prev);
next = findViewById(R.id.next);
ArrayList<Bitmap> bitmap = new ArrayList<Bitmap>();
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
ArrayList<Drawable> drawables = new ArrayList<Drawable>();
try {
objectDetectorClass = new objectDetectorClass(getAssets(), "bline_model.tflite", "bline_label.txt", 300);
Log.d("PreviewImageActivity", "Model is successfully loaded");
} catch (IOException e) {
Log.d("PreviewImageActivity", "Getting some error");
e.printStackTrace();
}
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
#Override
public View makeView() {
ImageView imageView = new ImageView(getApplicationContext());
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
return imageView;
}
});
prev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (placement > 0) {
placement--;
imageSwitcher.setImageDrawable(drawables.get(placement));
} else {
Toast.makeText(PreviewImageActivity.this, "No Previous Images", Toast.LENGTH_SHORT).show();
}
}
});
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (placement < drawables.size() - 1) {
placement++;
imageSwitcher.setImageDrawable(drawables.get(placement));
} else {
Toast.makeText(PreviewImageActivity.this, "No More Images", Toast.LENGTH_SHORT).show();
}
}
});
String filePath = getIntent().getStringExtra(FILEPATH);
ArrayList<String> f = new ArrayList<String>();
File dir = new File(filePath);
tvInstruction.setText("Images stored at path " + filePath);
File[] listFile;
listFile = dir.listFiles();
for (File e : listFile) {
f.add(e.getAbsolutePath());
}
if (f != null) {
Log.d("PreviewImageAdapter", "filepath: " + f);
for (int position = 0; position < f.size(); position++) {
Bitmap bmp = BitmapFactory.decodeFile(f.get(position));
bitmap.add(bmp);
Log.d("PreviewImageAdapter", "bitmap: " + bitmap);
if (bitmap.size() == f.size()) {
for (int m = 0; m < bitmap.size(); m++) {
Mat selected_image = new Mat(bitmap.get(m).getHeight(), bitmap.get(m).getWidth(), CvType.CV_8UC4);
Utils.bitmapToMat(bitmap.get(m), selected_image);
selected_image = objectDetectorClass.recognizeVideo(selected_image);
Bitmap bitmap1 = Bitmap.createBitmap(selected_image.cols(), selected_image.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(selected_image, bitmap1);
bitmaps.add(bitmap1);
Log.d("PreviewImageAdapter", "detected images: " + bitmaps);
}
if (bitmaps.size() == bitmap.size()) {
for (int n = 0; n < bitmaps.size(); n++) {
Drawable drawable = new BitmapDrawable(bitmaps.get(n));
drawables.add(drawable);
Log.d("PreviewImageAdapter", "drawables: " + drawables);
}
}
imageSwitcher.setImageDrawable(drawables.get(0));
placement = 0;
}
}
}
}
}
I am also new to java and am sorry if my question is silly.
I cannot get my imageview uploaded from gallery to stay once the application closes. I already looked at other questions like this one but it is not working for me. I tried shared pref but it is not working. I might be doing it wrong. Could someone look at my code? I want the imageview uploaded from gallery to stay in the imageview even after the application is closed. I want it to only changed when a new picture is uploaded from the gallery.I have already tried shared preference, but I am pretty sure I did it wrong. It is in the code that I have below. I also used base64.
need help..thanks in advance
here is my code :
package com.example.upload;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Base64;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import com.squareup.picasso.Picasso;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URI;
public class MainActivity extends Activity {
String TAG = "Hello";
private Button mButtonChooseImage;
private ImageView mImageView;
private Uri mImageUri;
private static final int PICK_IMAGE_REQUEST = 1;
private Bitmap bitmap;
private static int RESULT_LOAD_IMG = 1;
String imgDecodableString;
private String selectedImagePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.image_view);
mButtonChooseImage = (Button) findViewById(R.id.button_choose_image);
mButtonChooseImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openFileChooser();
}
});
Intent intent = getIntent();
if (getIntent().getExtras() != null) {
// for get data from intent
bitmap = intent.getParcelableExtra("PRODUCT_PHOTO");
// for set this picture to imageview
mImageView.setImageBitmap(bitmap);
sharedPreferences();
} else {
retrivesharedPreferences();
}
}
private void sharedPreferences() {
SharedPreferences shared = getSharedPreferences("App_settings", MODE_PRIVATE);
SharedPreferences.Editor editor = shared.edit();
editor.putString("PRODUCT_PHOTO", encodeTobase64(bitmap));
editor.commit();
}
private void retrivesharedPreferences() {
SharedPreferences shared = getSharedPreferences("MyApp_Settings", MODE_PRIVATE);
String photo = shared.getString("PRODUCT_PHOTO", "photo");
assert photo != null;
if (!photo.equals("photo")) {
byte[] b = Base64.decode(photo, Base64.DEFAULT);
InputStream is = new ByteArrayInputStream(b);
bitmap = BitmapFactory.decodeStream(is);
mImageView.setImageBitmap(bitmap);
}
}
public static String encodeTobase64(Bitmap image) {
Bitmap bitmap_image = image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap_image.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] b = baos.toByteArray();
String imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
return imageEncoded;
}
private void openFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
mImageUri = data.getData();
Picasso.get().load(mImageUri).into(mImageView);
selectedImagePath = getPath(mImageUri);
}
}
private String getPath(Uri mImageUri) {
if (mImageUri == null) {
}
return null;
}
#Override
protected void onResume() {
SharedPreferences sp = getSharedPreferences("AppSharedPref", MODE_PRIVATE);
selectedImagePath = sp.getString("ImagePath", "");
Bitmap myBitmap = BitmapFactory.decodeFile(selectedImagePath);
mImageView.setImageBitmap(myBitmap);
Picasso.get().load(mImageUri).into(mImageView);
super.onResume();
}
public void ff(View view) {
Intent i = new Intent(this, Main2Activity.class);
startActivity(i);
}
}
There are two Standard options 'Camera' and 'Gallery'. First I choose the option 'Camera', then capture the image and then edit and save.
HomeActivity.java file:
package com.saashtechs.photoeditor;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.support.annotation.NonNull;
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.util.Log;
import android.view.View;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Objects;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class HomeActivity extends AppCompatActivity {
private static final String TAG = "HomeActivity";
private static final int GALLERY_RESULT = 1;
private static final int CAMERA_RESULT = 2;
private static final String FILE_PROVIDER_AUTHORITY = "com.saashtechs.photoeditor";
private static final int CAMERA_PERMISSION_REQ_CODE = 1001;
private static final int STORAGE_PERMISSION_REQ_CODE = 1002;
private Uri imageToUploadUri;
private String mCapturedImagePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}
public void openCamera(View view) {
// check for camera permission if not granted before
if (ContextCompat.checkSelfPermission(this, CAMERA) != PERMISSION_GRANTED) {
String[] cameraPermission = {CAMERA};
ActivityCompat.requestPermissions(this, cameraPermission, CAMERA_PERMISSION_REQ_CODE);
} else {
dispatchImageCaptureIntent();
}
}
public void openGallery(View view) {
// check for storage permission if not granted before
if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
String[] storagePermissions = {READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE};
ActivityCompat.requestPermissions(this, storagePermissions, STORAGE_PERMISSION_REQ_CODE);
} else {
dispatchGalleryIntent();
}
}
private void dispatchGalleryIntent() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, GALLERY_RESULT);
}
private void dispatchImageCaptureIntent() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
Uri photoFileUri = FileProvider.getUriForFile(this, FILE_PROVIDER_AUTHORITY, photoFile);
Log.d(TAG, "dispatchImageCaptureIntent:photoFileUri: " + photoFile.toString());
imageToUploadUri = photoFileUri;
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri);
startActivityForResult(cameraIntent, CAMERA_RESULT);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case CAMERA_PERMISSION_REQ_CODE:
if (grantResults[0] == PERMISSION_GRANTED) {
dispatchImageCaptureIntent();
} else {
Toast.makeText(this, "Required camera permission not granted", Toast.LENGTH_SHORT).show();
}
break;
case STORAGE_PERMISSION_REQ_CODE:
if (grantResults[0] == PERMISSION_GRANTED) {
dispatchGalleryIntent();
} else {
Toast.makeText(this, "Required storage permission not granted", Toast.LENGTH_SHORT)
.show();
}
break;
default:
throw new IllegalArgumentException("Unexpected request code");
}
}
private File createImageFile() throws IOException {
String timeStamp = DateFormat.getDateTimeInstance().format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
mCapturedImagePath = image.getAbsolutePath();
Log.d(TAG, "createImageFile: " + mCapturedImagePath);
return image;
}
private Bundle uriToBundle(Uri imageUri) {
Bundle bundle = new Bundle();
bundle.putString(MainActivity.IMAGE_URI, imageUri.toString());
return bundle;
}
public Bitmap resizeBitmap(Bitmap getBitmap, int maxSize) {
int width = getBitmap.getWidth();
int height = getBitmap.getHeight();
double resized_image;
if (width >= height && width > maxSize) {
resized_image = width / height;
width = maxSize;
height = (int) (maxSize / resized_image);
} else if (height >= width && height > maxSize) {
resized_image = height / width;
height = maxSize;
width = (int) (maxSize / resized_image);
}
return Bitmap.createScaledBitmap(getBitmap, width, height, false);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == GALLERY_RESULT) {
Uri imageUri = data.getData();
startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageUri))));
} else if (requestCode == CAMERA_RESULT) {
File imageFile = new File(mCapturedImagePath);
Bitmap image = BitmapFactory.decodeFile(mCapturedImagePath);
image = Bitmap.createScaledBitmap(image, 4477, 3351, false);
image = resizeBitmap(image, 4477);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
try {
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "filename.jpg");
boolean result;
result = file.createNewFile();
if (result) {
FileOutputStream fo = new FileOutputStream(imageFile);
fo.write(bytes.toByteArray());
fo.close();
}
} catch(IOException ie) {
ie.printStackTrace();
}
startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageToUploadUri))));
}
} else {
Toast.makeText(this, "Image not loaded.", Toast.LENGTH_SHORT).show();
}
}
public static Intent getIntent(Context context) {
return new Intent(context, HomeActivity.class);
}
}
When the app is used for the first time, after image is captured, the folder is not getting created for the saved image to be stored in Gallery/Photos app. If I use 'Gallery' as the option to save the image, folder gets created. After the folder gets created, then if I capture the image, the captured image gets stored since folder is already created through 'Gallery' option
Can anyone please help?
Thanks in advance
How about changing File imageFile = new File(mCapturedImagePath); with
File imageFile = new File(intent.getData());
mCapturedImagePath is always empty when activityResult is being called. you would need to get the image path from the intent and then get a File instance from the path or uri. intent#getData() returns the uri of the image.
Recently I made webview app on Android Studio. And I notice weird problem: When user click on "Browse Image" link nothing happens. I am trying to make a code so user can choose file from their Gallery on mobile phone.
emulator screenshot
Here is my MainActivity.java
package com.ijust2.ijust2;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.File;
public class MainActivity extends Activity {
private WebView webView;
private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE=1;
private static final int PICK_IMAGE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(new myWebClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://ijust2.com");
}
public class myWebClient extends WebViewClient
{
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
#Override
// This method is used to detect back button
public void onBackPressed() {
if(webView.canGoBack()) {
webView.goBack();
} else {
// Let the system handle the back button
super.onBackPressed();
}
}
}
my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ijust2.ijust2.MainActivity">
<WebView
android:id="#+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</RelativeLayout>
Can anyone give me some tips or suggest what should I do. I am newbie.
Thanks, Edi
I found a solution. Here is a code:
package it.floryn90.webapp;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends ActionBarActivity {
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private WebView webView;
private WebSettings webSettings;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
return;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webview);
webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAllowFileAccess(true);
webView.setWebViewClient(new Client());
webView.setWebChromeClient(new ChromeClient());
if (Build.VERSION.SDK_INT >= 19) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
else if(Build.VERSION.SDK_INT >=11 && Build.VERSION.SDK_INT < 19) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.loadUrl("http://example.com"); //change with your website
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
public class ChromeClient extends WebChromeClient {
// For Android 5.0
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e(TAG, "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
// openFileChooser for Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
// Create AndroidExampleFolder at sdcard
// Create AndroidExampleFolder at sdcard
File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "AndroidExampleFolder");
if (!imageStorageDir.exists()) {
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
// Camera capture image intent
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
// Create file chooser intent
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
// Set camera intent to file chooser
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
, new Parcelable[] { captureIntent });
// On select image call onActivityResult method of activity
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
// openFileChooser for Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
//openFileChooser for other Android versions
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType,
String capture) {
openFileChooser(uploadMsg, acceptType);
}
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
public class Client extends WebViewClient {
ProgressDialog progressDialog;
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// If url contains mailto link then open Mail Intent
if (url.contains("mailto:")) {
// Could be cleverer and use a regex
//Open links in new browser
view.getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
// Here we can open new activity
return true;
}else {
// Stay within this webview and load url
view.loadUrl(url);
return true;
}
}
//Show loader on url load
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// Then show progress Dialog
// in standard case YourActivity.this
if (progressDialog == null) {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
}
// Called when all page resources loaded
public void onPageFinished(WebView view, String url) {
try {
// Close progressDialog
if (progressDialog.isShowing()) {
progressDialog.dismiss();
progressDialog = null;
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}