This is the error I've run into and there seem to be no proper fixes to this code since my understanding of the back4app and android studio is very limited (com.parse.ParseException: java.lang.IllegalStateException: Unable to encode an unsaved ParseFile.).
Some of the solution I've tried was not doable and it seem to be that the ParseFile wasn't saved properly. I've tried the callback function and progress function but it doesn't seem to work. So at this point I'm out of idea on how to fix this
here is the code for my compose fragment
package com.example.rentahome.fragments;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageDecoder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.SpannableStringBuilder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import com.example.rentahome.ImageFilePath;
import com.example.rentahome.Post;
import com.example.rentahome.R;
import com.example.rentahome.Reviews;
import com.example.rentahome.databinding.FragmentComposeBinding;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseRelation;
import com.parse.ParseUser;
import com.parse.ProgressCallback;
import com.parse.SaveCallback;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import static android.app.Activity.RESULT_OK;
import static com.parse.Parse.getApplicationContext;
public class ComposeFragment extends Fragment {
public static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 43;
public static final int PICK_PHOTO_CODE = 21;
private File photoFile;
FragmentComposeBinding fragmentComposeBinding;
private String photoFileName = "photo.jpg";
public String realPath = new String();
public static final String TAG = "ComposeFragment";
public ComposeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_compose, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fragmentComposeBinding = FragmentComposeBinding.bind(view);
fragmentComposeBinding.btnPicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
uploadImage();
}
});
fragmentComposeBinding.btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String address = fragmentComposeBinding.etAddress.getText().toString();
String price = fragmentComposeBinding.etPrice.getText().toString();
String description = fragmentComposeBinding.etDescription.getText().toString();
if(address.isEmpty()){
Toast.makeText(getContext(), "Address cannot be empty", Toast.LENGTH_SHORT).show();
return;
}
if(price.isEmpty()){
Toast.makeText(getContext(), "Price cannot be empty", Toast.LENGTH_SHORT).show();
return;
}
if(description.isEmpty()){
Toast.makeText(getContext(), "Description cannot be empty", Toast.LENGTH_SHORT).show();
return;
}
if(realPath == null || fragmentComposeBinding.ivPostImage.getDrawable()==null){
Toast.makeText(getContext(),"There is no image", Toast.LENGTH_SHORT).show();
return;
}
ParseUser currentUser = ParseUser.getCurrentUser();
savePost(address, price, description, currentUser);
}
});
}
private void uploadImage() {
// create Intent to upload a picture and return control to the calling application
// Edit action for MediaStore
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Create a File reference for future access
//photoFile = getPhotoFileUri(photoFileName);
// wrap File object into a content provider
// required for API >= 24
// See https://guides.codepath.com/android/Sharing-Content-with-Intents#sharing-files-with-api-24-or-higher
//Uri fileProvider = FileProvider.getUriForFile(getContext(), "com.example.rentahome.fileprovider", photoFile);
//intent.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
// If you call startActivityForResult() using an intent that no app can handle, your app will crash.
// So as long as the result is not null, it's safe to use the intent.
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
// Start the image pick intent to pick photo from external folder
startActivityForResult(intent, PICK_PHOTO_CODE);
}
}
public Bitmap loadFromUri(Uri photoUri) {
Bitmap image = null;
try {
// check version of Anrdoid on device
if(Build.VERSION.SDK_INT > 27) {
// newer version
ImageDecoder.Source source = ImageDecoder.createSource(this.getContext().getContentResolver(), photoUri);
image = ImageDecoder.decodeBitmap(source);
} else {
//support older
image = MediaStore.Images.Media.getBitmap(this.getContext().getContentResolver(),photoUri);
}
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
private File getPhotoFileUri(String fileName) {
// Get safe storage directory for photos
// Use `getExternalFilesDir` on Context to access package-specific directories.
// This way, we don't need to request external read/write runtime permissions.
File mediaStorageDir = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), TAG);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
Log.d(TAG, "failed to create directory..");
}
// Return the file target for the photo based on filename
File file = new File(mediaStorageDir.getPath() + File.separator + fileName);
return file;
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_PHOTO_CODE && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
realPath = ImageFilePath.getPath(getContext(), data.getData());
// realPath = RealPathUtil.getRealPathFromURI_API19(this, data.getData());
Log.i(TAG, "onActivityResult: file path : " + realPath);
Log.i(TAG, "onActivityResult: file path : " + getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getPath() );
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContext().getContentResolver(), uri);
// Log.d(TAG, String.valueOf(bitmap));
fragmentComposeBinding.ivPostImage.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getContext(), "Something Went Wrong", Toast.LENGTH_SHORT).show();
}
// if ((data != null) && requestCode == PICK_PHOTO_CODE) {
// if (resultCode == RESULT_OK) {
// Uri photoUri = data.getData();
// // by this point we have the camera photo on disk
// //Bitmap selectedImage = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
// //Load the image located at photoUri into selectedImage
// Bitmap selectedImage = loadFromUri(photoUri);
// // RESIZE BITMAP, see section below
// // Load the taken image into a preview
// fragmentComposeBinding.ivPostImage.setImageBitmap(selectedImage);
//
// } else { // Result was a failure
// Toast.makeText(getContext(), "Image not found", Toast.LENGTH_SHORT).show();
// }
// }
}
private void savePost(String address, String price, String description, ParseUser currentUser) {
//Post post = new Post();
ParseObject post = ParseObject.create("Post");
File file = new File(realPath);
ParseFile photo = new ParseFile(file);
photo.saveInBackground();
// post.setImage(photo);
// int parsed_price = Integer.parseInt(price);
// post.setPrice(parsed_price);
// post.setDescription(description);
// post.setUser(currentUser);
// post.setAddress(address);
// //photo.saveInBackground();
ParseRelation<ParseObject> hi;
//parse String price to int..
post.put("image",photo);
post.put("description",description);
post.put("address",address);
post.put("user",currentUser);
post.put("price",price);
//post.put("Reviews",hi);
// Reviews gameScore = new Reviews();
//
// gameScore.setlikesCount(0);
// gameScore.setdislikesCount(0);
// gameScore.setAuthor(currentUser);
// gameScore.setRating((float) (5.0));
// gameScore.setDescription("hi");
////
//// gameScore.put("Description","Hi ");
//// gameScore.put("author",currentUser);
//// gameScore.put("rating",(float)(5.0));
//// gameScore.put("likesCount",0);
//// gameScore.put("dislikesCount",0);
//
// ParseRelation<Reviews> temp = new ParseRelation<Reviews>();
// temp.add(gameScore);
post.saveInBackground(new SaveCallback() {
#Override
public void done(com.parse.ParseException e) {
if(e!=null){
Log.e(TAG,"Issue with saving posts..", e);
Toast.makeText(getContext(), "Error while saving", Toast.LENGTH_SHORT).show();
return;
}
Log.i(TAG,"Saved successfully!");
fragmentComposeBinding.etDescription.setText("");
fragmentComposeBinding.ivPostImage.setImageResource(0);
}
});
}
}
Here is my post class, and one of the special thing about it was the relation I have inside the post class. There is a reviews relation which contain objects reviews
package com.example.rentahome;
import com.parse.ParseClassName;
import com.parse.ParseFile;
import com.parse.ParseObject;
import com.parse.ParseRelation;
import com.parse.ParseUser;
import java.util.ArrayList;
#ParseClassName("Post")
public class Post extends ParseObject {
public static final String KEY_DESCRIPTION = "description";
public static final String KEY_IMAGE = "image"; //image should be 'uploaded'
public static final String KEY_USER = "user";
public static final String KEY_CREATED_KEY = "createdAt"; //have to figure out how to implement
public static final String KEY_address = "address";
public static final String KEY_price = "price";
public static final String KEY_reviews = "Reviews";
public static final String KEY_objectID = "objectID";
public String getDescription(){
return getString(KEY_DESCRIPTION);
}
public void setDescription(String description){
put(KEY_DESCRIPTION, description);
}
public ParseFile getImage(){
return getParseFile(KEY_IMAGE);
}
public void setImage(ParseFile parseFile){
put(KEY_IMAGE, parseFile);
}
public ParseUser getUser(){
return getParseUser(KEY_USER);
}
public void setUser(ParseUser user){put(KEY_USER, user);}
public String getAddress() {return getString(KEY_address);}
public void setAddress(String address){ put(KEY_address, address);}
public int getPrice(){return getInt(KEY_price);}
public void setPrice(int price){put(KEY_price,price);}
public String getobjectID(){return getString(KEY_objectID);}
public ParseRelation<ParseObject> getrelation() {return getRelation(KEY_reviews);}
public void setrelation(ParseRelation<ParseObject> relation){put(KEY_reviews, relation);}
//public ParseRelation<ParseObject> getReviews(){return getRelation(KEY_reviews);}
//public void setReviews(ParseRelation<ParseObject> reviews){put(KEY_reviews, reviews);}
//public Date getCreatedAt() { return getDate(KEY_CREATED_KEY);}
My review class
package com.example.rentahome;
import com.parse.ParseClassName;
import com.parse.ParseObject;
import com.parse.ParseUser;
#ParseClassName("Reviews")
public class Reviews extends ParseObject {
public static final String KEY_author = "author";
public static final String KEY_description = "Description";
public static final String KEY_likesCount = "likesCount";
public static final String KEY_dislikesCount = "dislikesCount";
public static final String KEY_rating = "rating";
public String getDescription(){return getString(KEY_description);}
public void setDescription(String description){put(KEY_description, description);}
public ParseUser getAuthor(){return getParseUser(KEY_author); }
public void setAuthor(ParseUser author){put(KEY_author,author);}
public float getRating(){return (float)getDouble(KEY_rating);}
public void setRating(float rating) {put(KEY_rating, rating);}
public int getlikesCount() {return getInt(KEY_likesCount);}
public void setlikesCount(int likesCount){put(KEY_likesCount, likesCount);}
public int getdislikesCount() {return getInt(KEY_dislikesCount);}
public void setdislikesCount(int dislikesCount){put(KEY_dislikesCount, dislikesCount);}
}
Here is the error message
E/ComposeFragment: Issue with saving posts..
com.parse.ParseException: java.lang.IllegalStateException: Unable to encode an unsaved ParseFile.
at com.parse.ParseTaskUtils$2$1.run(ParseTaskUtils.java:119)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.IllegalStateException: Unable to encode an unsaved ParseFile.
at com.parse.ParseFile.encode(ParseFile.java:653)
at com.parse.ParseEncoder.encode(ParseEncoder.java:77)
at com.parse.ParseSetOperation.encode(ParseSetOperation.java:31)
at com.parse.ParseEncoder.encode(ParseEncoder.java:126)
at com.parse.ParseObjectCoder.encode(ParseObjectCoder.java:57)
at com.parse.NetworkObjectController.saveAsync(NetworkObjectController.java:60)
at com.parse.ParseObject$32.then(ParseObject.java:2282)
at com.parse.ParseObject$32.then(ParseObject.java:2277)
at com.parse.boltsinternal.Task$15.run(Task.java:907)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.continueWithTask(Task.java:713)
at com.parse.boltsinternal.Task.continueWithTask(Task.java:724)
at com.parse.boltsinternal.Task$13.then(Task.java:816)
at com.parse.boltsinternal.Task$13.then(Task.java:804)
at com.parse.boltsinternal.Task$15.run(Task.java:907)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.access$100(Task.java:28)
at com.parse.boltsinternal.Task$11.then(Task.java:706)
at com.parse.boltsinternal.Task$11.then(Task.java:703)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetResult(Task.java:984)
at com.parse.boltsinternal.TaskCompletionSource.trySetResult(TaskCompletionSource.java:45)
at com.parse.boltsinternal.TaskCompletionSource.setResult(TaskCompletionSource.java:68)
at com.parse.boltsinternal.Task$15$1.then(Task.java:924)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.continueWith(Task.java:659)
at com.parse.boltsinternal.Task.continueWith(Task.java:670)
at com.parse.boltsinternal.Task$15.run(Task.java:911)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.access$100(Task.java:28)
at com.parse.boltsinternal.Task$11.then(Task.java:706)
at com.parse.boltsinternal.Task$11.then(Task.java:703)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetResult(Task.java:984)
at com.parse.boltsinternal.TaskCompletionSource.trySetResult(TaskCompletionSource.java:45)
at com.parse.boltsinternal.TaskCompletionSource.setResult(TaskCompletionSource.java:68)
at com.parse.boltsinternal.Task$8.then(Task.java:562)
at com.parse.boltsinternal.Task$8.then(Task.java:536)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
E/ComposeFragment: at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetResult(Task.java:984)
at com.parse.boltsinternal.TaskCompletionSource.trySetResult(TaskCompletionSource.java:45)
at com.parse.boltsinternal.TaskCompletionSource.setResult(TaskCompletionSource.java:68)
at com.parse.boltsinternal.Task$14.run(Task.java:867)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$8.then(Task.java:552)
at com.parse.boltsinternal.Task$8.then(Task.java:536)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$15$1.then(Task.java:922)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.access$000(Task.java:28)
at com.parse.boltsinternal.Task$10.then(Task.java:652)
at com.parse.boltsinternal.Task$10.then(Task.java:649)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$15$1.then(Task.java:922)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.continueWith(Task.java:659)
at com.parse.boltsinternal.Task.continueWith(Task.java:670)
at com.parse.boltsinternal.Task$15.run(Task.java:911)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeAfterTask(Task.java:898)
at com.parse.boltsinternal.Task.access$100(Task.java:28)
at com.parse.boltsinternal.Task$11.then(Task.java:706)
at com.parse.boltsinternal.Task$11.then(Task.java:703)
at com.parse.boltsinternal.Task.runContinuations(Task.java:946)
at com.parse.boltsinternal.Task.trySetError(Task.java:1001)
at com.parse.boltsinternal.TaskCompletionSource.trySetError(TaskCompletionSource.java:52)
at com.parse.boltsinternal.TaskCompletionSource.setError(TaskCompletionSource.java:77)
at com.parse.boltsinternal.Task$15$1.then(Task.java:922)
at com.parse.boltsinternal.Task$15$1.then(Task.java:911)
at com.parse.boltsinternal.Task$14.run(Task.java:866)
at com.parse.boltsinternal.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:113)
at com.parse.boltsinternal.Task.completeImmediately(Task.java:857)
at com.parse.boltsinternal.Task.continueWith(Task.java:659)
at com.parse.boltsinternal.Task.continueWith(Task.java:670)
at com.parse.boltsinternal.Task$15.run(Task.java:911)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Your problem happens because you are not awaiting photo.saveInBackground to complete. Your code should look like this:
ParseObject post = ParseObject.create("Post");
File file = new File(realPath);
ParseFile photo = new ParseFile(file);
photo.saveInBackground(new SaveCallback() {
#Override
public void done(com.parse.ParseException e) {
// Handle success or failure here ...
post.put("image",photo);
post.put("description",description);
post.put("address",address);
post.put("user",currentUser);
post.put("price",price);
post.saveInBackground(new SaveCallback() {
#Override
public void done(com.parse.ParseException e) {
// Handle success or failure here ...
}
});
}
});
Related
I'm creating an app using a MLkit and finally I made it. But it's not working and keep send me a errors I can't understand why error keep occurs.. here is my code and error pls help me
I just copied from MLKit example quick start sample for only using a pose
detector and it says " Invalid model name" .. I don't know why it does saying can you guys help me??
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.pose;
import androidx.camera.core.ImageAnalysis;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.util.Size;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ToggleButton;
import androidx.camera.core.CameraInfoUnavailableException;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback;
import androidx.core.content.ContextCompat;
import com.google.android.gms.common.annotation.KeepName;
import com.google.mlkit.common.MlKitException;
import com.google.mlkit.common.model.LocalModel;
import com.example.pose.CameraXViewModel;
import com.example.pose.GraphicOverlay;
import com.google.mlkit.vision.demo.R;
import com.example.pose.VisionImageProcessor;
import com.example.pose.posedetector.PoseDetectorProcessor;
import com.example.pose.preference.PreferenceUtils;
import com.google.mlkit.vision.pose.PoseDetectorOptions;
import java.util.ArrayList;
import java.util.List;
/** Live preview demo app for ML Kit APIs using CameraX. */
#KeepName
#RequiresApi(VERSION_CODES.LOLLIPOP)
public final class CameraXLivePreviewActivity extends AppCompatActivity
implements OnRequestPermissionsResultCallback,
OnItemSelectedListener,
CompoundButton.OnCheckedChangeListener {
private static final String TAG = "CameraXLivePreview";
private static final int PERMISSION_REQUESTS = 1;
private static final String OBJECT_DETECTION = "Object Detection";
private static final String POSE_DETECTION = "Pose Detection";
private static final String STATE_SELECTED_MODEL = "selected_model";
private static final String STATE_LENS_FACING = "lens_facing";
private PreviewView previewView;
private GraphicOverlay graphicOverlay;
#Nullable private ProcessCameraProvider cameraProvider;
#Nullable private Preview previewUseCase;
#Nullable private ImageAnalysis analysisUseCase;
#Nullable private VisionImageProcessor imageProcessor;
private boolean needUpdateGraphicOverlayImageSourceInfo;
private String selectedModel = OBJECT_DETECTION;
private int lensFacing = CameraSelector.LENS_FACING_BACK;
private CameraSelector cameraSelector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
Toast.makeText(
getApplicationContext(),
"CameraX is only supported on SDK version >=21. Current SDK version is "
+ VERSION.SDK_INT,
Toast.LENGTH_LONG)
.show();
return;
}
if (savedInstanceState != null) {
selectedModel = savedInstanceState.getString(STATE_SELECTED_MODEL, OBJECT_DETECTION);
lensFacing = savedInstanceState.getInt(STATE_LENS_FACING, CameraSelector.LENS_FACING_BACK);
}
cameraSelector = new CameraSelector.Builder().requireLensFacing(lensFacing).build();
setContentView(R.layout.activity_vision_camerax_live_preview);
previewView = findViewById(R.id.preview_view);
if (previewView == null) {
Log.d(TAG, "previewView is null");
}
graphicOverlay = findViewById(R.id.graphic_overlay);
if (graphicOverlay == null) {
Log.d(TAG, "graphicOverlay is null");
}
ToggleButton facingSwitch = findViewById(R.id.facing_switch);
facingSwitch.setOnCheckedChangeListener(this);
new ViewModelProvider(this, AndroidViewModelFactory.getInstance(getApplication()))
.get(CameraXViewModel.class)
.getProcessCameraProvider()
.observe(
this,
provider -> {
cameraProvider = provider;
if (allPermissionsGranted()) {
bindAllCameraUseCases();
}
});
if (!allPermissionsGranted()) {
getRuntimePermissions();
}
}
#Override
protected void onSaveInstanceState(#NonNull Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putString(STATE_SELECTED_MODEL, selectedModel);
bundle.putInt(STATE_LENS_FACING, lensFacing);
}
#Override
public synchronized void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// An item was selected. You can retrieve the selected item using
// parent.getItemAtPosition(pos)
selectedModel = parent.getItemAtPosition(pos).toString();
Log.d(TAG, "Selected model: " + selectedModel);
bindAnalysisUseCase();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d(TAG, "Set facing");
if (cameraProvider == null) {
return;
}
int newLensFacing =
lensFacing == CameraSelector.LENS_FACING_FRONT
? CameraSelector.LENS_FACING_BACK
: CameraSelector.LENS_FACING_FRONT;
CameraSelector newCameraSelector =
new CameraSelector.Builder().requireLensFacing(newLensFacing).build();
try {
if (cameraProvider.hasCamera(newCameraSelector)) {
lensFacing = newLensFacing;
cameraSelector = newCameraSelector;
bindAllCameraUseCases();
return;
}
} catch (CameraInfoUnavailableException e) {
// Falls through
}
Toast.makeText(
getApplicationContext(),
"This device does not have lens with facing: " + newLensFacing,
Toast.LENGTH_SHORT)
.show();
}
#Override
public void onResume() {
super.onResume();
bindAllCameraUseCases();
}
#Override
protected void onPause() {
super.onPause();
if (imageProcessor != null) {
imageProcessor.stop();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (imageProcessor != null) {
imageProcessor.stop();
}
}
private void bindAllCameraUseCases() {
if (cameraProvider != null) {
// As required by CameraX API, unbinds all use cases before trying to re-bind any of them.
cameraProvider.unbindAll();
bindPreviewUseCase();
bindAnalysisUseCase();
}
}
private void bindPreviewUseCase() {
if (!PreferenceUtils.isCameraLiveViewportEnabled(this)) {
return;
}
if (cameraProvider == null) {
return;
}
if (previewUseCase != null) {
cameraProvider.unbind(previewUseCase);
}
previewUseCase = new Preview.Builder().build();
previewUseCase.setSurfaceProvider(previewView.createSurfaceProvider());
cameraProvider.bindToLifecycle(/* lifecycleOwner= */ this, cameraSelector, previewUseCase);
}
private void bindAnalysisUseCase() {
if (cameraProvider == null) {
return;
}
if (analysisUseCase != null) {
cameraProvider.unbind(analysisUseCase);
}
if (imageProcessor != null) {
imageProcessor.stop();
}
try {
switch (selectedModel) {
case POSE_DETECTION:
PoseDetectorOptions poseDetectorOptions =
PreferenceUtils.getPoseDetectorOptionsForLivePreview(this);
boolean shouldShowInFrameLikelihood =
PreferenceUtils.shouldShowPoseDetectionInFrameLikelihoodLivePreview(this);
imageProcessor =
new PoseDetectorProcessor(this, poseDetectorOptions, shouldShowInFrameLikelihood);
break;
default:
throw new IllegalStateException("Invalid model name");
}
} catch (Exception e) {
Log.e(TAG, "Can not create image processor: " + selectedModel, e);
Toast.makeText(
getApplicationContext(),
"Can not create image processor: " + e.getLocalizedMessage(),
Toast.LENGTH_LONG)
.show();
return;
}
ImageAnalysis.Builder builder = new ImageAnalysis.Builder();
Size targetAnalysisSize = PreferenceUtils.getCameraXTargetAnalysisSize(this);
if (targetAnalysisSize != null) {
builder.setTargetResolution(targetAnalysisSize);
}
analysisUseCase = builder.build();
needUpdateGraphicOverlayImageSourceInfo = true;
analysisUseCase.setAnalyzer(
// imageProcessor.processImageProxy will use another thread to run the detection underneath,
// thus we can just runs the analyzer itself on main thread.
ContextCompat.getMainExecutor(this),
imageProxy -> {
if (needUpdateGraphicOverlayImageSourceInfo) {
boolean isImageFlipped = lensFacing == CameraSelector.LENS_FACING_FRONT;
int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();
if (rotationDegrees == 0 || rotationDegrees == 180) {
graphicOverlay.setImageSourceInfo(
imageProxy.getWidth(), imageProxy.getHeight(), isImageFlipped);
} else {
graphicOverlay.setImageSourceInfo(
imageProxy.getHeight(), imageProxy.getWidth(), isImageFlipped);
}
needUpdateGraphicOverlayImageSourceInfo = false;
}
try {
imageProcessor.processImageProxy(imageProxy, graphicOverlay);
} catch (MlKitException e) {
Log.e(TAG, "Failed to process image. Error: " + e.getLocalizedMessage());
Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_SHORT)
.show();
}
});
cameraProvider.bindToLifecycle(/* lifecycleOwner= */ this, cameraSelector, analysisUseCase);
}
private String[] getRequiredPermissions() {
try {
PackageInfo info =
this.getPackageManager()
.getPackageInfo(this.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] ps = info.requestedPermissions;
if (ps != null && ps.length > 0) {
return ps;
} else {
return new String[0];
}
} catch (Exception e) {
return new String[0];
}
}
private boolean allPermissionsGranted() {
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
return false;
}
}
return true;
}
private void getRuntimePermissions() {
List<String> allNeededPermissions = new ArrayList<>();
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
allNeededPermissions.add(permission);
}
}
if (!allNeededPermissions.isEmpty()) {
ActivityCompat.requestPermissions(
this, allNeededPermissions.toArray(new String[0]), PERMISSION_REQUESTS);
}
}
#Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
Log.i(TAG, "Permission granted!");
if (allPermissionsGranted()) {
bindAllCameraUseCases();
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private static boolean isPermissionGranted(Context context, String permission) {
if (ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission granted: " + permission);
return true;
}
Log.i(TAG, "Permission NOT granted: " + permission);
return false;
}
}
E/CameraXLivePreview: Can not create image processor: Object Detection
java.lang.IllegalStateException: Invalid model name
at com.example.pose.CameraXLivePreviewActivity.bindAnalysisUseCase(CameraXLivePreviewActivity.java:271)
at com.example.pose.CameraXLivePreviewActivity.bindAllCameraUseCases(CameraXLivePreviewActivity.java:229)
at com.example.pose.CameraXLivePreviewActivity.onCheckedChanged(CameraXLivePreviewActivity.java:187)
at android.widget.CompoundButton.setChecked(CompoundButton.java:218)
at android.widget.ToggleButton.setChecked(ToggleButton.java:81)
at android.widget.CompoundButton.toggle(CompoundButton.java:137)
at android.widget.CompoundButton.performClick(CompoundButton.java:142)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Please change this line to let the feature selector to select Pose detection
"private String selectedModel = OBJECT_DETECTION;"
to
"private String selectedModel = POSE_DETECTION;"
I'm doing a Simple Media Recorder/Player App and the recording part is successfully done. But now I'm having problems with the media player's part. Let me tell you the issues:
When I try to play a media file with the Media Player it says a preparing error like this:
java.io.IOException: Prepare failed.: status=0x1
How can I solve this problem?
My Three Classes:
-RecordFragment.java:
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.Fragment;
import android.os.Environment;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Chronometer;
import android.widget.TextView;
import android.widget.Toast;
import com.airbnb.lottie.LottieAnimationView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.venomapps.voicerecorder.R;
import com.venomapps.voicerecorder.Utils.Constants;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class RecordFragment extends Fragment {
private TextView textViewInformation;
private FloatingActionButton floatingActionButtonStartRecording;
private FloatingActionButton floatingActionButtonFinishRecording;
private FloatingActionButton floatingActionButtonCancelRecording;
private int recordingStatus = 0;
private String fileName = "";
private Context context;
String[] permissions = {Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE};
private MediaRecorder mediaRecorder;
private String outPutFilePath;
private Chronometer chronometerRecord;
private boolean running;
private long pauseOffset;
private LottieAnimationView lottieAnimationViewVoice;
public RecordFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_record, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
context = getActivity();
bindUI(view);
setListeners();
}
private void bindUI(View view) {
textViewInformation = view.findViewById(R.id.textViewInformation);
floatingActionButtonStartRecording = view.findViewById(R.id.floatingActionButtonStartRecording);
floatingActionButtonFinishRecording = view.findViewById(R.id.floatingActionButtonFinishRecording);
floatingActionButtonCancelRecording = view.findViewById(R.id.floatingActionButtonCancelRecording);
chronometerRecord = view.findViewById(R.id.chronometerRecord);
lottieAnimationViewVoice = view.findViewById(R.id.lottieAnimationViewVoice);
}
private void setListeners() {
floatingActionButtonStartRecording.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
switch (recordingStatus) {
case 0:
startRecording();
break;
case 1:
if (Build.VERSION.SDK_INT >= 24) {
pauseRecording();
} else {
finishRecording();
}
break;
case 2:
resumeRecording();
case 3:
break;
}
} else {
askPermissions();
}
}
});
floatingActionButtonFinishRecording.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View view) {
if (recordingStatus == 1 || recordingStatus == 2) {
finishRecording();
} else {
Toast.makeText(getActivity(), getString(R.string.not_recording), Toast.LENGTH_SHORT).show();
}
}
});
floatingActionButtonCancelRecording.setOnClickListener(new View.OnClickListener() {
#SuppressLint("SetTextI18n")
#Override
public void onClick(View view) {
if (recordingStatus == 1 || recordingStatus == 2) {
cancelRecording();
} else {
Toast.makeText(getActivity(), getString(R.string.not_recording), Toast.LENGTH_SHORT).show();
}
}
});
chronometerRecord.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
long time = SystemClock.elapsedRealtime() - chronometer.getBase();
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String t = (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s);
chronometer.setText(t);
}
});
}
#SuppressLint("SetTextI18n")
private void startRecording() {
String basePath = Environment.getExternalStorageDirectory().toString();
String date = getCurrentDateFormatted();
String myDirectory = "Voice Recorder";
fileName = getString(R.string.recording_file) + date;
fileName = fileName.replace(" ", "");
fileName = fileName.replace("|", "");
fileName = fileName + ".mp3";
outPutFilePath = basePath + File.separator + myDirectory + File.separator + fileName;
String filePath = basePath + File.separator + myDirectory;
File newFolder = new File(filePath);
if (!newFolder.exists()) {
boolean createFolder = newFolder.mkdirs();
if (createFolder) {
Log.d("VOICE_RECORDER", "Created folder successfully!");
}
}
recordingStatus = 1;
mediaRecorder = new MediaRecorder();
if (Build.VERSION.SDK_INT >= 24) {
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_pause_orange, null));
} else {
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_stop_red, null));
}
textViewInformation.setText(getString(R.string.recording));
lottieAnimationViewVoice.playAnimation();
lottieAnimationViewVoice.setVisibility(View.VISIBLE);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setOutputFile(outPutFilePath);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setAudioEncodingBitRate(16 * 44100);
mediaRecorder.setAudioSamplingRate(44100);
try {
mediaRecorder.prepare();
mediaRecorder.start();
if (!running) {
chronometerRecord.setVisibility(View.VISIBLE);
chronometerRecord.setBase(SystemClock.elapsedRealtime());
chronometerRecord.start();
running = true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void pauseRecording() {
if (Build.VERSION.SDK_INT >= 24) {
mediaRecorder.pause();
}
if (running) {
chronometerRecord.stop();
pauseOffset = SystemClock.elapsedRealtime() - chronometerRecord.getBase();
running = false;
}
lottieAnimationViewVoice.cancelAnimation();
lottieAnimationViewVoice.setFrame(0);
lottieAnimationViewVoice.setVisibility(View.INVISIBLE);
recordingStatus = 2;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_play_green, null));
textViewInformation.setText(getString(R.string.tap_to_resume));
Toast.makeText(context, getString(R.string.paused), Toast.LENGTH_SHORT).show();
}
private void resumeRecording() {
if (Build.VERSION.SDK_INT >= 24) {
mediaRecorder.resume();
}
chronometerRecord.setBase(SystemClock.elapsedRealtime() - pauseOffset);
chronometerRecord.start();
lottieAnimationViewVoice.playAnimation();
lottieAnimationViewVoice.setVisibility(View.VISIBLE);
recordingStatus = 1;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_pause_orange, null));
textViewInformation.setText(getString(R.string.recording));
Toast.makeText(context, getString(R.string.resume), Toast.LENGTH_SHORT).show();
}
#SuppressLint("SetTextI18n")
private void finishRecording() {
chronometerRecord.setVisibility(View.INVISIBLE);
chronometerRecord.stop();
chronometerRecord.setBase(SystemClock.elapsedRealtime());
pauseOffset = 0;
mediaRecorder.stop();
mediaRecorder = null;
recordingStatus = 3;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_app, null));
Toast.makeText(context, getString(R.string.saved) + " " + fileName, Toast.LENGTH_LONG).show();
textViewInformation.setText(getString(R.string.tap_to_record));
lottieAnimationViewVoice.cancelAnimation();
lottieAnimationViewVoice.setFrame(0);
lottieAnimationViewVoice.setVisibility(View.INVISIBLE);
recordingStatus = 0;
}
#SuppressLint("SetTextI18n")
private void cancelRecording() {
chronometerRecord.setVisibility(View.INVISIBLE);
chronometerRecord.stop();
chronometerRecord.setBase(SystemClock.elapsedRealtime());
pauseOffset = 0;
try {
mediaRecorder.stop();
} catch (RuntimeException e) {
e.printStackTrace();
mediaRecorder = null;
mediaRecorder = new MediaRecorder();
} finally {
if (mediaRecorder != null) {
mediaRecorder = null;
}
}
File file = new File(outPutFilePath);
if (file.exists()) {
boolean deleted = file.delete();
if (deleted) {
Log.d("Voice Recorder", "Deleted file successfully!");
}
}
recordingStatus = 3;
floatingActionButtonStartRecording.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_app, null));
Toast.makeText(context, getString(R.string.cancelled) + " " + fileName, Toast.LENGTH_LONG).show();
textViewInformation.setText(getString(R.string.tap_to_record));
lottieAnimationViewVoice.cancelAnimation();
lottieAnimationViewVoice.setFrame(0);
lottieAnimationViewVoice.setVisibility(View.INVISIBLE);
recordingStatus = 0;
}
private String getCurrentDateFormatted() {
return new SimpleDateFormat("dd-MM-yy|hh:mm:ss", Locale.getDefault()).format(new Date());
}
private void askPermissions() {
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
assert getParentFragment() != null;
requestPermissions(permissions, Constants.RECORD_AUDIO_AND_WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull final String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, getString(R.string.permission_granted), Toast.LENGTH_SHORT).show();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(getString(R.string.no_read_permission))
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permissions, Constants.RECORD_AUDIO_AND_WRITE_EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
}).setNegativeButton(getString(R.string.go_to_settings), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", "com.venomapps.voicerecorder", null);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setData(uri);
context.startActivity(intent);
requireActivity().finish();
}
});
builder.create();
builder.show();
}
}
}
PlaylistFragment.java:
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.venomapps.voicerecorder.Adapters.PlaylistAdapter;
import com.venomapps.voicerecorder.R;
import java.io.File;
import java.io.IOException;
public class PlaylistFragment extends Fragment implements PlaylistAdapter.onItemListClick {
private BottomSheetBehavior bottomSheetBehavior;
private RecyclerView recyclerViewPlaylist;
private File[] files;
private PlaylistAdapter playlistAdapter;
private MediaPlayer mediaPlayer = null;
private boolean isPlaying = false;
private File fileToPlay;
public PlaylistFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFiles();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_playlist_item_list, container, false);
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(linearLayoutManager);
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
bindUI(view);
setListeners();
setAdapter();
}
private void bindUI(View view) {
ConstraintLayout constraintLayoutMediaPlayer = view.findViewById(R.id.constraintLayoutMediaPlayer);
bottomSheetBehavior = BottomSheetBehavior.from(constraintLayoutMediaPlayer);
recyclerViewPlaylist = view.findViewById(R.id.recyclerViewPlaylist);
}
private void setListeners() {
bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
}
private void getFiles() {
String path = Environment.getExternalStorageDirectory().toString() + File.separator + "Voice Recorder";
File directory = new File(path);
files = directory.listFiles();
}
private void setAdapter() {
playlistAdapter = new PlaylistAdapter(files, this);
recyclerViewPlaylist.setHasFixedSize(true);
recyclerViewPlaylist.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerViewPlaylist.setAdapter(playlistAdapter);
}
#Override
public void onClickListener(File file, int position) throws IOException {
if(isPlaying){
stopAudio();
playAudio(fileToPlay);
}else{
fileToPlay = file;
playAudio(fileToPlay);
}
}
private void playAudio(File fileToPlay) {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(fileToPlay.getAbsolutePath());
mediaPlayer.prepare();
mediaPlayer.start();
}catch (Exception e){
e.printStackTrace();
}
isPlaying = true;
}
private void stopAudio(){
isPlaying = false;
}
}
-PlaylistAdapter.java:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.venomapps.voicerecorder.Utils.TimeAgo;
import com.venomapps.voicerecorder.R;
import java.io.File;
import java.io.IOException;
public class PlaylistAdapter extends RecyclerView.Adapter<PlaylistAdapter.PlaylistViewHolder> {
private static File[] files;
private TimeAgo timeAgo;
private Context context;
private static onItemListClick onItemListClick;
public PlaylistAdapter(File[] files, onItemListClick onItemListClick) {
PlaylistAdapter.files = files;
PlaylistAdapter.onItemListClick = onItemListClick;
}
#NonNull
#Override
public PlaylistViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_playlist_item, parent, false);
context = parent.getContext();
timeAgo = new TimeAgo();
return new PlaylistViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull PlaylistViewHolder holder, int position) {
holder.textViewPlaylistFileName.setText(files[position].getName());
holder.textViewPlaylistStats.setText(timeAgo.getTimeAgo(files[position].lastModified(), context));
if(position == getItemCount() - 1){
holder.playlistSeparator.setVisibility(View.INVISIBLE);
}
}
#Override
public int getItemCount() {
return files.length;
}
public static class PlaylistViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView textViewPlaylistFileName;
private final TextView textViewPlaylistStats;
private final View playlistSeparator;
private final FloatingActionButton floatingActionButtonPlaylistPlay;
private final ImageButton imageButtonPlaylistItem;
public PlaylistViewHolder(#NonNull View itemView) {
super(itemView);
textViewPlaylistFileName = itemView.findViewById(R.id.textViewPlaylistFileName);
textViewPlaylistStats = itemView.findViewById(R.id.textViewPlaylistStats);
playlistSeparator = itemView.findViewById(R.id.playlistSeparator);
floatingActionButtonPlaylistPlay = itemView.findViewById(R.id.floatingActionButtonPlaylistPlay);
imageButtonPlaylistItem = itemView.findViewById(R.id.imageButtonPlaylistItem);
floatingActionButtonPlaylistPlay.setOnClickListener(this);
}
#Override
public void onClick(View v) {
try {
onItemListClick.onClickListener(files[getAdapterPosition()], getAdapterPosition());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public interface onItemListClick{
void onClickListener(File file, int position) throws IOException;
}
}
Firstly, I suggest you to post full error log, and only the code which create the problem (and not your entire project ...)
There is 3 possibilities which can create your problem :
File problem (path or file not exist).
Wrong format (or not supported one).
Not permission. Do file.setReadable(true); to fix this
More informations here : https://stackoverflow.com/a/11977292/10952503
What i am trying to do is getting images from gallery and camera and placing it in an recyclerview.
Now main parts comes after image is now placedd in the recyclerview ,
but can anyone just tell me how can i get back these images shown in the recyclerview back to the mainActivity only when i click my upload button.
Thank you in advance.
My Main Activity.
package www.welkinfort.com.pphc;
import android.app.DatePickerDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import butterknife.ButterKnife;
public class XenImageUploading extends AppCompatActivity implements AdapterView.OnItemSelectedListener, View.OnClickListener {
ArrayAdapter<String> des_dataAdapter;
ArrayList<String> discription_list = new ArrayList<>();
//#BindView(R.id.selct_prject_spinner)
Spinner select_pro_spn;
TextView datetextTextView;
Calendar myCalendar;
static Bitmap rotatedBitmap;
static Bitmap finalrotatedBitmap;
DatePickerDialog.OnDateSetListener date;
static final int REQUEST_TAKE_PHOTO = 1;
private int SELECT_FILE = 2;
private static String bitmap_overdraw_str;
private static ImageButton cameraclick;
private static ImageButton galleryclick;
private static ImageButton videoclick;
private static String mCurrentPhotoPath;
private static RecyclerView recyclerView;
ArrayList<Data_Model> arrayList;
ImageView image_view;
MyAdapter m;
Bitmap finalbitmap;
static String clickpath;
int i = 0;
String path ;
private static final String TAG = "XenImageUploading";
static File photoFile_1 = null;
private String userChoosenTask;
private Uri fileUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xen_image_upload);
ButterKnife.bind(this);
setTitle("XEN IMAGE UPLOAD");
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
cameraclick = (ImageButton) findViewById(R.id.camera_btn);
galleryclick = (ImageButton) findViewById(R.id.gallery_btn);
image_view = (ImageView) findViewById(R.id.image_view);
arrayList = new ArrayList<>();
Log.d("oncreate", "set adapter");
bitmap_overdraw_str = "Lat:" + "aaaaaaaa" + "\nLong:" + "aaaaaaaa" + "\nDate:" + "aaaaaaaa";
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
///////////////////////////////////////////////////////////////////
//select_pro_spn = (Spinner) findViewById(R.id.selct_prject_spinner);
//datetextTextView = (TextView) findViewById(R.id.selctdate__txtv);
discription_list.add("Traffic light broken/not working");
discription_list.add("Traffic light pole hit by vehicle");
discription_list.add("No electricity connection");
discription_list.add("Traffic light not visible/partially visible");
// select_pro_spn.setOnItemSelectedListener(this);
// Creating adapter for spinner
des_dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, discription_list);
// Drop down layout style - list view with radio button
des_dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
// select_pro_spn.setAdapter(des_dataAdapter);
myCalendar = Calendar.getInstance();
date = new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub
myCalendar.set(Calendar.YEAR, year);
myCalendar.set(Calendar.MONTH, monthOfYear);
myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateLabel();
}
};
// datetextTextView.setOnClickListener(new View.OnClickListener() {
//
// #Override
// public void onClick(View v) {
// // TODO Auto-generated method stub
// new DatePickerDialog(XenImageUploading.this, date, myCalendar
// .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
// myCalendar.get(Calendar.DAY_OF_MONTH)).show();
// }
// });
cameraclick.setOnClickListener(this);
galleryclick.setOnClickListener(this);
recyclerView.setOnClickListener(this);
}
private void updateLabel() {
String myFormat = "MM-dd-yyyy"; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
datetextTextView.setText(sdf.format(myCalendar.getTime()));
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
// case R.id.selct_prject_spinner:
// String selected_intersection = parent.getSelectedItem().toString();
// Log.e("Selected item ", selected_intersection);
// //parent.notifyAll();
// break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.camera_btn:
selectImage();
break;
case R.id.recycler_view:
getImageall();
break;
case R.id.gallery_btn:
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
i.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(i, SELECT_FILE);
break;
}
}
private void getImageall() {
}
private void selectImage() {
takepicture();
}
public void takepicture() {
Log.d(TAG, "takepicture");
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
try {
photoFile_1 = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile_1 != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile_1));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK && null != data) {
// Save Image To Gallery
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
////////////////setting image to adapter on capturing///////////////////////////
clickpath = mCurrentPhotoPath;
Bitmap bitmap = BitmapUtility.decodeSampledBitmapFromResource(clickpath, 560, 300);
setCameraDisplayOrientation(bitmap);
try {
FileOutputStream fos = new FileOutputStream(photoFile_1);
finalrotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
Data_Model data_model = new Data_Model();
data_model.setImage(finalrotatedBitmap);
image_view.setImageBitmap(finalrotatedBitmap);
arrayList.add(data_model);
m = new MyAdapter(this, arrayList);
recyclerView.setAdapter(m);
m.notifyDataSetChanged();
}
if (requestCode == SELECT_FILE && resultCode == RESULT_OK && null != data) {
InputStream stream = null;
Uri uri = data.getData();
//for (int i =0 ; i<numberOfImages ;i++){
getImagePath(uri);
Data_Model data_model = new Data_Model();
data_model.setImage(finalbitmap);
image_view.setImageBitmap(finalbitmap);
arrayList.add(data_model);
m = new MyAdapter(this, arrayList);
recyclerView.setAdapter(m);
m.notifyDataSetChanged();
// }
}
}
public String getImagePath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
finalbitmap = BitmapUtility.decodeSampledBitmapFromResource(path, 560, 300);
//targetImage = (ImageView)findViewById(R.id.imageView1);
image_view.setImageBitmap(finalbitmap);
return path;
}
public static void setCameraDisplayOrientation(Bitmap fileresult) {
Log.e(TAG, "setCameraDisplayOrientation");
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(clickpath, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(clickpath, opts);
ExifInterface exif = null;
try {
exif = new ExifInterface(clickpath);
} catch (IOException e) {
e.printStackTrace();
}
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
finalrotatedBitmap = AddTextonBitmap.textAsBitmap(rotatedBitmap, bitmap_overdraw_str);
}
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 image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
}
Adapter class
package www.welkinfort.com.pphc;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.ArrayList;
/**
* Created by Admin on 13-Jul-17.
*/
class MyAdapter extends RecyclerView.Adapter<MyAdapter.Myviewholder> {
private static final String TAG = "Adapter";
static Data_Model m;
XenImageUploading xenImageUploading;
ArrayList<Data_Model> arrayList;
private Context mContext;
public MyAdapter(XenImageUploading xenImageUploading, ArrayList<Data_Model> arrayList) {
this.arrayList = arrayList;
this.xenImageUploading = xenImageUploading;
}
#Override
public Myviewholder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.abc, parent, false);
Myviewholder myviewholder = new Myviewholder(view);
Log.d("myactivty ", "oncreateViewHolder");
return myviewholder;
}
#Override
public void onBindViewHolder(final Myviewholder holder, final int position) {
m = arrayList.get(position);
Log.d(" myactivty", "onBindviewholder" + position);
holder.imageView.setImageBitmap(m.getImage());
}
#Override
public int getItemCount() {
return arrayList == null ? 0 : arrayList.size();
}
public class Myviewholder extends RecyclerView.ViewHolder {
// public View view;
public ImageView imageView;
public Myviewholder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.image);
}
}
}
try this create one method in your adapter like this
public ArrayList<Data_Model> getArray() {
return arrayList;
}
now on your button click just call this method
upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ArrayList<Data_Model> arrayList= adapter.getArray();
}
});
ask me in case of any query
I'm using the Google-API to get the count of unread E-Mails and some Events from the Google-Calender. I used the Quick-Start Sample Code from Google and it worked fine(asks for scope-permissions if not set and so on). So I formed it to a Service and a Auth-Activity for the user to change their Accounts. My problem is that the User don't get asked for Authorization anymore. The App still uses the right Account and if I select an Account which is authorized for my App it still work but if I select a new Account no Authorization-form is being shown.
Google AuthUtil Error:
09-19 13:13:54.114: D/DEBUG_TEST(7072): ERROR: UserRecoverableErrorNeedPermission
Here is my Activity that changes the Account. Every time a user selects an Google-Account the Static-Variable "gAccountDaten"(GoogleAccountCredential Object) got updated.
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.gmail.GmailScopes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class GoogleAuthActivity extends Activity implements EasyPermissions.PermissionCallbacks {
static GoogleAccountCredential gAccountDaten;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = { GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_READONLY , GmailScopes.MAIL_GOOGLE_COM, CalendarScopes.CALENDAR_READONLY};
private Boolean verbunden = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.googleauthactivitylayout);
gAccountDaten = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES)).setBackOff(new ExponentialBackOff());
chooseAccount();
}
private String getGoogleAccountNameSettings(){
String toReturn = getPreferences(Context.MODE_PRIVATE)
.getString(PREF_ACCOUNT_NAME, null);
Log.d("ACCOUNT_DEBUG", "FUNC: getGoogleAccountNameSettings --> " + toReturn);
return toReturn;
}
private boolean setGoogleAccountNameSettings(String accountName){
try{
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.apply();
Log.d("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> " + accountName);
}catch (Exception exc){
Log.e("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> ERROR");
return false;
}finally {
Log.e("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> ERROR");
return true;
}
}
private boolean removeGoogleAccountNameSettings(){
try{
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.remove(PREF_ACCOUNT_NAME);
editor.apply();
GoogleService.EMAIL_COUNT = 0;
GoogleService.lstKalender.clear();
Log.d("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> " + "rennt");
}catch (Exception exc){
Log.e("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> ERROR");
return false;
}finally {
Log.e("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> ERROR");
return true;
}
}
#AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
private void chooseAccount( ) {
removeGoogleAccountNameSettings();
if (EasyPermissions.hasPermissions(
this, android.Manifest.permission.GET_ACCOUNTS)) {
String accountName = getGoogleAccountNameSettings();
if (accountName != null) {
gAccountDaten.setSelectedAccountName(accountName);
this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
Log.d("AUTH_DEBUG", "Already authed" + " | " + gAccountDaten.getScope());
//finish();
} else {
// Start a dialog from which the user can choose an account
startActivityForResult(
gAccountDaten.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
} else {
// Request the GET_ACCOUNTS permission via a user dialog
EasyPermissions.requestPermissions(
this,
"This app needs to access your Google account .",
REQUEST_PERMISSION_GET_ACCOUNTS,
android.Manifest.permission.GET_ACCOUNTS);
}
}
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode != RESULT_OK) {
//mOutputText.setText(
// "This app requires Google Play Services. Please install " +
// "Google Play Services on your device and relaunch this app.");
} else {
//getResultsFromApi();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
String accountName =
data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
setGoogleAccountNameSettings(accountName);
gAccountDaten.setSelectedAccountName(accountName);
Log.d("AUTH_DEBUG", "Authed after Picker -->" + accountName + " | " + gAccountDaten.getScope());
this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
finish();
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == RESULT_OK) {
Log.d("AUTH_DEBUG", "started aufter authorization -->" + resultCode + " | " + gAccountDaten.getScope());
this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
finish();
}
break;
}
}
/////PERMISSION CALLBACKS
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(
requestCode, permissions, grantResults, this);
}
/**
* Callback for when a permission is granted using the EasyPermissions
* library.
* #param requestCode The request code associated with the requested
* permission
* #param list The requested permission list. Never null.
*/
#Override
public void onPermissionsGranted(int requestCode, List<String> list) {
// Do nothing.
}
/**
* Callback for when a permission is denied using the EasyPermissions
* library.
* #param requestCode The request code associated with the requested
* permission
* #param list The requested permission list. Never null.
*/
#Override
public void onPermissionsDenied(int requestCode, List<String> list) {
Log.d("DEBUG_TEST", "NO PERM");
}
}
And here is my Google-Service Code. It will gather the information from the google api every 60 seconds and write it to static variables.
import android.*;
import android.app.Dialog;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.RemoteViews;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.CalendarList;
import com.google.api.services.calendar.model.CalendarListEntry;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.api.services.calendar.model.Events;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Label;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class GoogleService extends Service implements EasyPermissions.PermissionCallbacks{
GoogleAccountCredential gAccountDaten;
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
private static final String PREF_ACCOUNT_NAME = "accountName";
static String testj = "";
static ArrayList<Kalender> lstKalender = new ArrayList<>();
static int EMAIL_COUNT = 0;
//GOOGLE BERECHTIGUNGEN
private static final String[] SCOPES = { GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_READONLY , GmailScopes.MAIL_GOOGLE_COM, CalendarScopes.CALENDAR_READONLY};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("DEBUG_TEST", "onStartCommand");
gAccountDaten = GoogleAuthActivity.gAccountDaten;
if(gAccountDaten == null){
Log.d("DEBUG_TEST", "gAccountDaten == NULL!");
return 0;
}
getResultsFromApi();
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
getResultsFromApi();
handler.postDelayed(this, 60000);
}
};
handler.postDelayed(runnable, 60000);
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
}
#Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
}
//HELFER FUNKTIONEN
private void getResultsFromApi() {
if (! isGooglePlayServicesAvailable()) {
acquireGooglePlayServices();
} else if (gAccountDaten.getSelectedAccountName() == null) {
Log.d("DEBUG_TEST", "ChooseAccount");
} else if (! isDeviceOnline()) {
//Gerät Offline
} else {
Log.d("DEBUG_TEST", "MakeRequestTask -->" + gAccountDaten.getSelectedAccountName());
new MakeRequestTask(gAccountDaten).execute();
}
}
//CHECK: GERÄT ONLINE ?
private boolean isDeviceOnline() {
ConnectivityManager connMgr =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
//CHECK: GOOGLE SERVICE ONLINE ?
private boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
return connectionStatusCode == ConnectionResult.SUCCESS;
}
private void acquireGooglePlayServices() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
}
/////////////////////////MAKE REQUEST KLASSE////////////////////////////////////
private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
private com.google.api.services.gmail.Gmail mService = null;
private com.google.api.services.calendar.Calendar mServiceKalender = null;
private Exception mLastError = null;
public MakeRequestTask(GoogleAccountCredential credential) {
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
HttpTransport transport2 = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory2 = JacksonFactory.getDefaultInstance();
mService = new com.google.api.services.gmail.Gmail.Builder(
transport, jsonFactory, credential)
.setApplicationName("Gmail API Android Quickstart")
.build();
mServiceKalender = new com.google.api.services.calendar.Calendar.Builder(
transport2, jsonFactory2, credential)
.setApplicationName("Google Calendar API Android Quickstart")
.build();
Log.d("DEBUG_TEST", "mService und mServiceKalender Objecte instanzieren --> " + credential.getSelectedAccountName());
}
/**
* Background task to call Gmail API.
* #param params no parameters needed for this task.
*/
#Override
protected List<String> doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
/**
* Fetch a list of Gmail labels attached to the specified account.
* #return List of Strings labels.
* #throws IOException
*/
private List<String> getDataFromApi() throws IOException {
// Get the labels in the user's account.
String user = "me";
List<String> labels = new ArrayList<String>();
Label label = mService.users().labels().get(user, "INBOX").execute();
Log.d("DEBUG_TEST", "getDataFromApi() --> " + user );
//EMAIL_COUNT = label.getMessagesUnread();
EMAIL_COUNT = label.getMessagesTotal();
labels.add("E-Mails: " + EMAIL_COUNT);
lstKalender.clear();
String pageToken = null;
do {
CalendarList calendarList = mServiceKalender.calendarList().list().setPageToken(pageToken).execute();
List<CalendarListEntry> items = calendarList.getItems();
for (CalendarListEntry calendarListEntry : items) {
String KALENDERNAME = calendarListEntry.getSummary();
String KALENDER_ID = calendarListEntry.getId();
Kalender neuerKalender = new Kalender();
neuerKalender.setKalenderName(KALENDERNAME);
neuerKalender.setKalenderId(KALENDER_ID);
Log.d("KALENDER_DEBUG", "Kalender: " + KALENDERNAME + "wurde angelegt! ID: " + KALENDER_ID);
String pageToken2 = null;
do {
Events events = mServiceKalender.events().list(KALENDER_ID).setPageToken(pageToken2).execute();
List<Event> items2 = events.getItems();
for (Event event : items2) {
String calName = event.getSummary();
EventDateTime calStart = event.getStart();
EventDateTime calEnde = event.getEnd();
String calLocation = event.getLocation();
String calID = event.getId();
if(neuerKalender.addEvent(calName,calStart,calEnde,calLocation,calID)){
//Log.d("KALENDER_DEBUG", "Event: " + calName + " wurde zum Kalender " + KALENDERNAME + " hinzugefügt!");
}
}
pageToken2 = events.getNextPageToken();
} while (pageToken2 != null);
lstKalender.add(neuerKalender);
Log.d("KALENDER_DEBUG", "Kalender: " + neuerKalender.getKalenderName() + " durchgelaufen und zur Globalen Liste hinzugefügt!");
}
pageToken = calendarList.getNextPageToken();
} while (pageToken != null);
DaWidgetProvider.updateEventList(getBaseContext());
UpdateService updateService = new UpdateService();
updateService.buildUpdate(getBaseContext());
DaWidgetProvider.updateAllWidgets(getBaseContext());
return labels;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(List<String> output) {
if (output == null || output.size() == 0) {
// mOutputText.setText("No results returned.");
} else {
//output.add(0, "Data retrieved using the Gmail API:");
//mOutputText.setText(TextUtils.join("\n", output));
//mProgress.dismiss();
Context mContext = getApplicationContext();
}
}
#Override
protected void onCancelled() {
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
} else if (mLastError instanceof UserRecoverableAuthIOException) {
Log.d("DEBUG_TEST", "ERROR: UserRecoverableError" + mLastError.getMessage());
} else {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
}
} else {
Log.d("DEBUG_TEST", "abgebrochen");
}
}
}
}
Thanks,
J. Doe ;)
Nice that seems to be the problem. But ive got a problem to fix it, because my Google-Service and my Google-Account Picker Activity are differented. I tried to pass the mLastError to my Activity in an Intent and start the Authentication-Request there but i got the following Error:
09-19 13:44:18.508: E/AndroidRuntime(7959): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException)
And my Code changes in Google-Service and GoogleAuthActivity:
Google-Service:
protected void onCancelled() {
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
} else if (mLastError instanceof UserRecoverableAuthIOException) {
Log.d("DEBUG_TEST", "ERROR: UserRecoverableError" + mLastError.getCause().getMessage());
//KEINE BERECHTIGUNG GESETZT
[CODE CHANGES]
Intent startIntent = new Intent(getApplicationContext(), GoogleAuthActivity.class);
startIntent.putExtra("auththis", mLastError);
startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startIntent);
[/CODE CHANGES]
} else {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
}
} else {
Log.d("DEBUG_TEST", "abgebrochen");
}
}
GoogleAuthActivity:
//EXTRA DATA???
if(getIntent().hasExtra("auththis")){
Intent edIntent = getIntent();
Bundle extras = edIntent.getExtras();
UserRecoverableAuthIOException mLastError = null;
mLastError = (UserRecoverableAuthIOException) extras.get("auththis");
startActivityForResult(
mLastError.getIntent(),
GoogleAuthActivity.REQUEST_AUTHORIZATION);
}else{
chooseAccount();
}
I am creating an android camera app using opencv. First I make it like when I click the start button, it start taking pictures and in every second takes a picture and store it in storage. It works perfectly for me.
Then I tried to make it some tricky by forcing it to take 5 pictures in a second it works well.
But actually I faced problem when I make it to 20 pictures in 1 second. It did not work. The app hangs as soon as I click on the start button. I don't know why. But I think the problem is in threading.
Can someone help me how i will do it.
I have two java files in my project and here is the code.
package org.opencv.samples.tutorial3;
import java.io.FileOutputStream;
import java.util.List;
import org.opencv.android.JavaCameraView;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.util.AttributeSet;
import android.util.Log;
public class Tutorial3View extends JavaCameraView implements PictureCallback {
private static final String TAG = "Sample::Tutorial3View";
private String mPictureFileName;
public Tutorial3View(Context context, AttributeSet attrs) {
super(context, attrs);
}
public List<String> getEffectList() {
return mCamera.getParameters().getSupportedColorEffects();
}
public boolean isEffectSupported() {
return (mCamera.getParameters().getColorEffect() != null);
}
public String getEffect() {
return mCamera.getParameters().getColorEffect();
}
public void setEffect(String effect) {
Camera.Parameters params = mCamera.getParameters();
params.setColorEffect(effect);
mCamera.setParameters(params);
}
public List<Size> getResolutionList() {
return mCamera.getParameters().getSupportedPreviewSizes();
}
public void setResolution(Size resolution) {
disconnectCamera();
mMaxHeight = resolution.height;
mMaxWidth = resolution.width;
connectCamera(getWidth(), getHeight());
}
public Size getResolution() {
return mCamera.getParameters().getPreviewSize();
}
public void takePicture(final String fileName) {
Log.i(TAG, "Taking picture");
this.mPictureFileName = fileName;
// Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture.
// Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue
mCamera.setPreviewCallback(null);
// PictureCallback is implemented by the current class
mCamera.takePicture(null, null, this);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
mCamera.setPreviewCallback(this);
// Write the image in a file (in jpeg format)
try {
FileOutputStream fos = new FileOutputStream(mPictureFileName);
fos.write(data);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
}
And the second one is:
package org.opencv.samples.tutorial3;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
public class Tutorial3Activity extends Activity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private Tutorial3View mOpenCvCameraView;
private List<Size> mResolutionList;
private MenuItem[] mEffectMenuItems;
private SubMenu mColorEffectsMenu;
private MenuItem[] mResolutionMenuItems;
private SubMenu mResolutionMenu;
Thread thread;
Button start,stop;
boolean loop=false;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public Tutorial3Activity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.tutorial3_surface_view);
start=(Button)findViewById(R.id.button2) ;
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loop=true;
thread = new Thread(new task());
thread.start();
}
});
stop=(Button) findViewById(R.id.button);
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loop=false;
}
});
mOpenCvCameraView = (Tutorial3View) findViewById(R.id.tutorial3_activity_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
#Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
#Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
}
public void onCameraViewStopped() {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return inputFrame.rgba();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
List<String> effects = mOpenCvCameraView.getEffectList();
if (effects == null) {
Log.e(TAG, "Color effects are not supported by device!");
return true;
}
mColorEffectsMenu = menu.addSubMenu("Color Effect");
mEffectMenuItems = new MenuItem[effects.size()];
int idx = 0;
ListIterator<String> effectItr = effects.listIterator();
while(effectItr.hasNext()) {
String element = effectItr.next();
mEffectMenuItems[idx] = mColorEffectsMenu.add(1, idx, Menu.NONE, element);
idx++;
}
mResolutionMenu = menu.addSubMenu("Resolution");
mResolutionList = mOpenCvCameraView.getResolutionList();
mResolutionMenuItems = new MenuItem[mResolutionList.size()];
ListIterator<Size> resolutionItr = mResolutionList.listIterator();
idx = 0;
while(resolutionItr.hasNext()) {
Size element = resolutionItr.next();
mResolutionMenuItems[idx] = mResolutionMenu.add(2, idx, Menu.NONE,
Integer.valueOf(element.width).toString() + "x" + Integer.valueOf(element.height).toString());
idx++;
}
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
if (item.getGroupId() == 1)
{
mOpenCvCameraView.setEffect((String) item.getTitle());
Toast.makeText(this, mOpenCvCameraView.getEffect(), Toast.LENGTH_SHORT).show();
}
else if (item.getGroupId() == 2)
{
int id = item.getItemId();
Size resolution = mResolutionList.get(id);
mOpenCvCameraView.setResolution(resolution);
resolution = mOpenCvCameraView.getResolution();
String caption = Integer.valueOf(resolution.width).toString() + "x" + Integer.valueOf(resolution.height).toString();
Toast.makeText(this, caption, Toast.LENGTH_SHORT).show();
}
return true;
}
class task implements Runnable {
public void run() {
while (loop) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
String currentDateandTime = sdf.format(new Date());
final String fileName = Environment.getExternalStorageDirectory().getPath() +
"/sample_picture_" + currentDateandTime + ".jpg";
mOpenCvCameraView.takePicture(fileName);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Tutorial3Activity.this, fileName + " saved", Toast.LENGTH_SHORT).show();
}
});
try {
thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Note: The above code works well for taking 5 pictures in 1 second. But when I change thread.sleep(200) to thread.sleep(50) for taking 20 pictures in 1 second it hangs.