如何解决Android中的相机预览和GPS读取
| 我试图编写一个Android应用程序。现在,我编写了一些代码,这些代码可以显示摄像机的预置位并从设备上的传感器(gps接收器)获取数据。 当我在单独的应用程序中运行代码时(例如将摄像头预览作为一个应用程序运行,而将gps数据作为第二个应用程序运行),一切正常。但是,当我尝试集成这两个模块时-GPS停止工作;看来侦听器未获取任何数据,而且由于我正在模拟器上进行尝试,因此出于这个原因,我用一个值初始化了纬度和经度,以便在未接收到位置的情况下不会给出null 。 该应用程序应以以下方式运行:单击照片并将其保存到sdcard的同时,我应该同时获取设备的gps位置,这也需要保存到sd卡中。一些类似的问题? 代码如下: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,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,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,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();
}
}
cameraPreview代码如下所示:
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 CameraSurface(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);
}
},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;
}}
清单文件的外观如下:
<?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\" />
任何帮助,将不胜感激..
解决方法
如果我错了,请纠正我,但是您第一次单击图片时明确停止了位置更新
mLocationManager.removeUpdates(mlocListener);
在回调onJpegPictureTaken()
同样,getLastKnownLocation()将给出最后的缓存位置,而不是最新的位置。您需要单次拍摄模式。
甚至更多信息:您可以在相机中启用一些设置,通过该设置可以对图片进行地理标记。无需亲自学习,就可以阅读Jpeg元数据。
, 根据我的理解,您想要的是Camera应用程序,该应用程序可以生成经地理标记(经纬度/经长写)的jpeg图像。这是如何实现它的代码。
AndroidManifest.xml中所需的权限是
<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>
这是活动文件
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);
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);
}}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。