Hello everyone, My group for Thesis project is currently having problems on running our android app using Android Studio, The concept is Steganography and we are using an F5 Library from https://github.com/guardianproject/PixelKnot/tree/version_2/PixelKnot/src/main/java/info/guardianproject/pixelknot
Here is our user interface and whenever clicking embed button, the app closes automatically
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.angel.filepicker, PID: 2972
java.lang.NullPointerException: Attempt to invoke virtual method 'void info.guardianproject.f5android.stego.StegoProcessor.addThread(info.guardianproject.f5android.stego.StegoProcessThread, boolean)' on a null object reference
at com.example.angel.filepicker.EmbedFragment$3.onClick(EmbedFragment.java:162)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
EmbedFragment.java code
package com.example.angel.filepicker;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
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.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaScannerConnection;
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.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import info.guardianproject.f5android.plugins.f5.Embed;
import info.guardianproject.f5android.stego.*;
import info.guardianproject.f5android.plugins.PluginNotificationListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import static android.app.Activity.RESULT_OK;
public class EmbedFragment extends Fragment {
private static final String TAG = "EMbed";
public EmbedFragment() {
}
private Activity a;
public File finalFile;
public File msgFile;
public byte[] seed = new String("This is hopefully Temporary").getBytes();
public String baseimage;
public String secret_file;
public Intent fileIntent;
public static Activity act;
public static Context cntx;
public StegoProcessor stego_processor;
//FOR FILE BUTTON
public static final int FILE_PICKER_REQUEST_CODE = 1;
Intent intent;
Button btn_choose_image;
ImageView image;
TextView text;
//FOR IMAGE BUTTON
File photoFile = null;
static final int CAPTURE_IMAGE_REQUEST = 2;
static final int SELECT_FILE = 3;
String mCurrentPhotoPath;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.embed_fragment, container, false);
cntx = getActivity().getBaseContext();
act = getActivity();
//initialize and set intent type
fileIntent = new Intent();
fileIntent.setType("*/*");
fileIntent.setAction(Intent.ACTION_GET_CONTENT);
text = view.findViewById(R.id.textView2);
//FOR FILE BUTTON
Button pickButton = view.findViewById(R.id.pick_from_activity);
pickButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// checkPermissionsAndOpenFilePicker();
startActivityForResult(Intent.createChooser(fileIntent, "Select File"), FILE_PICKER_REQUEST_CODE);
}
});
//FOR IMAGE BUTTON
btn_choose_image = view.findViewById(R.id.btn_choose_image);
image = view.findViewById(R.id.imageView2);
btn_choose_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
captureImage();
}
});
final Button embedButton = (Button) view.findViewById(R.id.embedButton);
embedButton.setOnClickListener(embedButtonListener);
return view;
}
View.OnClickListener embedButtonListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
if(baseimage !=null)
{
if ( secret_file != null) {
//ImageSteganography Object instantiation
Embed embed = new Embed(a,baseimage , secret_file, seed) {
#Override
public void run() {
super.run();
}
};
stego_processor.addThread(embed, true);
}
}
}
};
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Log.e("onActivityResult", "requestCode " + requestCode + ", resultCode " + resultCode);
if (requestCode == FILE_PICKER_REQUEST_CODE && resultCode==RESULT_OK && data != null && data.getData() != null) {
Uri uri=data.getData();
try{
msgFile=new File(uri.getPath());//get the file
secret_file = uri.getPath();
//secretFile = getPathFromUri(getActivity(),uri);
Toast.makeText(act.getBaseContext(), "Picked file: " + msgFile, Toast.LENGTH_LONG).show();
//text.setText(textx);
}catch(Exception e){}
if(msgFile.length()==0){
try{
msgFile=new File(getPathFromUri(getActivity(),uri));//get the file
// secretFile = getPathFromUri(getActivity(),uri);
Toast.makeText(act.getBaseContext(), "Picked file: " + msgFile, Toast.LENGTH_LONG).show();
}catch(Exception e){
Log.e("Main","Unable to get file!");
e.printStackTrace();
}
}
}
if (requestCode == CAPTURE_IMAGE_REQUEST && resultCode == RESULT_OK) {
// baseImage = photoFile.getAbsoluteFile();
Bitmap myBitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
image.setImageBitmap(myBitmap);
}
//PROBLEMA NITO IS YUNG PAG DISPLAY NG PIC YUNG SIZE NG PIC .
// MAY METHOD NA RESIZIND PERO TSAKA NA CGURO PAG NALAGAY NA UI
if (requestCode == SELECT_FILE && data != null && data.getData() != null) {
// baseImage = getRealPathFromURI(getActivity(), data.getData());
Uri uri=data.getData();
try {
// mengambil gambar dari Gallery
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
baseimage = uri.getPath();
image.setImageBitmap(bitmap);
text.setText(baseimage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// private String getRealPathFromURI(Context context, Uri contentUri) {
// Cursor cursor = null;
// try {
// String[] proj = { MediaStore.Images.Media.DATA };
// cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
// int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// cursor.moveToFirst();
// return cursor.getString(column_index);
// } catch (Exception e) {
// Log.e(TAG, "getRealPathFromURI Exception : " + e.toString());
// return "";
// } finally {
// if (cursor != null) {
// cursor.close();
// }
// }
// }
public static String getPathFromUri(final Context context, final Uri uri) {//get path name from a uri object(source: web)
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];
}
// TODO handle non-primary volumes
}
// 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;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.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 the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static 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 index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
//...................................................................................................................................
//FOR IMAGE BUTTON
private void captureImage() {
image.setImageResource(0);
final CharSequence[] items = {"Take Photo", "Choose from Library",
"Cancel"};
//ITO YUNG CHOICE KUNG TAKE PHOTO OR SELECT IMAGE . KAPAG TAKE PHOTO DAPAT
// NASASAVE SA GALLERY PERO WALA AKO NAKITA SA GALLERY KO HAHAH FEELING KO MAS OKAY PAG DI NLNG NASSASAVE
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Add Photo!");
builder.setIcon(R.mipmap.ic_launcher);
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Take Photo")) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getContext().getPackageManager()) != null) {
// Create the File where the photo should go
try {
photoFile = createImageFile();
displayMessage(getActivity().getBaseContext(), photoFile.getAbsolutePath());
Log.i("Stegrapp", photoFile.getAbsolutePath());
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getActivity(),
"com.example.angel.filepicker.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, CAPTURE_IMAGE_REQUEST);
}
} catch (Exception ex) {
// Error occurred while creating the File
displayMessage(getActivity().getBaseContext(), ex.getMessage().toString());
}
} else {
displayMessage(getActivity().getBaseContext(), "Nullll");
}
//PROBLEMA NITO IS YUNG PAG DISPLAY NG PIC YUNG SIZE NG PIC .
// MAY METHOD NA RESIZIND PERO TSAKA NA CGURO PAG NALAGAY NA UI
} else if (items[item].equals("Choose from Library")) {
intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_FILE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
//........................................................................................................
//ITO YUNG PAG CREATE NG FILE NUNG IMAGE GALING CAMERA
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 = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private void displayMessage(Context context, String message)
{
Toast.makeText(context,message,Toast.LENGTH_LONG).show();
}
public static void show(final String toast){
act.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(EmbedFragment.cntx,toast,Toast.LENGTH_LONG).show();
}
});
}
}
MainActivity.java code
package com.example.angel.filepicker;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private static int SPLASH_TIME_OUT = 4000;
ImageView imageView;
Toolbar toolbar;
ViewPager viewPager;
TabLayout tabLayout;
FloatingActionButton shareButton;
Button btn_choose_image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar_id);
viewPager = findViewById(R.id.viewPager_id);
tabLayout = findViewById(R.id.tabLayout_id);
shareButton = findViewById(R.id.shareButton_id);
//sharing
shareButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(Intent.ACTION_SEND);
// this should be the file
// must create folder the carrier image
// this is a sample that takes string
//intent takes string should be file
myIntent.setType("text/plain");
//should be the carrier image
String shareBody = "Your body here";
// can be removed / optional
String shareSub = "Your subject here";
myIntent.putExtra(Intent.EXTRA_SUBJECT,shareSub);
myIntent.putExtra(Intent.EXTRA_TEXT,shareBody);
startActivity(Intent.createChooser(myIntent, "Share using"));
}
});
// SETTING UP ViewPagerAdapter
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPagerAdapter.addElements(new EmbedFragment(), "Embed");
viewPagerAdapter.addElements(new ExtractFragment(), "Extract");
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
}
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.
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();
}
}
}
}
In my application there is a button to "upload a picture": taking a photo from camera or choosing from gallery.
On both options, there are 3 problems:
1) When clicking again to upload another picture - the application crushes
2) On the first "upload", the picture is rotated on the side (90 degrees counterclockwise)
3) The picture's size is the original size and I want it to be compressed to resolution of 125x125.
Please help (even if you have a solution to one problem)
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import entities.Order;
public class SellABookFragment extends Fragment implements View.OnClickListener {
private ImageView ivBookPicture;
private EditText etBookName, etBookAuthor, etBookGenre, etBookPublishing, etQuantity, etBookPrice, etBookDetails;
private Button bUploadPicture, bAddBook;
public SellABookFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_sell_a_book, container, false);
ivBookPicture = (ImageView) view.findViewById(R.id.ivBook_Picture);
etBookName = (EditText) view.findViewById(R.id.etBook_Name);
etBookAuthor = (EditText) view.findViewById(R.id.etAuthor_Name);
etBookGenre = (EditText) view.findViewById(R.id.etGenre);
etBookPublishing = (EditText) view.findViewById(R.id.etPublishing_Year);
etQuantity = (EditText) view.findViewById(R.id.etBook_Quantity);
etBookPrice = (EditText) view.findViewById(R.id.etBook_Price);
etBookDetails = (EditText) view.findViewById(R.id.etBook_Details);
bUploadPicture = (Button) view.findViewById(R.id.bUpload_Picture);
bAddBook = (Button) view.findViewById(R.id.bAdd_Book);
bUploadPicture.setOnClickListener(this);
bAddBook.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bUpload_Picture:
selectPicture();
break;
case R.id.bAdd_Book:
addBook();
break;
}
}
private void addBook() {
try {
HomeActivity.backEnd.addOrder(new Order(HomeActivity.LoggedUser.getID(),
etBookGenre.getText().toString(),
etBookName.getText().toString(),
Integer.parseInt(etBookPublishing.getText().toString()),
etBookAuthor.getText().toString(),
Double.parseDouble(etBookPrice.getText().toString()),
(Integer) ivBookPicture.getTag()));
} catch (Exception e) {
Toast.makeText(getActivity().getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}
private void selectPicture() {
final CharSequence[] options = {
getResources().getString(R.string.take_photo),
getResources().getString(R.string.gallery_choose),
getResources().getString(R.string.cancel)};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getResources().getString(R.string.upload_picture));
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals(getResources().getString(R.string.take_photo))) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "tmp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, 1);
} else if (options[item].equals(getResources().getString(R.string.gallery_choose))) {
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 2);
} else
dialog.dismiss();
}
});
builder.show();
}
Bitmap bitmap;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
OutputStream outFile;
String path = android.os.Environment.getExternalStorageDirectory()
+ File.separator
+ "MyApp";
File file;
if (resultCode == Activity.RESULT_OK) {
if (bitmap != null) {
ivBookPicture.setImageBitmap(null);
bitmap.recycle();
bitmap = null;
}
try {
if (requestCode == 1) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File tmp : f.listFiles()) {
if (tmp.getName().equals("tmp.jpg")) {
f = tmp;
break;
}
}
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(), bitmapOptions);
ivBookPicture.setImageBitmap(bitmap);
if (f.delete()) {
file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
outFile = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
} else if (requestCode == 2) {
Uri selectedImage = data.getData();
String[] filePath = {MediaStore.Images.Media.DATA};
Cursor c = getActivity().getContentResolver().query(selectedImage, filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
bitmap = (BitmapFactory.decodeFile(picturePath));
Log.w("image path", picturePath);
ivBookPicture.setImageBitmap(bitmap);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The ImageView which contains the uploaded picture:
<ImageView
android:id="#+id/ivBook_Picture"
android:layout_width="#dimen/sell_a_book_picture_size"
android:layout_height="#dimen/sell_a_book_picture_size"
android:src="#mipmap/ic_launcher" />
Thanks!
public Bitmap compressBySize(String pathName, int targetWidth,
int targetHeight) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(pathName, opts);
int imgWidth = opts.outWidth;
int imgHeight = opts.outHeight;
int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth);
int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight);
if (widthRatio > 1 || heightRatio > 1) {
if (widthRatio > heightRatio) {
opts.inSampleSize = widthRatio;
} else {
opts.inSampleSize = heightRatio;
}
}
opts.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(pathName, opts);
return bitmap;
}
Use this method to do the compress,just set the targetWidth&targetHeight yourself.
Also,you can use bitmap.compress(Bitmap.CompressFormat.JPEG, compressRate, byteOutputStream); to compress your bitmap by quality.
For the crash,it's because the picture bitmap takes too much memory.You should compress the picture and remember to release the memory after your first upload.You can consider using a WeakReference.