Java tutorial
/****************************************************************************** * Project: NextGIS mobile * Purpose: Mobile GIS for Android. * Author: Dmitry Baryshnikov (aka Bishop), polimax@mail.ru ****************************************************************************** * Copyright (C) 2012-2013 NextGIS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ****************************************************************************/ package com.nextgis.mobile.forms; import java.io.File; import java.io.IOException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.location.Location; import android.location.LocationManager; import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.support.v4.app.Fragment; import android.util.Log; import android.view.Display; import android.view.LayoutInflater; import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ListView; import android.widget.SimpleAdapter; import com.nextgis.mobile.InputPointActivity; import com.nextgis.mobile.R; import static com.nextgis.mobile.util.Constants.*; public class CameraFragment extends Fragment { private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 7; private String fileName; private File imgFile; private SensorManager sensorManager; private float declination; protected Location currentLocation; protected Map<Long, Float> mAngles = new HashMap<Long, Float>(); private ArrayList<HashMap<String, Object>> listItems = new ArrayList<HashMap<String, Object>>(); private static final String IMG_NAME = "image_name"; private static final String IMG_ROT = "image_rotation"; //DEFINING STRING ADAPTER WHICH WILL HANDLE DATA OF LISTVIEW private SimpleAdapter adapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { setRetainInstance(true); View view = inflater.inflate(R.layout.camfragment, container, false); Button button = (Button) view.findViewById(R.id.insert_take_photo); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { onCapturePhoto(); } }); ListView photoList = (ListView) view.findViewById(R.id.poi_photos_list); adapter = new SimpleAdapter(view.getContext(), listItems, R.layout.row, new String[] { IMG_NAME, IMG_ROT, }, new int[] { R.id.image_name, R.id.image_rotation }); photoList.setAdapter(adapter); final LocationManager locationManager = (LocationManager) getActivity() .getSystemService(Context.LOCATION_SERVICE); if (currentLocation == null) { currentLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (currentLocation == null) { currentLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } } long now = System.currentTimeMillis(); declination = CompassFragment.getDeclination(currentLocation, now); sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); return view; } public void onStoreValues() { if (getView() != null) { InputPointActivity activity = (InputPointActivity) getActivity(); if (activity == null) return; //if (getView().findViewById(R.id.poi_notes_text) != null) { // activity.SetNotes(((TextView) getView().findViewById(R.id.poi_notes_text)).getText().toString()); //} } //UpdateSummary(); } private Uri getOutputMediaFileUri() { return Uri.fromFile(getOutputMediaFile()); } private File getOutputMediaFile() { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES), ""); // Create the storage directory if it does not exist if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d(TAG, "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); fileName = "IMG_" + timeStamp + ".jpg"; imgFile = new File(mediaStorageDir, fileName); return imgFile; } private Date stringToDate(String aDate, String aFormat) { if (aDate == null) return null; ParsePosition pos = new ParsePosition(0); SimpleDateFormat simpledateformat = new SimpleDateFormat(aFormat); Date stringDate = simpledateformat.parse(aDate, pos); return stringDate; } protected SensorEventListener sensorListener = new SensorEventListener() { public void onSensorChanged(SensorEvent event) { //long stamp = event.timestamp; long stamp = System.currentTimeMillis(); float dfAz = event.values[0] + declination + CameraFragment.this.getDeviceRotation(); mAngles.put(stamp, dfAz); /* if(mAngles.size() > 5000) { Set set = mAngles.keySet(); Iterator itr = set.iterator(); while(itr.hasNext()){ if(mAngles.size() < 5000) break; itr.remove(); } } //bundle.putFloat("pitch", event.values[1]); //bundle.putFloat("roll", event.values[2]); */ } public void onAccuracyChanged(Sensor arg0, int arg1) { } }; public int getDeviceRotation() { if (getActivity() == null) return 0; if (getActivity().getWindowManager() == null) return 0; Display display = getActivity().getWindowManager().getDefaultDisplay(); if (display != null) { if (display.getRotation() == Surface.ROTATION_90) { return 90; } else if (display.getRotation() == Surface.ROTATION_180) { return 180; } else if (display.getRotation() == Surface.ROTATION_270) { return 270; } } return 0; } public void onCapturePhoto() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri fileUri = getOutputMediaFileUri(); // create a file to save the image intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name mAngles.clear(); sensorManager.registerListener(sensorListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL); // start the image capture Intent startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); sensorManager.unregisterListener(sensorListener); if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE && resultCode == Activity.RESULT_OK) { //add angle float dfAngle = 0; try { ExifInterface exif = new ExifInterface(imgFile.getPath()); String sDate = exif.getAttribute(ExifInterface.TAG_DATETIME); Date datetime = stringToDate(sDate, "yyyy:MM:dd HH:mm:ss"); Log.d(TAG, "image date: " + datetime.toString()); long testMilli = datetime.getTime(); long nDif = 1000000; for (long n : mAngles.keySet()) { long nDifTmp = Math.abs(testMilli - n); if (nDifTmp < nDif) { nDif = nDifTmp; dfAngle = (Float) mAngles.get(n); } } Log.d(TAG, "image angle: " + dfAngle); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } String listItem; if (data != null) { Uri outPath = data.getData(); listItem = outPath.getLastPathSegment(); } else { listItem = fileName; } HashMap<String, Object> hm = new HashMap<String, Object>(); hm.put(IMG_NAME, listItem); String sAngle = CompassFragment.formatNumber(dfAngle, 0, 0) + CompassFragment.DEGREE_CHAR + " " + CompassFragment.getDirectionCode(dfAngle, getResources()); hm.put(IMG_ROT, sAngle); listItems.add(hm); adapter.notifyDataSetChanged(); InputPointActivity activity = (InputPointActivity) getActivity(); if (activity == null) return; activity.AddImage(listItem, dfAngle); } } }