I tried to write an android app. For now I wrote some code that display camera prewiew and gets data from sensors on the device (gps reciver).
When I run the code in separate app (like camera preview as one app and application that gets gps data as a second) everything is OK. But when I try to integrate this two modules - GPS stop working; it looks like the listener doesn't get any data and moreover as i am trying it on the emulator so for that reason i have initialized the latitude and longitude with a value so that in case a location is not recieved it does not give null.
The app should function in a way that as soon as the photograph is clicked and saved to the sdcard ,at the very same time i should get the gps location of the device which would also be needed to save on the sd card.Did You had some similar problems?
The code looks like this:
public class MainActivity extends Activity implements CameraCallback{
private FrameLayout cameraholder = null;
private CameraSurface camerasurface = null;
LocationManager mLocationManager;
LocationListener mlocListener;
Double lat;
Double lng;
/* Class My Location Listener */
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location loc)
{
String Text = "My current location is:\n" + "Latitude = " + loc.getLatitude() + "\nLongitude = " + loc.getLongitude()+ "\nAccuracy = "+ loc.getAccuracy();
Toast.makeText(MainActivity.this,Text,Toast.LENGTH_SHORT).show();
}
public void onProviderDisabled(String provider)
{
Toast.makeText(MainActivity.this,"Gps Disabled",Toast.LENGTH_SHORT ).show();
}
public void onProviderEnabled(String provider)
{
/*Toast.makeText(getApplicationContext(),"Gps Enabled",Toast.LENGTH_SHORT).show();*/
Toast.makeText(MainActivity.this,"Gps Enabled",Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras){}
{
Toast.makeText(MainActivity.this, "Provider status changed",Toast.LENGTH_LONG).show();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cameraholder = (FrameLayout)findViewById(R.id.camera_preview);
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
setupPictureMode();
((ImageButton)findViewById(R.id.takepicture)).setOnClickListener(onButtonClick);
((ImageButton)findViewById(R.id.about)).setOnClickListener(onButtonClick);
}
private void setupPictureMode(){
camerasurface = new CameraSurface(this);
cameraholder.addView(camerasurface, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
camerasurface.setCallback(this);
}
@Override
public void onJpegPictureTaken(byte[] data, Camera camera) {
try
{
long currentTime = System.currentTimeMillis();
FileOutputStream outStream = new FileOutputStream(String.format(
"/sdcard/%d.jpg",currentTime));
outStream.write(data);
outStream.close();
//mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
/*mlocListener = new MyLocationListener();
mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);*/
Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null) {
lat = 13.6972 * 1E6;
lng = 100.5150 * 1E6;
} else { // get real location if can retrieve the location sent by DDMS or GPS
lat = location.getLatitude() * 1E6;
lng = location.getLongitude() * 1E6;
}
//GeoPoint point = new GeoPoint(lat.intValue(), lng.intValue());
System.out.println("Latitude is :"+lat+" Logitude is "+lng);
mLocationManager.removeUpdates(mlocListener);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
camerasurface.startPreview();
}
}
The cameraPreview code looks like:
public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback, OnGestureListener{
private Camera camera = null;
private SurfaceHolder holder = null;
private CameraCallback callback = null;
private GestureDetector gesturedetector = null;
public Cam开发者_如何学CeraSurface(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
initialize(context);
}
public CameraSurface(Context context)
{
super(context);
initialize(context);
}
public CameraSurface(Context context, AttributeSet attrs)
{
super(context, attrs);
initialize(context);
}
private void initialize(Context context)
{
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
gesturedetector = new GestureDetector(this);
}
public void setCallback(CameraCallback callback){
this.callback = callback;
}
public void startPreview(){
camera.startPreview();
}
public void startTakePicture(){
camera.autoFocus(new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
takePicture();
}
});
}
public void takePicture() {
camera.takePicture(
new ShutterCallback() {
@Override
public void onShutter(){
if(null != callback) callback.onShutter();
}
},
new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera){
if(null != callback) callback.onRawPictureTaken(data, camera);
}
},
new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera){
if(null != callback) callback.onJpegPictureTaken(data, camera);
}
});
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
if(null != camera)
{
camera.startPreview();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if(null != callback) callback.onPreviewFrame(data, camera);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}}
The manifest file looks this way:
<?xml version="1.0" encoding="utf-8"?>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="com.varma.samples.camera.ui.MainActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="10" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Any help would be appreciated..
Correct me if I'm wrong but you are explicitly stopping location updates the first time you click a picture
mLocationManager.removeUpdates(mlocListener);
in the callback onJpegPictureTaken()
Also getLastKnownLocation() will give the last cached location, not the latest one. You require the single shot mode.
Even more info: You can enable some setting in your camera with which the picture is geotagged with the lat-lon. Instead of getting the lat-lon yourself read the Jpeg metadata.
As per my understanding what you want is Camera application which produces geotagged(lat/long written) jpeg image. Here is the code for how you can achive it.
Permission needed in AndroidManifest.xml are
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.CAMERA" >
</uses-permission>
Here is Activity file
public class TaggedImageActivity extends Activity implements SurfaceHolder.Callback, OnClickListener{
static final int FOTO_MODE = 0;
private LocationManager locationManager;
private SurfaceView surefaceView;
private SurfaceHolder surefaceHolder;
private LocationListener locationListener;
private Camera camera;
private String make;
private String model;
private String imei;
private Location thislocation;
double lat ;
double lon ;
private boolean previewRunning = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
surefaceView = (SurfaceView) findViewById(R.id.surface_camera);
surefaceView.setOnClickListener(this);
surefaceHolder = surefaceView.getHolder();
surefaceHolder.addCallback(this);
surefaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
locationListener = new LocationListener() {
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
public void onLocationChanged(Location location) {
TaggedImageActivity.this.gpsLocationReceived(location);
lat = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getLatitude();
lon = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getLongitude();
}
};
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria locationCritera = new Criteria();
locationCritera.setAccuracy(Criteria.ACCURACY_COARSE);
locationCritera.setAltitudeRequired(false);
locationCritera.setBearingRequired(false);
locationCritera.setCostAllowed(true);
locationCritera.setPowerRequirement(Criteria.NO_REQUIREMENT);
String providerName = locationManager.getBestProvider(locationCritera, true);
if (providerName != null && locationManager.isProviderEnabled(providerName)) {
locationManager.requestLocationUpdates(providerName, 20000, 100, TaggedImageActivity.this.locationListener);
} else {
// Provider not enabled, prompt user to enable it
Toast.makeText(TaggedImageActivity.this, R.string.please_turn_on_gps, Toast.LENGTH_LONG).show();
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
TaggedImageActivity.this.startActivity(myIntent);
}
if(locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)!=null){
lat = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER).getLatitude();
lon = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER).getLongitude();
}
else if (locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)!=null){
Log.d("TAG", "Inside NETWORK");
lat = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getLatitude();
lon = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getLongitude();
}
else{
Log.d("TAG", "else +++++++ ");
lat = -1;
lon = -1;
}
}
protected void gpsLocationReceived(Location location) {
thislocation = location;
}
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){
@Override
public void onAutoFocus(boolean arg0, Camera arg1) {
Toast.makeText(getApplicationContext(), "'It is ready to take the photograph !!!", Toast.LENGTH_SHORT).show();
}};
Camera.PictureCallback pictureCallBack = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if(data != null){
Intent imgIntent = new Intent();
storeByteImage(data);
camera.startPreview();
setResult(FOTO_MODE, imgIntent);
}
}
};
public boolean storeByteImage(byte[] data){
String filename = Environment.getExternalStorageDirectory()+String.format("/%d.jpeg", System.currentTimeMillis());
Log.d("TAG", "filename = "+ filename);
try {
FileOutputStream fileOutputStream = new FileOutputStream(filename);
try {
fileOutputStream.write(data);
Log.d("TAG", "Image file created, size in bytes = "+ data.length);
} catch (IOException e) {
e.printStackTrace();
}
fileOutputStream.flush();
fileOutputStream.close();
Log.e("TAG", "lat ="+ lat+" lon :"+ lon);
ExifInterface exif = new ExifInterface(filename);
createExifData(exif,lat , lon);
exif.saveAttributes();
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null,null);
while (cursor.moveToNext()) {
String imagefilename = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
Long latitide = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.LATITUDE));
Long longitude = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.LONGITUDE));
Log.d("TAG", "filepath: "+imagefilename+" latitude = "+latitide+" longitude = "+longitude);
}
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public void createExifData(ExifInterface exif, double lattude, double longitude){
if (lattude < 0) {
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "S");
lattude = -lattude;
} else {
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "N");
}
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE,
formatLatLongString(lattude));
if (longitude < 0) {
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "W");
longitude = -longitude;
} else {
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "E");
}
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE,
formatLatLongString(longitude));
try {
exif.saveAttributes();
} catch (IOException e) {
e.printStackTrace();
}
make = android.os.Build.MANUFACTURER; // get the make of the device
model = android.os.Build.MODEL; // get the model of the divice
exif.setAttribute(ExifInterface.TAG_MAKE, make);
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
imei = telephonyManager.getDeviceId();
exif.setAttribute(ExifInterface.TAG_MODEL, model+" - "+imei);
exif.setAttribute(ExifInterface.TAG_DATETIME, (new Date(System.currentTimeMillis())).toString()); // set the date & time
Log.d("TAG", "Information : lat ="+ lattude+" lon ="+ longitude+" make = "+make+" model ="+ model+" imei="+imei+" time ="+(new Date(System.currentTimeMillis())).toString());
}
private static String formatLatLongString(double d) {
StringBuilder b = new StringBuilder();
b.append((int) d);
b.append("/1,");
d = (d - (int) d) * 60;
b.append((int) d);
b.append("/1,");
d = (d - (int) d) * 60000;
b.append((int) d);
b.append("/1000");
return b.toString();
}
protected boolean isRouteDisplayed() {
return false;
}
@Override
public void onClick(View v) {
camera.takePicture(null, pictureCallBack, pictureCallBack);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if(previewRunning){
camera.stopPreview();
}
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
previewRunning = true;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
previewRunning = false;
camera.release();
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.cameramenu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item01:
Toast.makeText(this, "Pressed !", Toast.LENGTH_LONG).show(); break;
case R.id.item03:
System.exit(0);
break;
}
return true;
}
@Override
protected void onStop() {
super.onStop();
LocationManager locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(this.locationListener);
}}
精彩评论