3
\$\begingroup\$

This is a task from lab classes at my university. Problem statement was to showcase following features:

  • Multiple activities in app.
  • Passing data from one activity to another.
  • Changing behavior of back button in one of activities.
  • Getting picture from camera and displaying it in app.
  • Binding callback action in XML file instead of Java code.

It's based heavily on examples, but I wonder if I can get any general advice about code quality.

Whole project on GitHub: https://github.com/rogalski/tmlab2

And Java and layout code:

MyActivity.java:

package lab.tm.rogalski.lab2;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setListeners();
    }

    @Override
    public void onResume() {
        EditText editText = (EditText) findViewById(R.id.TextToSend);
        editText.setText("");
        super.onResume();
    }

    private void setListeners() {
        Button sendButton = (Button) findViewById(R.id.SendBtn);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText editText = (EditText) findViewById(R.id.TextToSend);
                String data = editText.getText().toString();
                sendIntent(data);
            }
        });
    }

    private void sendIntent(String data) {
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("data", data);
        startActivity(intent);
    }


}

SecondActivity.java

package lab.tm.rogalski.lab2;

import android.app.Activity;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SecondActivity extends Activity {
    static final int REQUEST_TAKE_PHOTO = 1;
    String mCurrentPhotoPath;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
        retrieveIntentData();
    }

    private void retrieveIntentData() {
        Intent intent = getIntent();
        TextView target = (TextView) findViewById(R.id.TextDestination);
        target.setText(intent.getStringExtra("data"));
    }

    private void showPicture() {
        if (mCurrentPhotoPath == null)
            return;
        ImageView iv = (ImageView) findViewById(R.id.imageView);
        iv.setImageBitmap(BitmapFactory.decodeFile(mCurrentPhotoPath));
    }

    @Override
    public void onBackPressed() {
        Toast.makeText(this, "Back button disabled. Use a button above.", Toast.LENGTH_SHORT).show();
        // super.onBackPressed();
    }

    public void onBtnClick(View v) {
        Intent intent = new Intent(this, MyActivity.class);
        startActivity(intent);
    }

    public void onTakePhotoBtnClick(View v) {
        dispatchTakePictureIntent();
    }

    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) == null) {
            Toast.makeText(this, "Camera not detected.", Toast.LENGTH_SHORT).show();
        }

        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            Log.d("TAG", Log.getStackTraceString(ex));
            Toast.makeText(this, "Failed to create image file.", Toast.LENGTH_SHORT).show();
        }

        if (photoFile != null) {
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }

    private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);

        if (isExternalStorageWritable() && !storageDir.isDirectory()) {
            storageDir.mkdirs();
        }

        File image = File.createTempFile(imageFileName, ".jpg", storageDir);
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        showPicture();
    }
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >
    <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/TextToSend" android:layout_gravity="center_horizontal"/>
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Send to another activity"
            android:id="@+id/SendBtn" android:layout_gravity="center_horizontal"/>
</LinearLayout>

second.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:id="@+id/TextDestination" android:layout_gravity="center_horizontal"/>
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Go Back To Main Activity"
            android:id="@+id/GoBackBtn" android:layout_gravity="center_horizontal" android:onClick="onBtnClick"/>
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Take Picture"
            android:id="@+id/button" android:layout_gravity="center_horizontal" android:onClick="onTakePhotoBtnClick"/>
    <ImageView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/imageView" android:layout_gravity="center_horizontal"/>
</LinearLayout>
\$\endgroup\$
3
\$\begingroup\$

There is just a couple of small things you can improve on but mostly are personal preferences.

The first thing that you should do is getting used to have all the string in the strings.xml file in the values folder. This is very useful to keep organized and for localization.

Ids of elements in the xml often go in the format camelCase, like in imageView. If you don't like it I suggest at least sticking to one version.

I suggest avoiding using very short names (like v for the Views) as variable names. In long methods this could get messy. The only case where I see it reasonable is for the index in a loop.

In the xml fill_parent has been deprecated since API 8, you should use match_parent everywhere.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.