0

I've written an application which should take picture and record video and then show it on the screen. When trying it on phone the camera won't work but works in emulator.

When executing the app this is what exactly happens:

Every time I clicked on the button to open the camera, the app stopped and the error it display is Appname has stopped, Open app again

When I clicked on Open app again it return to normal state

I have granted the camera permission in my program

below is my code:

public class EventActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
    public static final String KEY_MENU_TYPE = "menutype";
    //public static final String KEY_PREF_USER_DETAILS = "prefUserDetails";
    private static final String TAG = EventActivity.class.getSimpleName();

    private static final String SERVER_IMAGE_PATH = "http://edo.com/imageupload/";
    private static final String SERVER_PATH = "http://edo.com/";

    String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};

    private GoogleApiClient mGoogleApiClient;

    private Location mLastLocation;
    private LocationRequest mLocationRequest;

    private EditText event, eventDescription, name;
    private TextView attachmentStatus;

    private static final int TAKE_PICTURE = 1;
    private static final int PERMISSION_ALL = 3;

    private Uri capturedImageUri;
    private Uri videoUri;
    private String mediaFile;
    private String videoFile;

    private static final int MY_SOCKET_TIMEOUT_MS = 5000;
    private String[] serverData;
    private static final int REQUEST_VIDEO_CAPTURE = 300;

    private boolean isImage;
    private String locationResult;
    String menutype = "";


 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
        Intent intent = getIntent();
       /* ActionBar mBar = getSupportActionBar();
        if(mBar != null){
            mBar.setDisplayHomeAsUpEnabled(true);
        }*/

        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addApi(LocationServices.API)
                    .build();
        }
        mLocationRequest = createLocationRequest();

        Button photoVideoButton = (Button)findViewById(R.id.take_image_video);
        photoVideoButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showOptionDialog();
            }
        });
        attachmentStatus = (TextView)findViewById(R.id.file_status);
        event = (EditText)findViewById(R.id.enter_event);
        eventDescription =(EditText)findViewById(R.id.enter_event_description);
        name = (EditText)findViewById(R.id.name);

        Button cancelUploadButton = (Button) findViewById(R.id.cancel_upload);
        assert cancelUploadButton != null;
        cancelUploadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                resetViewControls();
            }
        });

        Button sendToServerButton = (Button) findViewById(R.id.send_to_server);
        assert sendToServerButton != null;
        sendToServerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String eventValue = event.getText().toString().trim();
                String eventDescriptionValue = eventDescription.getText().toString();
                String nameValue = name.getText().toString();
                String locationValue = "";

                if(TextUtils.isEmpty(eventValue) || TextUtils.isEmpty(eventDescriptionValue) || TextUtils.isEmpty(nameValue)){
                    Toast.makeText(EventActivity.this, getString(R.string.send_to_server_error), Toast.LENGTH_LONG).show();
                    return;
                }

                if(locationResult == null || locationResult.equals("")){
                    locationValue = "";
                }else{
                    locationValue = locationResult;
                }

                if(TextUtils.isEmpty(mediaFile) && TextUtils.isEmpty(videoFile)){
                    Toast.makeText(EventActivity.this, "Please attach a photo or video", Toast.LENGTH_LONG).show();
                    return;
                }

                if(!TextUtils.isEmpty(mediaFile) && isImage){
                    // send the information to remote server
                    Bitmap storeBitmap = BitmapFactory.decodeFile(mediaFile);
                    Bitmap resizedBitmap = Bitmap.createScaledBitmap(storeBitmap, 640, 420, true);
                    String imageBasedString = convertBitmapToBaseImageString(resizedBitmap);

                    serverData = new String[]{eventValue, eventDescriptionValue, nameValue, imageBasedString, locationValue};
                    sendCapturedImageToServer(serverData);

                    //move stored video to a new folder
                    String photoPath = getMovedFilePath(mediaFile, eventValue);
                    moveFileToNewDestination(mediaFile, photoPath);

                }else if(!TextUtils.isEmpty(mediaFile) && !isImage){

                    //Store the video to your server
                    uploadVideoToServer(videoFile, eventValue, eventDescriptionValue, nameValue, locationValue);
                    //move stored video to a new folder
                    String photoPath = getMovedFilePath(videoFile, eventValue);
                    moveFileToNewDestination(videoFile, photoPath);

                }else{
                    // Image or video is missing. Show message to user
                    Toast.makeText(EventActivity.this, getString(R.string.upload_image_or_video), Toast.LENGTH_LONG).show();
                }
            }
        });


        this.menutype = intent.getStringExtra(KEY_MENU_TYPE);
        if (this.menutype == null) {
            this.menutype = "";
        }
    }


    public void goBack(View view) {
        Intent intent;
        if (this.menutype.equals("PRE")) {
            intent = new Intent(this, PreElectionMenuActivity.class);
        } else if (this.menutype.equals("ACC")) {
            intent = new Intent(this, AccreditationMenuActivity.class);
        } else if (this.menutype.equals("ELE")) {
            intent = new Intent(this, VotingMenuActivity.class);
        } else if (this.menutype.equals("INC")) {
            intent = new Intent(this, IncidentMenuActivity.class);
        } else {
            intent = new Intent(this, HomeActivity.class);
        }
        startActivity(intent);
    }

    private String getMovedFilePath(String filePath, String eventName){
        int indexPosition = filePath.lastIndexOf(".");
        String fileExtension = filePath.substring(indexPosition, filePath.length());
        String newFilename = eventName + fileExtension;
        return getFileDestinationPath(newFilename);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == TAKE_PICTURE) {
                capturedImageUri = data.getData();

                if (!hasPermissions(this, PERMISSIONS)){
                    ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
                }else {
                    mediaFile = "";
                    mediaFile = getRealPathFromURIPath(capturedImageUri, EventActivity.this);
                    Log.d(TAG, "Capture image path" + mediaFile);
                    attachmentStatus.setText("Image file has been attached");
                    isImage = true;
                }
            }
            if (requestCode == REQUEST_VIDEO_CAPTURE) {
                videoUri = data.getData();

                if (!hasPermissions(this, PERMISSIONS)){
                    ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
                }else{
                    videoFile = getRealPathFromURIPath(videoUri, EventActivity.this);
                    Log.d(TAG, "Captured video path " + videoUri);
                    Log.d(TAG, "New path " + videoFile);
                    attachmentStatus.setText("Video file has been attached");
                    isImage = false;
                }
            }
        }
    }

    private void resetViewControls(){
        event.setText("");
        eventDescription.setText("");
        name.setText("");
        attachmentStatus.setText(R.string.attached_file);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(capturedImageUri != null){
            if (!hasPermissions(this, PERMISSIONS)){
                ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
            }else {
                mediaFile = getRealPathFromURIPath(capturedImageUri, EventActivity.this);
            }
        }
    }

    private String getRealPathFromURIPath(Uri contentURI, Activity activity) {
        Cursor cursor = activity.getContentResolver().query(contentURI, null, null, null, null);
        if (cursor == null) {
            return contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            return cursor.getString(idx);
        }
    }

    private String convertBitmapToBaseImageString(Bitmap bitmap){
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream);
        byte[] byte_arr = stream.toByteArray();
        return Base64.encodeToString(byte_arr, 0);
    }

    private void sendCapturedImageToServer(String[] photoDetails){
        Map<String, String> params = new HashMap<String,String>();
        params.put("EVENT", photoDetails[0]);
        params.put("EVENT_DESCRIPTION", photoDetails[1]);
        params.put("NAME", photoDetails[2]);
        params.put("CAPTURE_IMAGE", photoDetails[3]);
        params.put("EVENT_LOCATION", photoDetails[4]);

        GsonRequest<ServerObject> serverRequest = new GsonRequest<ServerObject>(
                Request.Method.POST,
                SERVER_IMAGE_PATH,
                ServerObject.class,
                params,
                createRequestSuccessListener(),
                createRequestErrorListener());

        serverRequest.setRetryPolicy(new DefaultRetryPolicy(
                MY_SOCKET_TIMEOUT_MS,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        VolleySingleton.getInstance(EventActivity.this).addToRequestQueue(serverRequest);
    }

    private Response.Listener<ServerObject> createRequestSuccessListener() {
        return new Response.Listener<ServerObject>() {
            @Override
            public void onResponse(ServerObject response) {
                try {
                    Log.d(TAG, "Json Response " + response.getSuccess());
                    if(!TextUtils.isEmpty(response.getSuccess()) && response.getSuccess().equals("1")){
                        Toast.makeText(EventActivity.this, getString(R.string.successful_upload), Toast.LENGTH_LONG).show();
                        resetViewControls();
                    }else{
                        Toast.makeText(EventActivity.this, getString(R.string.server_error), Toast.LENGTH_LONG).show();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
        };
    }

    private Response.ErrorListener createRequestErrorListener() {
        return new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        };
    }

    public static void getAddressFromLocation(final double lat, final double lon, final Context context, final Handler handler) {
        Thread thread = new Thread() {
            @Override public void run() {
                Geocoder geocoder = new Geocoder(context, Locale.getDefault());
                String result = null;
                try {
                    List<Address> list = geocoder.getFromLocation(lat, lon, 1);
                    if (list != null && list.size() > 0) {
                        Address address = list.get(0);
                        // sending back first address line and locality
                        result = address.getAddressLine(0) + ", " + address.getLocality() + ", " +  address.getCountryName() ;
                        Log.d(TAG, "The converted Address " + result);
                    }
                } catch (IOException e) {
                    Log.e(TAG, "Impossible to connect to GeoCoder", e);
                } finally {
                    Message msg = Message.obtain();
                    msg.setTarget(handler);
                    if (result != null) {
                        msg.what = 1;
                        Bundle bundle = new Bundle();
                        bundle.putString("address", result);
                        msg.setData(bundle);
                    } else
                        msg.what = 0;
                    msg.sendToTarget();
                }
            }
        };
        thread.start();
    }

    @SuppressLint("HandlerLeak")
    private class GeoCoderHandler extends Handler {
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case 1:
                    Bundle bundle = message.getData();
                    locationResult = bundle.getString("address");
                    Log.d(TAG, "Location Result " + locationResult);
                    break;
                default:
                    locationResult = null;
            }
        }
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
        PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult result) {
                final Status status = result.getStatus();

                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        Log.d(TAG, "Connection method has been called");
                        if(!hasPermissions(EventActivity.this, PERMISSIONS)){
                            ActivityCompat.requestPermissions(EventActivity.this, PERMISSIONS, PERMISSION_ALL);
                        }
                        else{
                            if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                                    && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                                mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                                if(mLastLocation != null){
                                    getAddressFromLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude(), EventActivity.this, new GeoCoderHandler());
                                }
                            }
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        break;
                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_ALL: {
                // If request is cancelled, the result arrays are empty.
                if(grantResults[0] == PackageManager.PERMISSION_DENIED){
                    Toast.makeText(EventActivity.this, "Sorry!!!, you can't use this app without granting this permission", Toast.LENGTH_LONG).show();
                    finish();
                }
                if (grantResults[1] == PackageManager.PERMISSION_DENIED || grantResults[2] == PackageManager.PERMISSION_DENIED) {
                    // permission was denied, show alert to explain permission
                    showPermissionAlert();
                }else{
                    //permission is granted. Get current location values
                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                            && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                    }
                }
            }
        }
    }

    private void showPermissionAlert(){
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.permission_request_title);
        builder.setMessage(R.string.app_permission_notice);
        builder.create();

        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if(!hasPermissions(EventActivity.this, PERMISSIONS)){
                    ActivityCompat.requestPermissions(EventActivity.this, PERMISSIONS, PERMISSION_ALL);
                }
            }
        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(EventActivity.this, R.string.permission_refused, Toast.LENGTH_LONG).show();
            }
        });
        builder.show();
    }

    protected LocationRequest createLocationRequest() {
        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000);
        mLocationRequest.setFastestInterval(3000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        return mLocationRequest;
    }

    @Override
    protected void onStart() {
        mGoogleApiClient.connect();
        super.onStart();
    }

    @Override
    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    public void onConnectionSuspended(int i) {
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    public static boolean hasPermissions(Context context, String... permissions) {
        if (android.os.Build.VERSION.SDK_INT >= M && context != null && permissions != null) {
            for (String permission : permissions) {
                if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
        }
        return true;
    }

    private boolean isLocationEnabled(){
        LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        try {
            gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        }catch (Exception ex){}
        try{
            network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        }catch (Exception ex){}
        if(!gps_enabled && !network_enabled){
            return false;
        }
        return true;
    }

    private void showLocationAlert(){
        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setMessage(getResources().getString(R.string.gps_enable));
        dialog.setPositiveButton(getResources().getString(R.string.network_location), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                EventActivity.this.startActivity(myIntent);
            }
        });
        dialog.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
            }
        });
        dialog.show();
    }

    private void moveFileToNewDestination(String fromPath, String toPath){
        File fromFile = new File(fromPath);
        File toFile = new File(toPath);
        if(!toFile.exists()){
            try {
                toFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        FileInputStream fromStream = null;
        FileOutputStream toStream = null;

        try {
            fromStream = new FileInputStream(fromFile);
            toStream = new FileOutputStream(toFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        byte[] sourceByte = new byte[1024];
        int index;
        try {
            while((index = fromStream.read(sourceByte)) > 0){
                if (toStream != null) {
                    toStream.write(sourceByte, 0, index);
                }
            }
            Log.d(TAG, "Video successfully moved to a new location");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getFileDestinationPath(String filename){
        String filePathEnvironment = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
        File directoryFolder = new File(filePathEnvironment + "/events/");
        if(!directoryFolder.exists()){
            directoryFolder.mkdir();
        }
        Log.d(TAG, "Full path " + filePathEnvironment + "/events/" + filename);
        return filePathEnvironment + "/events/" + filename;
    }

    private void uploadVideoToServer(String pathToVideoFile, String eventName, String eventDescription, String eventCoverage, String eventLocation){

        File videoFile = new File(pathToVideoFile);
        RequestBody videoBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
        MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody);

        RequestBody event = RequestBody.create(MediaType.parse("text/plain"), eventName);
        RequestBody description = RequestBody.create(MediaType.parse("text/plain"), eventDescription);
        RequestBody name = RequestBody.create(MediaType.parse("text/plain"), eventCoverage);
        RequestBody location = RequestBody.create(MediaType.parse("text/plain"), eventLocation);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(SERVER_PATH)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        VideoInterface vInterface = retrofit.create(VideoInterface.class);
        Call<ResultObject> serverCom = vInterface.uploadVideoToServer(vFile, event, description, name, location);
        serverCom.enqueue(new Callback<ResultObject>() {
            @Override
            public void onResponse(Call<ResultObject> call, retrofit2.Response<ResultObject> response) {
                ResultObject result = response.body();
                if(!TextUtils.isEmpty(result.getSuccess()) && result.getSuccess().equals("1")){
                    Toast.makeText(EventActivity.this, getString(R.string.successful_upload), Toast.LENGTH_LONG).show();
                    resetViewControls();
                }else{
                    Toast.makeText(EventActivity.this, getString(R.string.server_error), Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<ResultObject> call, Throwable t) {
                Log.d(TAG, "Error message " + t.getMessage());
            }
        });
    }

    private void showOptionDialog(){
        final Dialog dialog = new Dialog(EventActivity.this);
        dialog.setTitle("SELECT ACTION TO COMPLETE");
        dialog.setContentView(R.layout.image_video_layout);

        final TextView takePhoto = (TextView)dialog.findViewById(R.id.take_photo);
        final TextView recordVideo = (TextView)dialog.findViewById(R.id.record_video);

        dialog.show();

        takePhoto.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Log.d(TAG, "Take a picture");
                if(isLocationEnabled()){
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(intent, TAKE_PICTURE);
                }else{
                    showLocationAlert();
                }
                dialog.dismiss();
            }
        });

        recordVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "Record a video");
                Intent videoCaptureIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                if(videoCaptureIntent.resolveActivity(getPackageManager()) != null){
                    startActivityForResult(videoCaptureIntent, REQUEST_VIDEO_CAPTURE);
                }
                dialog.dismiss();
            }
        });
    }

    private boolean gps_enabled;
    private boolean network_enabled;
Tonye Boro
  • 313
  • 4
  • 15

0 Answers0