I tried to implement a loading circle in my application as it transitioned from the previous activity to this activity. As there are a ton of calculations in this activity, it turns black screen as it's doing the calculations for a good 10 to 15 seconds, once the calculations are done it'd display an image, seen in onCreate: resultImage.setImageBitmap(finalBitmap);
However, the circle doesn't appear, and it's still the same old black screen to image transition.
Imported:
import android.app.ProgressDialog;
Declared:
private ProgressDialog progressDialog;
Initialized:
progressDialog = new ProgressDialog(this);
progressDialog.setTitle(null);
progressDialog.setCancelable(false);
Made it visible:
progressDialog.show();
Changed its message as the code progressed:
progressDialog.setMessage("Finding Objects...");
progressDialog.setMessage("Calculating Areas...");
progressDialog.setMessage("Calculating Height...");
... etc etc
onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
progressDialog = new ProgressDialog(this);
progressDialog.setTitle(null);
progressDialog.setCancelable(false);
progressDialog.setMessage("Processing...");
progressDialog.show();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto_test);
if (!OpenCVLoader.initDebug()) {
Log.d("opencv", "OpenCVLoader.initDebug() - ERROR");
} else {
Log.d("opencv", "OpenCVLoader.initDebug() - OK");
}
String filePath = getIntent().getStringExtra(FILEPATH);
ArrayList<String> f = new ArrayList<String>();
File dir = new File(filePath);
File[] listFile;
listFile = dir.listFiles();
for (File e : listFile) {
f.add(e.getAbsolutePath());
}
paths = f;
resetVariables();
progressDialog.setMessage("Finding Objects...");
for (int xx = 0; xx < paths.size(); xx++) {
Bitmap areaBitmap = BitmapFactory.decodeFile(paths.get(xx));
getArea(areaBitmap);
}
if (loopCounter > 0) {
progressDialog.setMessage("Calculating Areas...");
meanBlackArea = blackArea / loopCounter;
Log.e("meanBlackArea", "30% of mean black " + String.valueOf(meanBlackArea * 0.3) + " 110% of mean black " + String.valueOf(meanBlackArea * 1.1));
Log.e("Loopcounter", String.valueOf(loopCounter));
}
resetVariables();
Log.e("~", "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Log.e("Lowest Green", String.valueOf(greenArea));
Log.e("~", "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
progressDialog.setMessage("Calculating Height...");
int frameNumber = 0;
for (int x = 0; x < paths.size(); x++) {
Bitmap calculationsBitmap = BitmapFactory.decodeFile(paths.get(x));
numRectBlack = 0;
numRectGreen = 0;
tempBitmap = findCombineBitmap(calculationsBitmap);
if (check == true) {
if (Double.isInfinite(tempLineHeightCm) == false) {
frameNumber = x;
finalBitmap = tempBitmap;
}
}
}
progressDialog.setMessage("Tidying Up...");
TextView tvR = (TextView) findViewById(R.id.tvR);
if(tempLineHeightCm==0) {
tvR.setText("We could not detect a bounce!\nPlease do the following and try again:\n1. Remove all foreign objects from testing grounds.\n2.Make sure that there are ample lighting on the testing grounds.");
}else{
tvR.setText("Frame " + frameNumber + ", Bounce Height = " + tempLineHeightCm + "cm");
ImageView resultImage = (ImageView) findViewById(R.id.resultImage);
resultImage.setImageBitmap(finalBitmap);
progressDialog.dismiss();
}
}
Link to code file:
Google Drive
Notes:
MainActivity.java has a working progresscircle
TestAutoRun.java is the one I'm working on.
Show ProgressDialog, start new AsyncTask and do your heavy calculations in background. After the AsyncTask completes, hide the progress dialog and go to next activity.
If you don't know how to use AsyncTask, check the reference here.
Related
I am trying to crop faces out of the original captured image using the rect values to identify the target areas and create bitmaps of just the face detected area. This works :)
The issue is:
When I have an image with more than one face, the for loop in the onSuccess method which calls an alert dialog for user input for each cropped face filename seems to loop before the alert dialogs onClick() is complete. The code for saving each face is fired once the alert dialog onClick (OK) method is called.
The code currently saves only one of the cropped faces, the different user inputs are correctly handled in the individual alert dialogs but, only the last face in the is saved.
I think, the for loop is continuing to loop after the alert dialog is triggered but before the user has completed the input and the save has taken place for each face. Therefore, when the save method is called it is only saving the last object in the faces list.
Any suggestions on how I can improve this code?
#Override
public void onImage(CameraKitImage cameraKitImage) {
capturedImage = cameraKitImage.getBitmap();
capturedImage = Bitmap.createScaledBitmap(capturedImage, cameraView.getWidth(), cameraView.getHeight(), false);
cameraView.stop();
processFaceDetection(capturedImage);
}
public void processFaceDetection(final Bitmap bitmap) {
FirebaseVisionImage visionImage = FirebaseVisionImage.fromBitmap(bitmap);
FirebaseVisionFaceDetectorOptions detectorOptions = new FirebaseVisionFaceDetectorOptions.Builder()
.setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
.setLandmarkMode(FirebaseVisionFaceDetectorOptions.NO_LANDMARKS)
.setClassificationMode(FirebaseVisionFaceDetectorOptions.NO_CLASSIFICATIONS)
.setMinFaceSize(0.15f)
.enableTracking()
.build();
FirebaseVisionFaceDetector detector = FirebaseVision.getInstance().getVisionFaceDetector(detectorOptions);
detector.detectInImage(visionImage).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
#Override
public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) {
listSize = firebaseVisionFaces.size();
Bitmap originalCapture = Bitmap.createScaledBitmap(capturedImage, cameraView.getWidth(), cameraView.getHeight(), false);//scaled bitmap created from captured image
saveImageOriginal(originalCapture);
//for (FirebaseVisionFace face : firebaseVisionFaces) {
for ( i = 0; i < firebaseVisionFaces.size(); i++){
FirebaseVisionFace face = firebaseVisionFaces.get(i);
Rect rect = face.getBoundingBox();
faceCrop = Bitmap.createBitmap(originalCapture, rect.left, rect.top, rect.width(), rect.height());//face cropped using rect values
RectOverlay rectOverlay = new RectOverlay(graphicOverlay, rect);
graphicOverlay.add(rectOverlay);//draw box around face
showAddItemDialog(Camera.CurrentContext); //prompt for name, save cropped face
}
}
});
}
private void showAddItemDialog(Context c) {
final EditText inputName = new EditText(c);
AlertDialog dialog = new AlertDialog.Builder(c)
.setTitle("Input Person's Name" + i)
.setMessage("Format: LastName, FirstName")
.setView(inputName)
.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
nameIn = String.valueOf(inputName.getText());
try {
saveImage(faceCrop); //give read write permission
}catch (Exception e) {
e.printStackTrace();
}
}
})
.setNegativeButton("Cancel", null)
.create();
dialog.show();
}
public String saveImage(Bitmap croppedFace) {
String eventFaces, event;
event = "/Summer Event 2020";
eventFaces = "/Event_Faces";
final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
croppedFace.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
final File facesDirectory = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + event + eventFaces); //crop
if (!facesDirectory.exists()) {
Log.d("directory SAVING", "" + facesDirectory.mkdirs());
facesDirectory.mkdirs();
}
try {
croppedFile = new File(facesDirectory, nameIn + ".jpg");
croppedFile.createNewFile();
FileOutputStream fo = new FileOutputStream(croppedFile);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(Camera.CurrentContext, new String[]{croppedFile.getPath()}, new String[]{"image/jpeg"}, null);
fo.close();
Log.d("TAG", "File Saved::--->" + croppedFile.getAbsolutePath());
Toast.makeText(Camera.this, nameIn + " " + "i" + i + " list" + listSize + " " + "Face Cropped and Saved to -> " + croppedFile.getPath(), Toast.LENGTH_SHORT).show();
return croppedFile.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}//end of save image
If anyone is experiencing this same type of issue, I divided the code in the for loop into two separate loops and incorporated a flag into the AlertDialog on user input (keyboard in). Once the flag is true, following the AlertDialog user input, the conditions will now be met for the second for loop.
Hope this helps.
I am using the HERE Maps Lite SDK for Android as a library in my project.
I want to show MapView, and add overlays of all shelters I have in my database, in their specific coordinates.
The map works well, but the shown coordinates are not accurate. I tried to geocode the coordinates in lat-long website, and they are correct, but in the map they are shown right to their real location.
My code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shelters_map);
mapView = findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
ActivityCompat.requestPermissions(SheltersMapActivity.this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION}, 123);
if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
Toast.makeText(getApplicationContext(), "אנא אפשר גישה לשירותי מיקום", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this,
new String[]{ACCESS_FINE_LOCATION},
1);
} else // premission is granted
{
GPStracker g = new GPStracker(getApplicationContext());
userLocation = g.getLocation();
}
loadMapScene();
addSheltersOverlay();
// loadMapScene();
}
private void loadMapScene() {
// Load a scene from the SDK to render the map with a map style.
mapView.getMapScene().loadScene(MapStyle.NORMAL_DAY, new MapScene.LoadSceneCallback() {
#Override
public void onLoadScene(#Nullable MapScene.ErrorCode errorCode) {
if (errorCode == null) {
mapView.getCamera().setTarget(new GeoCoordinates(userLocation.getLatitude(),
userLocation.getLongitude()));
mapView.getCamera().setZoomLevel(15);
} else {
Log.d("data1", "onLoadScene failed: " + errorCode.toString());
}
}
});
}
private void addSheltersOverlay() {
db = new DatabaseHandler(this);
ArrayList<Shelter> places = this.db.getAllPlaces();
Shelter userLocationPlace = new Shelter("המיקום שלך", "", userLocation, null, 0, "");
places.add(userLocationPlace);
int size = places.size();
for(int i = 0; i < size; i++) {
TextView textView = new TextView(this);
textView.setTextColor(Color.parseColor("#FFFFFF"));
textView.setText(places.get(i).getName());
LinearLayout linearLayout = new LinearLayout(this);
if (places.get(i) instanceof Basement)
linearLayout.setBackgroundColor(Color.BLACK);
else if (places.get(i) instanceof Stairs)
linearLayout.setBackgroundColor(Color.GREEN);
else
linearLayout.setBackgroundColor(Color.BLUE);
linearLayout.setPadding(10, 10, 10, 10);
linearLayout.addView(textView);
GeoCoordinates geoCoordinates = new GeoCoordinates(places.get(i).getLocation().getLatitude(),
places.get(i).getLocation().getLongitude());
MapOverlay<LinearLayout> mapOverlay = new MapOverlay<>(linearLayout, geoCoordinates);
mapView.addMapOverlay(mapOverlay);
}
}
The shown map:
.
I can see the streets names in the shown map itself, and I see that it is not the accurate point.
Anybody help?
From the code it looks correct, but I cannot see the location vs. the expected location. By default, MapOverlays are drawn centered on the coordinates. You can set an anchor point to move the overlay in relation to the coordinates. This could help if there is always an offset between the coordinates in your database and the location on the map.
Maybe, can you try to render a small MapCircle item onto the map at the expected location? Then you can more easily see where that location lies on the map. You can compare the results with https://www.latlong.net/.
I apologize if I worded this poorly but for the sake of clarity I will explain as best I can. I'm using MPAndroidChart to draw a line graph and I followed this tutorial to get it up and running https://www.numetriclabz.com/android-line-chart-using-mpandroidchart-tutorial/#Defining_X-axis_labels. I've made some adjustments to suit my needs and so on.
On button click, I call a method that adds another entry using the value of the edit text field, at the position that i increment each button press so the code is something like entries.add(new Entry(editTextValue, numEntries));This does what I want it to do while I'm looking at the current activity screen, with the previous value remaining, and the next value being added. However, once i leave that activity and return to it, only the last value remains. My understanding is that I need to have a for loop that will iterate over each element in arraylist when I call the drawGraph method that I'm using, but I haven't had any luck with this. I've tried to use for(Entry e: entries) and use e in place of numEntries, but the data type is not compatible. Any help is greatly appreciated!
EDIT: `public class testActivity extends AppCompatActivity {
int counter = 0;
public ArrayList entries = new ArrayList<>();
public static int lifetimeNums;
public static int nums = 0;
public static int numEntries;
public static String entryLabel = Integer.toString(numEntries);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
reDrawGraph();
}
// Graphing method
public void reDrawGraph(){
LineChart chart = (LineChart) findViewById(R.id.chart);
XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
chart.getAxisLeft().setAxisMaxValue(100);
chart.getXAxis().setAxisMaxValue(100);
//Creating list of entries
LineDataSet dataset = new LineDataSet(entries, "# of Calls");
// creating labels
ArrayList<String> labels = new ArrayList<String>();
for (int i = 0; i < 10 + numEntries; i++) {
labels.add(Integer.toString(i));
}
LineData data = new LineData(labels, dataset);
entries.add(new Entry(testActivity.nums, numEntries));
chart.animateXY(1000,1000);
chart.notifyDataSetChanged();
chart.invalidate();
chart.setData(data); // set the data and list of lables into chart
}
public void counterClicked(View view){
try {
EditText inputText = (EditText) findViewById(R.id.edit_text_val);
int localNums = Integer.parseInt(inputText.getText().toString());
if (counter < 3) {
nums += localNums;
counter++;
numEntries++;
Toast.makeText(this, "Total Entries" + entries.get(0),
Toast.LENGTH_SHORT).show();
reDrawGraph();
inputText.getText().clear();
}
if (counter == 3){
lifetimeNums++;
numEntries++;
Intent intent = new Intent(this, SelectionActivity.class);
startActivity(intent);
}
}catch (Exception e) {
Toast.makeText(this, "Please enter a value",
Toast.LENGTH_SHORT).show();
}`
I need to implement few gestures in activity. I used Genymotion for that, saved gestures file in res/raw folder and wrote a code which is showing all good but keeps crashing the application. Does anyone know what could be the possible reason? I really tried to solve, but it seems i am missing something!
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GestureOverlayView gesturesView = new GestureOverlayView(this);
View inflate = getLayoutInflater().inflate(R.layout.activity_garden,
null);
gesturesView.addView(inflate);
gesturesView.addOnGesturePerformedListener(this);
gestures = GestureLibraries.fromRawResource(this, R.raw.gestures);
if (!gestures.load()) {
finish();
}
setContentView(gesturesView);
}
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = gestures.recognize(gesture);
int index = 0;
double maxScore = predictions.get(index).score;
for (int i = 1; i < predictions.size(); i++) {
if (predictions.get(i).score > maxScore) {
index = i;
maxScore = predictions.get(i).score;
}
}
Prediction p = predictions.get(index);
if (p.name.equalsIgnoreCase("Love"))
daisy.setImageResource(sp.getInt("Love", 0));
if (p.name.equalsIgnoreCase("Hit"))
daisy.setImageResource(sp.getInt("Hit", 0));
if (p.name.equalsIgnoreCase("Pet"))
daisy.setImageResource(sp.getInt("Pet", 0));
Toast.makeText(this, p.name + "\n" + p.score, Toast.LENGTH_SHORT)
.show();
}
On your code, what happen if you don't get any prediction?
Well, index will be equals to 0, and predictions.get(index) will crash because there is no object at index 0.
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = gestures.recognize(gesture);
if (predictions == null || predictions.isEmpty()) {
return;
}
// continue the regular flow
}
i make a button to start a game. whenever i click on that button from AVD, unfortunately the program has stopped and i am new to android programming. i try googling my problem and it seems there is something wrong with the code. can anyone help me? i also share a link to my code, visit https://www.dropbox.com/sh/hyitjbgda69rkd4/3Iz8WuM5-5
the main activity
public class MainActivity extends Activity
{
private Game game1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.startbutton);
button.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
// Perform action on click
game1 = new Game(this);
setContentView(game1);
}
});
}
}
Game class :
public Game(OnClickListener onClickListener)
{
super((Context) onClickListener);
caneta = new Paint();
this.caneta.setARGB(255, 0, 0, 0);
this.caneta.setAntiAlias(true);
this.caneta.setStyle(Style.STROKE);
this.caneta.setStrokeWidth(5);
l = this.getWidth();
a = this.getHeight();
singlesquare = new Cell[x][y];
int xss = l / x;
int yss = a / y;
for (int z = 0; z < y; z++)
{
for (int i = 0; i < x; i++)
{
singlesquare[z][i] = new Empty(xss * i, z * yss);
}
}
}
You really shouldn't be calling setContentView() more than once. Is that the line that's causing the error? Further, the object type of game1 doesn't appear to be a View.