2011-06-15 88 views
1

我試圖編寫一個android應用程序。現在我寫了一些代碼來顯示相機預覽,並從設備上的傳感器(gps reciver)獲取數據。Android中的攝像頭預覽和GPS讀取

當我在單獨的應用程序中運行代碼(如相機預覽作爲一個應用程序和獲取gps數據作爲第二個應用程序),一切正常。但是,當我嘗試整合這兩個模塊 - GPS停止工作;它看起來像監聽器沒有得到任何數據,而且我正在模擬器上嘗試它,所以出於這個原因我已經初始化了經度和緯度的值,以便在沒有收到位置的情況下它不會給出空值。

該應用程序應該以一種方式運行,只要照片被點擊並保存到SD卡,同時我應該得到設備的GPS位置,這也將需要保存在SD卡上.Did你有類似的問題嗎?

的代碼看起來是這樣的:

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(); 
    } 

} 

的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); 
       } 
      }, 
      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; 
}} 

清單文件看起來是這樣的:

<?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" /> 

任何幫助,將不勝感激..

回答

0

糾正我,如果我錯了,但你被明確停止位置更新第一次單擊回調圖片

mLocationManager.removeUpdates(mlocListener); 

onJpegPictureTaken ()

另外,getLastKnownLocation()將給出最後一個緩存的位置,而不是最新的位置。您需要單拍模式。

更多信息:您可以在相機中啓用一些設置,使用經緯度對圖片進行地理標記。而不是自己閱讀經緯度閱讀Jpeg metadata

+0

可能你是對的裏諾我會嘗試刪除該語句。而且最主要的問題是我不也可以看到Println語句,正如你在OnJpegPictureTaken()中看到的那樣,我正在初始化lat和long的值,以便我得到一些東西,即使它沒有使用gps位置。 – 2011-06-15 13:30:57

0

根據我的理解,你想要的是產生地理標記(經緯度/長寫)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, 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); 
}}