/r/learnandroid

Photograph via snooOG

Ask questions, help others - everything related to android programming

/r/learnandroid

5,977 Subscribers

0

help

0 Comments
2023/08/05
19:16 UTC

1

What I Wish I'd Known About Software Engineering

0 Comments
2023/07/22
18:22 UTC

3

Understanding Android Fundamentals.

I have just started professionally in the industry with an YOE of 1 and I can pretty much decently build features , fix bugs , create applications from scratch etc .
But sometimes , I still feel like I do not understand what is going underneath and some android fundamentals are a total blackbox for me.
For eg if someone asks what exactly is Context or ContextCompat or maybe what is Handler and Looper or How does networking in android work or maybe how to solve ANRs etc.
( I am just stating some examples , I know what they are but still )

I feel like I Just know how to make applications and I a lot of fundamentals feel like a blackbox to me.
Maybe this is because the way I started learning native development . I did not start by understanding the things going underneath , I started by just randomly building projects . or maybe this is normal.

This entire problem creates a huge Imposter syndrome and makes me feel superficial .
I would like to fix this and understand things from scratch but it also feels like android has reached a level of abstraction , that I do not actually need or would need to understand all of these since its APIs handle most of the stuff.

But as a Engineer , I would love to understand how things work , is there any resources which would help me with this , or maybe a process which I should go through to get a better grasp at things or am i just delusional.

0 Comments
2023/07/20
09:09 UTC

3

Understanding Android Fundamentals.

I have just started professionally in the industry with an YOE of 1 and I can pretty much decently build features , fix bugs , create applications from scratch etc .
But sometimes , I still feel like I do not understand what is going underneath and some android fundamentals are a total blackbox for me.
For eg if someone asks what exactly is Context or ContextCompat or maybe what is Handler and Looper or How does networking in android work or maybe how to solve ANRs etc.
( I am just stating some examples , I know what they are but still )

I feel like I Just know how to make applications and I a lot of fundamentals feel like a blackbox to me.
Maybe this is because the way I started learning native development . I did not start by understanding the things going underneath , I started by just randomly building projects . or maybe this is normal.

This entire problem creates a huge Imposter syndrome and makes me feel superficial .
I would like to fix this and understand things from scratch but it also feels like android has reached a level of abstraction , that I do not actually need or would need to understand all of these since its APIs handle most of the stuff.

But as a Engineer , I would love to understand how things work , is there any resources which would help me with this , or maybe a process which I should go through to get a better grasp at things or am i just delusional.

3 Comments
2023/07/20
09:09 UTC

1

Resources for learning app development with Java.

I am currently following android development fundamentals from google, it is in java, but is somewhat outdated,

  • Some methods used are outdated.
  • There are new chnages (like basic activty now hase 4 parts instead of 2, activity_main.xml, contents_main.xml, and 2 fragments.)
  • There is also the Binding class, which is not mentioned in the course yet, so i guess it is relatively new. And the situation is similar with NavController and NavHostFragment classes
  • etc, i am sure there will be more unknown and new things as I progress through the course.

The reasons why i want to stick with java are as follow:

  • I already know the basics atleast, and plan on learning advanced stuff in java Mainly DS algo.
  • Java has vast uses and is used in alot of places. Where as i have heard that kotlin i smainly only used for android apps?
  • I am somewhat short on time, and am not sure if i will be able to learn Kotlin quick enough.

Although Java is prefered, but if there are no up to date courses in it, and you strongly advise going the Kotlin route, Then please mention a some good resource.

I know of Android basics with compose and Basics in Kotlin (which one of these to follow?? Later units of both courses have similar titles). There is also the Udacity nanodegree, but that is expensive (400$/mo Uff).

Any free or affordable course will be prefered. Maybe video ones will be better??

0 Comments
2023/07/09
05:14 UTC

2

Security for Android Developers

0 Comments
2023/06/17
14:37 UTC

1

Applying Kotlin Structured concurrency: Part IV — Coroutines Cancellation

0 Comments
2023/06/15
17:26 UTC

2

Applying Structured concurrency in Kotlin: Part II — Coroutines creation

0 Comments
2023/06/14
19:51 UTC

2

Applying Kotlin Structured Concurrency: Part III — Exceptions in coroutines

0 Comments
2023/06/13
11:59 UTC

3

Real Interview with Big Bank Corp - Senior Android Developer position - 14 Questions

0 Comments
2023/06/10
19:34 UTC

5

Help with applying to Android Jobs: Tips for CV, Cover Letter and Motivation Questions

1 Comment
2023/06/06
20:34 UTC

5

XML or Compose? RxJava or Coroutines?

0 Comments
2023/04/28
14:24 UTC

2

TFLite Model Not Analyzing Bitmap

I cannot identify precisely what the problem is, but I know it is a problem with how a TFLite model is receiving a bitmap, as I tried sending it a different way through calling the Camera intent and it worked as intended by doing that, but I cannot call the Camera Intent as it will pull up the Camera screen, which I aim to not do.

Both versions of this code use the same tflite model, so I know it is not a model issue.

  picture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(cameraIntent, 1);
    }

    public void classifyImage(Bitmap image){
        try {
            Model model = Model.newInstance(getApplicationContext());
            TensorBuffer inputFeature0 = TensorBuffer.createFixedSize(new int[]{1, 224, 224, 3}, DataType.FLOAT32);
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * imageSize * imageSize * 3);
            byteBuffer.order(ByteOrder.nativeOrder());
            int [] intValues = new int[imageSize * imageSize];
            image.getPixels(intValues, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight());
            int pixel = 0;
            for(int i = 0; i < imageSize; i++){
                for(int j = 0; j < imageSize; j++){
                    int val = intValues[pixel++]; // RGB
                    byteBuffer.putFloat(((val >> 16) & 0xFF) * (1.f / 255.f));
                    byteBuffer.putFloat(((val >> 8) & 0xFF) * (1.f / 255.f));
                    byteBuffer.putFloat((val & 0xFF) * (1.f / 255.f));
                }
            }
            inputFeature0.loadBuffer(byteBuffer);
            Model.Outputs outputs = model.process(inputFeature0);
            TensorBuffer outputFeature0 = outputs.getOutputFeature0AsTensorBuffer();
            float[] confidences = outputFeature0.getFloatArray();
            int maxPos = 0;
            float maxConfidence = 0;
            for(int i = 0; i < confidences.length; i++){
                if(confidences[i] > maxConfidence){
                    maxConfidence = confidences[i];
                    maxPos = i;
                }
            }
            String[] classes = {"Banana", "Orange", "Pen", "Sticky Notes"};
            result.setText(classes[maxPos]);
            String s = "";
            for(int i = 0; i < classes.length; i++){
                s += String.format("%s: %.1f%%\n", classes[i], confidences[i] * 100);
            }
            confidence.setText(s);
            model.close();
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == 1 && resultCode == RESULT_OK) {
            Bitmap image = (Bitmap) data.getExtras().get("data");
            int dimension = Math.min(image.getWidth(), image.getHeight());
            image = ThumbnailUtils.extractThumbnail(image, dimension, dimension);
            imageView.setImageBitmap(image);

            image = Bitmap.createScaledBitmap(image, imageSize, imageSize, false);
            classifyImage(image);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

Nonworking version:

This version will always return the same confidences (changes depending on different tflite models being used) no matter the image.

public class MainActivity extends AppCompatActivity implements ImageAnalysis.Analyzer, View.OnClickListener {

    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    PreviewView previewView;
    private ImageCapture imageCapture;
    private Button bCapture;
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                startCameraX(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }, getExecutor());

    }

    Executor getExecutor() {
        return ContextCompat.getMainExecutor(this);
    }

    private void startCameraX(ProcessCameraProvider cameraProvider) {
        cameraProvider.unbindAll();
        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();
        Preview preview = new Preview.Builder()
                .build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());

        // Image capture use case
        imageCapture = new ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build();
        cameraProvider.bindToLifecycle( this, cameraSelector, preview, imageCapture);
    }



    @SuppressLint("RestrictedApi")
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.bCapture:
                capturePhoto();
                break;
        }
    }

    private void capturePhoto() {
        ContentValues contentValues = new ContentValues();
        imageCapture.takePicture(
                new ImageCapture.OutputFileOptions.Builder(
                        getContentResolver(),
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        contentValues
                ).build(),
                getExecutor(),
                new ImageCapture.OnImageSavedCallback() {
                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                        Toast.makeText(MainActivity.this, "Photo has been saved successfully.", Toast.LENGTH_SHORT).show();
                        Bitmap image = BitmapFactory.decodeFile(getLastImageId());
                        int dimension = Math.min(image.getWidth(), image.getHeight());
                        image = ThumbnailUtils.extractThumbnail(image, dimension, dimension);
                        image = Bitmap.createScaledBitmap(image, 224, 224, false);
                        imageView.setImageBitmap(image);
                        classifyImage(image);
                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {
                        Toast.makeText(MainActivity.this, "Error saving photo: " + exception.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                }
        );

    }
    private String getLastImageId(){
        final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
        final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
        Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
        if(imageCursor.moveToFirst()){
            @SuppressLint("Range") String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
            imageCursor.close();
            System.out.println(fullPath);
            return fullPath;
        }else{
            return "";
        }
    }

    private void classifyImage(Bitmap image) {
        try {
            Model model = Model.newInstance(getApplicationContext());

            // Creates inputs for reference.
            TensorBuffer inputFeature0 = TensorBuffer.createFixedSize(new int[]{1, 224, 224, 3}, DataType.FLOAT32);
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4*224*224*3);
            byteBuffer.order(ByteOrder.nativeOrder());
            int[] intValues = new int[224*224];
            image.getPixels(intValues, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight());
            int pixel = 0;
                    for(int i = 0; i < 224; i++) {
                        int val = intValues[pixel++];
                        byteBuffer.putFloat(((val >> 16) & 0xFF) * (1.f/255.f));
                        byteBuffer.putFloat(((val >> 8) & 0xFF) * (1.f/255.f));
                        byteBuffer.putFloat(((val  & 0xFF) * (1.f/255.f)));
                    }
            inputFeature0.loadBuffer(byteBuffer);

            // Runs model inference and gets result.
            Model.Outputs outputs = model.process(inputFeature0);
            TensorBuffer outputFeature0 = outputs.getOutputFeature0AsTensorBuffer();
            float[] conifdences = outputFeature0.getFloatArray();
            int maxPos = 0;
            float maxConf = 0;
            for(int i = 0; i < conifdences.length; i++) {
                if(conifdences[i] > maxConf) {
                    maxConf = conifdences[i];
                    maxPos = i;
                }
            }
            String[] classes = {"chicken", "apple", "things", "things"};
            System.out.println(classes[maxPos]);
            String s = "";
            for(int i = 0; i < classes.length; i++) {
                s+= String.format("%s: %.1f%%\n", classes[i], conifdences[i]*100);
            }
            System.out.println(s);
            // Releases model resources if no longer used.
            model.close();
          }

}
0 Comments
2023/04/09
19:45 UTC

0

Android Studio Help

Can you help me with this error in Android Studio?

0 Comments
2023/04/02
06:13 UTC

1

Tell us what you think about this design

0 Comments
2023/03/13
13:05 UTC

2

Material Design Login, Signup & Splash Pages Tutorial for Android

0 Comments
2023/03/12
12:18 UTC

5

When i use the Delete from table from DAO file my table in recyclerview clears but when i make a new entry the ID remains the same. Why is this and how could i make the ID start from 1?

Here is the DAO and table

@Entity(tableName = "results_table")
data class Result(
    @PrimaryKey(autoGenerate = true)
    var Id: Long? = 0L,

    @ColumnInfo(name = "points")
    val points: Int?,



    @ColumnInfo(name = "time")
    val lapsedTime: Long,


    @ColumnInfo(name = "date")
    val date: String



)


Dao:
@Query("DELETE FROM results_table")
        suspend fun clear()
2 Comments
2023/03/08
09:40 UTC

3

How to save time to room database with a counter?

I would like to save the time i spent playing my game in my room database. Is there any better way to make a counter?

ViewModel:

val secondscount: MutableLiveData<Int> by lazy {
        MutableLiveData<Int>()
    }

fun startTimer() {
        runnable = Runnable {
            secondscount++ //This results as an typemismatch error
            handler.postDelayed(runnable, 1000)
        }
        handler.postDelayed(runnable, 1000)

    }

    fun stopTimer() {
        handler.removeCallbacks(runnable)

    }

The database table

@Entity(tableName = "results_table")
data class ResultRow(
    @PrimaryKey(autoGenerate = true)
    var Id: Long? = 0L,

    @ColumnInfo(name = "points")
    val pisteet: Int,


    @ColumnInfo(name = "time")
    val time: Int,

)
1 Comment
2023/03/07
08:10 UTC

2

Can't get test to run

I'm working through Udacity's "Developing Android Apps with Kotlin" class. I'm in part 6, where I'm supposed to run a test (SleepDatabaseTest). When I originally ran it, I got an error that said

"Run Android instrumented tests using Gradle" option was ignored because this module type is not supported yet.

So I found a post on StackOverflow that said to uncheck "Run Android instrumented tests using Gradle" in the testing settings.

I did that, and the error message went away, but the test is still not running (it just says "Tests Passed 0 passed")

Can anyone help me fix this? Thanks

ETA: I also added the exclude module: "protobuf-lite" line to my build.gradle (Module) file, but that didn't seem to make a difference (although I'm not 100% sure I did that right)

ETA^2 : found the solution: https://stackoverflow.com/questions/72130959/android-studio-test-passed-0-passed

0 Comments
2023/03/07
01:40 UTC

3

How can i use Kotlin to run a series of sequential strings in a Multiline android widget?

I am taking the self learning approach, through a couple of books. i decided to refactor a Python CLI Into a GUI through Android. My question is this, in the application i set the id to a multiline text widget and create an onClick button to get everything in motion but due to my limited experience i have the on click function give me the second text output i want to spit out. Can someone point me in the best way to suspend/ or sleep the function and then clear the original output from my multiline text field and output my next desired text??

fun startSpeechBlurb(view: View) {

        var intro_multiline: EditText =findViewById(R.id.intro_multiline)

        if (intro_multiline.text.isEmpty()){

            val hiNum: String = "Hello Friend"
            val byeNum: String = "Bye Friend"
            
            intro_multiline.setText(hiNum)
            intro_multiline.setText(byeNum)

        }
0 Comments
2023/03/01
03:00 UTC

1

The Complete Guide to Android Design Patterns - Part 3

0 Comments
2023/02/26
14:16 UTC

4

The Complete Guide to Android Design Patterns - Part 2

0 Comments
2023/02/19
13:32 UTC

3

The Complete Guide to Android Design Patterns - Part 1

0 Comments
2023/02/13
11:20 UTC

5

Senior Android Developer Checklist

0 Comments
2023/02/11
19:29 UTC

3

How to put integer on textview?

So i have to make this mathgame at school. Basicly the game shows two random numbers and then you have to tell what is the numbers sum.

I have two TextViwe elements and i need them to display integer type of data not string. How is this possible?

3 Comments
2023/02/02
16:23 UTC

2

The paradigm of state and UI in Jetpack Compose is something I'm still wrapping my head around, but it feels good. Abstracting UI elements into functions just works with my brain somehow. So much better than looking up views the way it was before.

0 Comments
2023/02/02
03:45 UTC

3

How can i make my app to start from fragment?

How can i make my app to start from fragment? My app currrenty starts from mainactvity. Is there a video or code example somewhere?

Fix: Go to activitymain.xml and edit <fragment>

3 Comments
2023/01/31
07:48 UTC

Back To Top