2016年11月27日 星期日

Ref :  https://read01.com/NkD6Q0.html

從2013年開始ldpi mdpi hdpi相繼退出了歷史舞台!以1280*720的720P主要機型占據了主流,即xhdpi。
2015年預計將會是1080P的天下了,因為從14年下半年到2015年推出的android手機均為1080P,可以預見未來的趨勢!
以下是當前android主要機型規範:
手機常見解析度:

原文網址:https://read01.com/NkD6Q0.html

2016年11月1日 星期二

video preview sample

Ref :  https://developer.android.com/guide/topics/media/camera.html#custom-camera


add preview data
Ref : https://nidesai.wordpress.com/2013/09/22/android-camera-capturing-raw-video-frames/


draw text on camera preview
Ref :  http://seshadripera.blogspot.tw/2013/04/how-to-draw-overlay-on-surfaceview-used.html

Detecting camera hardware

If your application does not specifically require a camera using a manifest declaration, you should check to see if a camera is available at runtime. To perform this check, use the PackageManager.hasSystemFeature() method, as shown in the example code below:
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}


Android devices can have multiple cameras, for example a back-facing camera for photography and a front-facing camera for video calls. Android 2.3 (API Level 9) and later allows you to check the number of cameras available on a device using the Camera.getNumberOfCameras() method.

Accessing cameras

If you have determined that the device on which your application is running has a camera, you must request to access it by getting an instance of Camera (unless you are using an intent to access the camera).
To access the primary camera, use the Camera.open() method and be sure to catch any exceptions, as shown in the code below:
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}
Caution: Always check for exceptions when using Camera.open(). Failing to check for exceptions if the camera is in use or does not exist will cause your application to be shut down by the system.
On devices running Android 2.3 (API Level 9) or higher, you can access specific cameras using Camera.open(int). The example code above will access the first, back-facing camera on a device with more than one camera.

Checking camera features


Once you obtain access to a camera, you can get further information about its capabilities using the Camera.getParameters() method and checking the returned Camera.Parameters object for supported capabilities. When using API Level 9 or higher, use the Camera.getCameraInfo() to determine if a camera is on the front or back of the device, and the orientation of the image.

Creating a preview class

For users to effectively take pictures or video, they must be able to see what the device camera sees. A camera preview class is a SurfaceView that can display the live image data coming from a camera, so users can frame and capture a picture or video.
The following example code demonstrates how to create a basic camera preview class that can be included in a View layout. This class implements SurfaceHolder.Callback in order to capture the callback events for creating and destroying the view, which are needed for assigning the camera preview input.
  private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

If you want to set a specific size for your camera preview, set this in the surfaceChanged() method as 
noted in the comments above. When setting preview size, you must use values 
from getSupportedPreviewSizes()Do not set arbitrary values in the setPreviewSize() method.

Placing preview in a layout

A camera preview class, such as the example shown in the previous section, must be placed in the 
layout of an activity along with other user interface controls for taking a picture or video. This section 
shows you how to build a basic layout and activity for the preview.
The following layout code provides a very basic view that can be used to display a camera preview. In 
this example, the FrameLayout element is meant to be the container for the camera preview class. This 
layout type is used so that additional picture information or controls can be overlayed on the live 
camera preview images.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

On most devices, the default orientation of the camera preview is landscape. This example layout 
specifies a horizontal (landscape) layout and the code below fixes the orientation of the application to 
landscape. For simplicity in rendering a camera preview, you should change your application's preview 
activity orientation to landscape by adding the following to your manifest.
<activity android:name=".CameraActivity"
          android:label="@string/app_name"

          android:screenOrientation="landscape">
          <!-- configure this activity to use landscape orientation -->

          <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Note: A camera preview does not have to be in landscape mode. Starting in Android 2.2 (API Level 8), you can use the setDisplayOrientation()method to set the rotation of the preview image. In order to change preview orientation as the user re-orients the phone, within the surfaceChanged() method of your preview class, first stop the preview with Camera.stopPreview() change the orientation and then start the preview again with Camera.startPreview().
In the activity for your camera view, add your preview class to the FrameLayout element shown in the 
example above. Your camera activity must also ensure that it releases the camera when it is paused or 
shut down. The following example shows how to modify a camera activity to attach the preview class 
public class CameraActivity extends Activity {

    private Camera mCamera;
    private CameraPreview mPreview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create an instance of Camera
        mCamera = getCameraInstance();

        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }
}

ote: The getCameraInstance() method in the example above refers to the example method shown in Accessing cameras.

Capturing pictures

Once you have built a preview class and a view layout in which to display it, you are ready to start 
capturing images with your application. In your application code, you must set up listeners for your user 
interface controls to respond to a user action by taking a picture.
In order to retrieve a picture, use the Camera.takePicture() method. This method takes three 
parameters which receive data from the camera. In order to receive data in a JPEG format, you must 
implement an Camera.PictureCallback interface to receive the image data and write it to a file. The 
following code shows a basic implementation of the Camera.PictureCallback interface to save an 
image received from the camera.

private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: " +
                e.getMessage());
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};














install opencv 310

Ref :  http://blog.csdn.net/bless2015/article/details/52075440


新建项目并装载OpenCV的so库函数


首先,很重要,先导入so库。
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public void onResume() {  
  3.     super.onResume();  
  4.     if (!OpenCVLoader.initDebug()) {  
  5.         Log.d(TAG,  
  6.                 "Internal OpenCV library not found. Using OpenCV Manager for initialization");  
  7.         OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this,  
  8.                 mLoaderCallback);  
  9.     } else {  
  10.         Log.d(TAG, "OpenCV library found inside package. Using it!");  
  11.         mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);  
  12.     }  
  13. }  

因为我用的3.1版本,所以用的这句话OpenCVLoader.OPENCV_VERSION_3_1_0,不同版本直接改后面的_3_1_0就好了(应该是这样,点进代码里简单看了看)。
单独写上边这行代码是报错的,我照着samples里这个项目的代码写的:



Ref :  http://stackoverflow.com/questions/36204781/error-package-android-hardware-camera2-does-not-exist-opencv

Here's the build.gradle file of the OpenCV (3.0) module:
apply plugin: 'com.android.library'

android {
    compileSdkVersion 17
    buildToolsVersion "23.0.2"

defaultConfig {
    minSdkVersion 8
    targetSdkVersion 21
}

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

Change compileSdkVersion 17 to minimum 21 (recommended 24). Because android.hardware.camera2 was added in API 21.





2016年10月16日 星期日

Google map api demo II : CircleDemoActivity 和 SplitStreetViewPanoramaAndMapDemoActivity



public class CircleDemoActivity extends AppCompatActivity implements OnSeekBarChangeListener,
        OnMarkerDragListener, OnMapLongClickListener, OnMapReadyCallback {}

先看   onCreate()


@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.circle_demo);

    mColorBar = (SeekBar) findViewById(R.id.hueSeekBar);
    mColorBar.setMax(HUE_MAX);
    mColorBar.setProgress(0);

    mAlphaBar = (SeekBar) findViewById(R.id.alphaSeekBar);
    mAlphaBar.setMax(ALPHA_MAX);
    mAlphaBar.setProgress(127);

    mWidthBar = (SeekBar) findViewById(R.id.widthSeekBar);
    mWidthBar.setMax(WIDTH_MAX);
    mWidthBar.setProgress(10);

    SupportMapFragment mapFragment =
            (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    mClickabilityCheckbox = (CheckBox) findViewById(R.id.toggleClickability);
}

有三個   colorBar...  和一個CheckBox....

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">

    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:text="@string/properties_circle" />

    <TableLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:stretchColumns="1">// 只有一欄

        <TableRow            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:gravity="center_vertical">

            <TextView android:text="@string/fill_hue" />

            <SeekBar android:id="@+id/hueSeekBar" />
        </TableRow>

        <TableRow            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:gravity="center_vertical">

            <TextView android:text="@string/fill_alpha" />

            <SeekBar android:id="@+id/alphaSeekBar" />
        </TableRow>

        <TableRow            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:gravity="center_vertical">

            <TextView android:text="@string/stroke_width" />

            <SeekBar android:id="@+id/widthSeekBar" />
        </TableRow>

        <TableRow            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:gravity="center_vertical">

            <CheckBox                android:id="@+id/toggleClickability"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:checked="true"                android:onClick="toggleClickability"                android:text="@string/clickable"/>
        </TableRow>

    </TableLayout>

    <fragment        android:id="@+id/map"        android:layout_width="match_parent"        android:layout_height="match_parent"        class="com.google.android.gms.maps.SupportMapFragment"/>

</LinearLayout>


先看  onMapReady()



@Overridepublic void onMapReady(GoogleMap map) {
    mMap = map;

    // Override the default content description on the view, for accessibility mode.    map.setContentDescription(getString(R.string.map_circle_description));

    mColorBar.setOnSeekBarChangeListener(this);
    mAlphaBar.setOnSeekBarChangeListener(this);
    mWidthBar.setOnSeekBarChangeListener(this);
    mMap.setOnMarkerDragListener(this);
    mMap.setOnMapLongClickListener(this);

    mFillColor = Color.HSVToColor(
            mAlphaBar.getProgress(), new float[]{mColorBar.getProgress(), 1, 1});
    mStrokeColor = Color.BLACK;

    DraggableCircle circle =
            new DraggableCircle(SYDNEY, DEFAULT_RADIUS, mClickabilityCheckbox.isChecked());
    mCircles.add(circle);

    // Move the map so that it is centered on the initial circle    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 4.0f));
    // Set up the click listener for the circle.    map.setOnCircleClickListener(new OnCircleClickListener() {
        @Override        public void onCircleClick(Circle circle) {
            // Flip the r, g and b components of the circle's stroke color.            int strokeColor = circle.getStrokeColor() ^ 0x00ffffff;
            circle.setStrokeColor(strokeColor);
        }
    });
}


private class DraggableCircle {
    private final Marker centerMarker;
    private final Marker radiusMarker;
    private final Circle circle;
    private double radius;
    public DraggableCircle(LatLng center, double radius, boolean clickable) {
        this.radius = radius;
        centerMarker = mMap.addMarker(new MarkerOptions()
                .position(center)
                .draggable(true));
        radiusMarker = mMap.addMarker(new MarkerOptions()
                .position(toRadiusLatLng(center, radius))
                .draggable(true)
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_AZURE)));
        circle = mMap.addCircle(new CircleOptions()
                .center(center)
                .radius(radius)
                .strokeWidth(mWidthBar.getProgress())
                .strokeColor(mStrokeColor)
                .fillColor(mFillColor)
                .clickable(clickable));
    }

    public DraggableCircle(LatLng center, LatLng radiusLatLng, boolean clickable) {
        this.radius = toRadiusMeters(center, radiusLatLng);
        centerMarker = mMap.addMarker(new MarkerOptions()
                .position(center)
                .draggable(true));
        radiusMarker = mMap.addMarker(new MarkerOptions()
                .position(radiusLatLng)
                .draggable(true)
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_AZURE)));
        circle = mMap.addCircle(new CircleOptions()
                .center(center)
                .radius(radius)
                .strokeWidth(mWidthBar.getProgress())
                .strokeColor(mStrokeColor)
                .fillColor(mFillColor)
                .clickable(clickable));
    }

    public boolean onMarkerMoved(Marker marker) {
        if (marker.equals(centerMarker)) {
            circle.setCenter(marker.getPosition());
            radiusMarker.setPosition(toRadiusLatLng(marker.getPosition(), radius));
            return true;
        }
        if (marker.equals(radiusMarker)) {
            radius = toRadiusMeters(centerMarker.getPosition(), radiusMarker.getPosition());
            circle.setRadius(radius);
            return true;
        }
        return false;
    }

    public void onStyleChange() {
        circle.setStrokeWidth(mWidthBar.getProgress());
        circle.setFillColor(mFillColor);
        circle.setStrokeColor(mStrokeColor);
    }

    public void setClickable(boolean clickable) {
        circle.setClickable(clickable);
    }
}




當常按時...新增一個circle.....

@Overridepublic void onMapLongClick(LatLng point) {
    // We know the center, let's place the outline at a point 3/4 along the view.    View view = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
            .getView();
    LatLng radiusLatLng = mMap.getProjection().fromScreenLocation(new Point(
            view.getHeight() * 3 / 4, view.getWidth() * 3 / 4));

    // ok create it    DraggableCircle circle =
            new DraggableCircle(point, radiusLatLng, mClickabilityCheckbox.isChecked());
    mCircles.add(circle);   //  新增一個  circles
}


//  當按下   checkbox  -> toggleClickability

public void toggleClickability(View view) {
    boolean clickable = ((CheckBox) view).isChecked();
    // Set each of the circles to be clickable or not, based on the    // state of the checkbox.    for (DraggableCircle draggableCircle : mCircles) {
        draggableCircle.setClickable(clickable);
    }
}



@Overridepublic void onMarkerDragStart(Marker marker) {
    onMarkerMoved(marker);
}

@Overridepublic void onMarkerDragEnd(Marker marker) {
    onMarkerMoved(marker);
}

@Overridepublic void onMarkerDrag(Marker marker) {
    onMarkerMoved(marker);
}

private void onMarkerMoved(Marker marker) {
    for (DraggableCircle draggableCircle : mCircles) {
        if (draggableCircle.onMarkerMoved(marker)) {
            break;
        }
    }
}


=======================================================================================================

public class SplitStreetViewPanoramaAndMapDemoActivity extends AppCompatActivity
        implements OnMarkerDragListener, OnStreetViewPanoramaChangeListener {}

@Overrideprotected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.split_street_view_panorama_and_map_demo);

    final LatLng markerPosition;
    if (savedInstanceState == null) {
        markerPosition = SYDNEY;
    } else {
        markerPosition = savedInstanceState.getParcelable(MARKER_POSITION_KEY);
    }

    SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
            (SupportStreetViewPanoramaFragment)
                    getSupportFragmentManager().findFragmentById(R.id.streetviewpanorama);
    streetViewPanoramaFragment.getStreetViewPanoramaAsync(
            new OnStreetViewPanoramaReadyCallback() {
                @Override                public void onStreetViewPanoramaReady(StreetViewPanorama panorama) {
                    mStreetViewPanorama = panorama;
                    mStreetViewPanorama.setOnStreetViewPanoramaChangeListener(
                            SplitStreetViewPanoramaAndMapDemoActivity.this);
                    // Only need to set the position once as the streetview fragment will maintain                    // its state.                    if (savedInstanceState == null) {
                        mStreetViewPanorama.setPosition(SYDNEY);
                    }
                }
            });

    SupportMapFragment mapFragment =
            (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(new OnMapReadyCallback() {
        @Override        public void onMapReady(GoogleMap map) {
            map.setOnMarkerDragListener(SplitStreetViewPanoramaAndMapDemoActivity.this);
            // Creates a draggable marker. Long press to drag.            mMarker = map.addMarker(new MarkerOptions()
                    .position(markerPosition)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.pegman))
                    .draggable(true));
        }
    });
}