I am building an app to upload images to my company server
I am using koush-ion for the upload,
now my problem is I have to dynamically change the URL for upload depending on information entered in another activity(LoginActivity) via edittext boxes
and I don't understand how to do that
so what I want to happen is the client enters thier Email, password and clientID(4 digits)(in LoginActivity) and the app uses that to build a url for the upload
like this one(in CameraActivity)
https://www.blahpractice.co.za/files-upload-ruben.asp?MyForm=Yes&ClientID=1234&Username=man#blahpractice.co.za&Pwd=BlahBlah123#
I got this From the koush github, and i am unsure if this is what i am looking for and also how to implement data from another activity in koush-ion
Post application/x-www-form-urlencoded and read a String
Ion.with(getContext())
.load("https://koush.clockworkmod.com/test/echo")
.setBodyParameter("goop", "noop")
.setBodyParameter("foo", "bar")
.asString()
.setCallback(...)
Camera Activity
public class CameraActivity extends AppCompatActivity implements
View.OnClickListener{
private final int PICK_IMAGE = 12345;
private final int REQUEST_CAMERA = 6352;
private static final int REQUEST_CAMERA_ACCESS_PERMISSION =5674;
private Bitmap bitmap;
private ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
imageView =findViewById(R.id.imageView);
Button fromCamera=findViewById(R.id.fromCamera);
Button fromGallery=findViewById(R.id.fromGallery);
Button upload=findViewById(R.id.upload);
upload.setOnClickListener(this);
fromCamera.setOnClickListener(this);
fromGallery.setOnClickListener(this);
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
fromCamera.setVisibility(View.GONE);
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.fromCamera:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_ACCESS_PERMISSION);
}else {
getImageFromCamera();
}
break;
case R.id.fromGallery:
getImageFromGallery();
break;
case R.id.upload:
if (bitmap != null)
uploadImageToServer();
break;
}
}
private void uploadImageToServer() {
I want to call the url here
File imageFile = persistImage(bitmap, "SP_Upload");
Ion.with(this)
.load("https://www.Blahpractice.co.za/files-upload-ruben.asp?MyForm=Yes")
.setMultipartFile("SP-LOG", "image/jpeg", imageFile)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
}
});
}
private File persistImage(Bitmap bitmap, String name) {
File filesDir = getApplicationContext().getFilesDir();
File imageFile = new File(filesDir, name + ".jpg");
OutputStream os;
try {
os = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.flush();
os.close();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
}
return imageFile;
}
private void getImageFromCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}
private void getImageFromGallery() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE) {
if (resultCode == Activity.RESULT_OK) {
try {
InputStream inputStream = getContentResolver().openInputStream(data.getData());
bitmap = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
} else if (requestCode == REQUEST_CAMERA) {
if (resultCode == Activity.RESULT_OK) {
Bundle extras = data.getExtras();
bitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(bitmap);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CAMERA_ACCESS_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getImageFromCamera();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
LoginActivity
public class LoginActivity extends AppCompatActivity {
private EditText email, password, id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
email=findViewById(R.id.emailtext);
password=findViewById(R.id.pwdtext);
id=findViewById(R.id.clientid);
Button loginBtn=findViewById(R.id.button);
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String emailAddress=email.getText().toString().trim();
String userPassword=password.getText().toString().trim();
String clientId=id.getText().toString().trim();
Intent intent=new Intent(LoginActivity.this, CameraActivity.class);
intent.putExtra("clientId", clientId);
intent.putExtra("email", emailAddress);
intent.putExtra("password", userPassword);
startActivity(intent);
}
});
}
}
You could store the url on the shared preferences and retrieve it every time you execute your upload task and set it on the .load() method.
Also, what you need to send an image to your server is a multipart post. I haven't used Ion but I have used multipart in other libraries like OkHttp, I´ve copied the method that appears on the Ion documentation:
String dynamicUrl = PreferenceManager.getDefaultSharedPreferences(context).getString(CURRENT_SELECTED_URL, null);
File myImage = new File(myImagePath);
if(dynamicUrl != null) {
Ion.with(getContext())
.load(dynamicUrl)
.uploadProgressBar(uploadProgressBar)
.setMultipartParameter("goop", "noop")
.setMultipartFile("myImageName", "image/*", myImage)
.asJsonObject()
.setCallback(...)
}
Related
I am trying to use Ucrop from a fragment. The issue I am facing is that onActivityresult is not receiving requestCode == UCrop.REQUEST_CROP thus not performing the actions I need to do with the image. I have searched around for tutorials but I haven't managed to find any.
The following is the code of the fragment that is using UCrop:
public class FragmentSettingsTabImage extends Fragment {
private String TAG = "----->";
Tools t;
private String currentPhotoPath;
private final int REQUEST_TAKE_PHOTO = 1;
private final int CAMERA_PERMISSIONS = 2;
private ImageView imgTabImageDriver;
private Button btnSettingsSaveImage;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == CAMERA_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// All good so launch take picture from here
dispatchTakePictureIntent();
} else {
// Permission denied. Warn the user and kick out of app
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.permsDeniedCameraTitle);
builder.setMessage(R.string.permsDeniedCameraMessage);
builder.setCancelable(false);
builder.setPositiveButton(R.string.close, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Objects.requireNonNull(getActivity()).finishAffinity();
}
});
builder.create().show();
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
Uri starturi = Uri.fromFile(new File(currentPhotoPath));
Uri destinationuri = Uri.fromFile(new File(currentPhotoPath));
UCrop.Options options = AppConstants.makeUcropOptions(Objects.requireNonNull(getActivity()));
UCrop.of(starturi, destinationuri).withOptions(options).start(getActivity());
}
Log.d(TAG, "onActivityResult: CCCCCCC" + resultCode + " " + requestCode);
// On result from cropper add to imageview
getActivity();
if (resultCode == Activity.RESULT_OK && requestCode == UCrop.REQUEST_CROP) {
final Uri resultUri = UCrop.getOutput(data);
assert resultUri != null;
File imgFile = new File(resultUri.getPath());
Picasso.Builder builder = new Picasso.Builder(Objects.requireNonNull(getActivity()));
builder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
exception.printStackTrace();
}
});
builder.build().load(imgFile).into(imgTabImageDriver, new Callback() {
#Override
public void onSuccess() {
btnSettingsSaveImage.setEnabled(true);
}
#Override
public void onError(Exception e) {
e.printStackTrace();
}
});
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
SharedPreferences preferences = Objects.requireNonNull(this.getActivity()).getSharedPreferences("mykago-driver", Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = preferences.edit();
View view = inflater.inflate(R.layout.fragment_settings_tab_image, container, false);
imgTabImageDriver= view.findViewById(R.id.imgTabImageDriver);
ImageView imgTakeSettingsDriverPicture = view.findViewById(R.id.imgTakeSettingsDriverPicture);
btnSettingsSaveImage = view.findViewById(R.id.btnSettingsSaveImage);
imgTakeSettingsDriverPicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
imgTabImageDriver.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
btnSettingsSaveImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editor.putString("driver_picture", currentPhotoPath);
editor.apply();
}
});
Picasso.Builder builder = new Picasso.Builder(Objects.requireNonNull(getContext()));
builder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
exception.printStackTrace();
}
});
Log.d(TAG, "onCreateView: " + preferences.getString("driver_picture", ""));
builder.build().load(new File(preferences.getString("id_picture", ""))).into(imgTabImageDriver);
return view;
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(Objects.requireNonNull(getActivity()).getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Log.d("IMAGE CREATION", ex.toString());
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getActivity(),
"com.mytestapp.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = "didimage_" + timeStamp + "_";
File storageDir = Objects.requireNonNull(getActivity()).getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName,
".png",
storageDir
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
}
The same code from a normal activity works without any issues. Any help appreciated.
Managed to solve the issue. To pass the result of the UCrop activity to the fragment and not to the hosting activity you need to call the UCrop....start() method as follows:
UCrop.of(starturi, destinationuri).withOptions(options).start(getActivity().getApplicationContext(), getFragmentManager().findFragmentByTag("your_fragment_tag"));
so
.start(Context, Fragment)
This will make sure that the onActivityResult of the fragment gets called and not the one of the hosting activity.
This works also:
UCrop.of(sourceUri,destinationUri)
.withOptions(options)
.start(getActivity(),YourFragment.this);
If you want to start uCrop activity from Fragment use this.
UCrop.of(uri, destinationFileName)
.withAspectRatio(1, 1)
.start(getContext(), this, UCrop.REQUEST_CROP);
I am trying to upload Image to firebase storage but I am neither seeing the progress dialog nor the toast message.
The debug breakpoint is not even stopping at those lines.
Please help.
ib_profileImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent_modifyImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent_modifyImage);
}
});
}
//Image Capture Activity Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK){
progressDialog.setMessage("Uploading Image...");
progressDialog.show();
Uri uri = data.getData();
StorageReference filepath = storageReference_image.child("profile_photos").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(UserProfileActivity.this,"Upload Complete",Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
});
}
}
try this
public class MainActivity extends AppCompatActivity {
Button chooseImg, uploadImg;
ImageView imgView;
int PICK_IMAGE_REQUEST = 111;
Uri filePath;
ProgressDialog pd;
//creating reference to firebase storage
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("gs://fir-example-c4312.appspot.com"); //change the url according to your firebase app
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chooseImg = (Button)findViewById(R.id.chooseImg);
uploadImg = (Button)findViewById(R.id.uploadImg);
imgView = (ImageView)findViewById(R.id.imgView);
pd = new ProgressDialog(this);
pd.setMessage("Uploading....");
chooseImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
startActivityForResult(Intent.createChooser(intent, "Select Image"), PICK_IMAGE_REQUEST);
}
});
uploadImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(filePath != null) {
pd.show();
StorageReference childRef = storageRef.child("image.jpg");
//uploading the image
UploadTask uploadTask = childRef.putFile(filePath);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
pd.dismiss();
Toast.makeText(MainActivity.this, "Upload successful", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
pd.dismiss();
Toast.makeText(MainActivity.this, "Upload Failed -> " + e, Toast.LENGTH_SHORT).show();
}
});
}
else {
Toast.makeText(MainActivity.this, "Select an image", Toast.LENGTH_SHORT).show();
}
}
});
}
#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) {
filePath = data.getData();
try {
//getting image from gallery
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
//Setting image to ImageView
imgView.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
don't forget to Change Rules in firebase console
By default we are not allowed to access firebase storage without authentication. To change it go to firebase console using any web browser. Open the firebase project that you have used in above steps and go to Storage and then Rules tab. Now change read and write rules to true as shown in below image.
try this method,its worked for me
Inside onActivityResult,
StorageReference storageRef = storage.getReferenceFromUrl(---STORAGE_BUCKET---);
StorageReference imagePathReference = storageRef.child("image");
final Uri uri = data.getData();
Bitmap bmp = null;
try {
bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
// convert bitmap to byte array to save image in firebase storage
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (bmp != null) {
bmp.compress(Bitmap.CompressFormat.JPEG, 60, bos);
}
byte[] dataNew = bos.toByteArray();
uploadTask = imagePathReference.putBytes(dataNew);
try {
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// success
}
});
}catch (Exception e){
}
I am trying to build an app that enables you to change your profile picture. When the app opens for the first time, it contains a Networkimageview for the current profile pic and a button to change the picture. When the button is pressed a new Activity is started that enables one to choose an image from the gallery and upload to a server.
When the upload is done, the new Activity is closed and the app returns to the MainActivity. How can I make the MainActivity to reload the image just uploaded to the server when the image uploads successfully from the new activity and closes? This is my code
Here's the MainActivity.java
public class MainActivity extends AppCompatActivity {
ImageLoader mImageLoader;
NetworkImageView mNetworkImageView;
private Button buttonChoose;
static final int PROFILE_PICTURE_REQUEST = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonChoose = (Button) findViewById(R.id.buttonChoose);
mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
loadImage();
}
private String url = "http://10.0.2.2/images/0.jpg";
private void loadImage() {
mImageLoader = CustomVolleyRequest.getInstance(this).getImageLoader();
mNetworkImageView.setImageUrl(url, mImageLoader);
}
public void newActivity(View view) {
Intent profileIntent = new Intent(this, Activity2.class);
startActivityForResult(profileIntent, PROFILE_PICTURE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PROFILE_PICTURE_REQUEST) {
if (resultCode == RESULT_OK) {
loadImage();
}
}
}
}
The second activity Activity2.java
public class Activity2 extends AppCompatActivity implements View.OnClickListener {
private Bitmap bitmap;
private ImageView imageView;
private int PICK_IMAGE_REQUEST = 1;
private String UPLOAD_URL ="http://10.0.2.2/uploadd.php";
private String KEY_IMAGE = "image";
private Button buttonUpload;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
imageView = (ImageView) findViewById(R.id.imageView);
buttonUpload = (Button) findViewById(R.id.buttonUpload);
buttonUpload.setOnClickListener(this);
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
public String getStringImage(Bitmap bmp) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
}
public void uploadImage() {
//Showing the progress dialog
final ProgressDialog loading = ProgressDialog.show(this, "Uploading...", "Please wait...", false, false);
StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String s) {
loading.dismiss();
Toast.makeText(Activity2.this, s, Toast.LENGTH_LONG).show();
Intent returnIntent = new Intent();
setResult(RESULT_OK,returnIntent);
finish();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
//Dismissing the progress dialog
loading.dismiss();
//Showing toast
Toast.makeText(Activity2.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
//Converting Bitmap to String
String image = getStringImage(bitmap);
//Creating parameters
Map<String, String> params = new Hashtable<String, String>();
//Adding parameters
params.put(KEY_IMAGE, image);
//returning parameters
return params;
}
};
//Creating a Request Queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(stringRequest);
}
#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) {
Uri filePath = data.getData();
try {
//Getting the Bitmap from Gallery
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
//Setting the Bitmap to ImageView
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onClick(View v) {
if(v == buttonUpload){
uploadImage();
}
}
}
When you're finishing the Activity2 on a successful image upload, you need to put some extras in the intent which is passed to the launcher activity which is MainActivity.
So the onResponse segment of your uploadImage() function should look like the following. Declare the filePath variable as public so that you can use it here too.
// Declare filePath as public
Uri filePath;
#Override
public void onResponse(String s) {
loading.dismiss();
Toast.makeText(Activity2.this, s, Toast.LENGTH_LONG).show();
Intent returnIntent = new Intent();
returnIntent.putExtra("UPDATED_PIC", filePath.toString());
setResult(RESULT_OK,returnIntent);
finish();
}
Now from your MainActivity handle the retuneIntent to get the filePath and load the image from there. So the onActivityResult may look like -
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PROFILE_PICTURE_REQUEST) {
if (resultCode == RESULT_OK) {
if(data != null) {
Uri filePath = Uri.parse(extras.getString("UPDATED_PIC"));
try {
//Getting the Bitmap from Gallery
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
// Setting the Bitmap to ImageView
mNetworkImageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I'm trying to make an app that uses the camera to take photos and sends this to my NAS, I managed to do create an app through a tutorial, which takes a picture, saves the picture and shows it onscreen. Another tutorial shows me how to upload a "selected" image by pressing an "extra" button on the screen, it's just that I want to get rid of this step and instead of showing the picture, it directly sends the picture to my NAS.
The current app I created:
package com.deshpande.camerademo;
public class MainActivity extends AppCompatActivity {
private Button takePictureButton;
private ImageView imageView;
private Uri file;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takePictureButton = (Button) findViewById(R.id.button_image);
imageView = (ImageView) findViewById(R.id.imageview);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
takePictureButton.setEnabled(false);
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 0) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
takePictureButton.setEnabled(true);
}
}
}
public void takePicture(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
file = Uri.fromFile(getOutputMediaFile());
intent.putExtra(MediaStore.EXTRA_OUTPUT, file);
startActivityForResult(intent, 100);
}
private static File getOutputMediaFile(){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "WedCam");
if (!mediaStorageDir.exists()){
if (!mediaStorageDir.mkdirs()){
Log.d("WedCam", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
if (resultCode == RESULT_OK) {
try {
final FTPClient client = new FTPClient();
final File image = new File(file.getPath());
final FileInputStream fis = new FileInputStream(image);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
client.connect("ftp://127.0.0.1:2221");
client.login("francis", "francis");
client.storeFile(image.getName(), fis);
client.logout();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
Thanks to #Matthias F. I got it all working, this guy is great!
You need to use your saved URI from the camera for the FileInputStream. Try it with this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
if (resultCode == RESULT_OK) {
try {
final FTPClient client = new FTPClient();
final File image = new File(file.getPath());
final FileInputStream fis = new FileInputStream(image);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
client.connect("127.0.0.1", 2221);
client.login("francis", "francis");
client.setFileType(FTP.BINARY_FILE_TYPE);
client.storeFile(image.getName(), fis);
client.logout();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Now the FileInputStream points to the created image.
EDIT:
The problem was that the upload was executed on the ui thread and that is not allowed in android. Now a new thead is created for the upload process. Also I forgot to say that you need to access a android permission for using network functionalities. So you need to set
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> in the AndroidManifest.xml.
i need to save a camera image from sd card to sqlite in android. The problem i am facing is out of memory exception. How i can compress this image and sav it in sqlite. The image format is jpeg
thanks in advance
jibysthomas
I do not know if this is the best way to save storage space using SQLite and I am still looking for it, but here we go.
You can select the source of your image, such as gallery or camera and below is the code.
private void selectProductImage() {
final CharSequence[] itens = {"Use Camera", "Gallery", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(this,R.style.AlertDialog);
builder.setItems(itens, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (itens[which].equals("Use Camera")) {
Toast.makeText(YourActivity.this, "Use Camera", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
} else {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
} else if (itens[which].equals("Gallery")) {
Toast.makeText(YourActivity.this, "Gallery", Toast.LENGTH_SHORT).show();
Intent galleryIntent = new Intent();
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, REQUEST_GALLERY_PHOTO);
} else if (itens[which].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
Maybe you need permission to use the camera
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_CAMERA_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
} else {
Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
Here is how to handle the image from the source you selected.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Bitmap bitmap = Bitmap.createScaledBitmap((Bitmap) data.getExtras().get("data"),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
}
if (requestCode == REQUEST_GALLERY_PHOTO && resultCode == RESULT_OK && data != null) {
//mProductImage.setImageURI(data.getData());
// INSERT IMAGE INTO SQLite
Uri uri = data.getData();
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
As you can notice in my example, there is no place to save the image case you selected camera and I placed the image on an ImageView variable named mProductImage.
From now, you can use a Button to save the image in your SQLite Database. Here is the function you can use for it.
private void saveImage() {
productTablePath = Environment.getExternalStorageDirectory()+"/YourAditionalPath/";
ProductDatabaseHelper productDatabaseHelper = new ProductDatabaseHelper(getApplicationContext(), "dbname.db", productTablePath);
productListTable = productDatabaseHelper.getWritableDatabase();
productRepository = new ProductRepository(productListTable);
try {
if (isPriviteImage) {
productRepository.addProduct(imageViewToByte(mProductImage));
isPriviteImage = false;
} else {
productRepository.addProduct(null);
}
mProductImage.setImageResource(R.drawable.shopping_cart_black_48dp);
} catch (Exception e) {
e.printStackTrace();
}
}
Where imageViewToByte functon is:
private byte[] imageViewToByte(CircleImageView image) {
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
Now you need to implement the SQLiteOpenHelper. You need to create a new class for this. The java file name I used for this was ProductDatabaseHelper.java.
public class ProductDatabaseHelper extends SQLiteOpenHelper {
private static int dbVersion = 1;
public ProductDatabaseHelper(Context context, String name, String storageDirectory) {
super(context, storageDirectory+name, null, dbVersion);
}
#Override
public void onCreate(SQLiteDatabase db) {
StringBuilder sql = new StringBuilder();
sql.append("CREATE TABLE IF NOT EXISTS PRODUCTLIST (");
sql.append(" IMAGE BLOB,");
db.execSQL(sql.toString());
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Now you need to implement your CRUD (Create new item, Read, Update and Delete).
public class ProductRepository {
SQLiteDatabase instance;
public ProductRepository(SQLiteDatabase instance) {
this.instance = instance;
}
public void addProduct(byte[] image){
ContentValues contentValues = new ContentValues();
contentValues.put("IMAGE",image);
instance.insertOrThrow("PRODUCTLIST",null, contentValues);
}
}
It is important to mention that the compression of the image was made in the onActivityResult() for both source image (camera and gallery).
with the command:
Bitmap bitmap = Bitmap.createScaledBitmap(capturedImage, width, height, true);
Besides that, here is a link where we can read a little bit about compression.
https://androidwave.com/capture-image-from-camera-gallery/
If you have a better way to compress images to save in SQLite Database, please post your code here!