19th Camera I: Viewfinder

Source: Internet
Author: User

Please refer to the textbook to fully understand and complete the section of this chapter ...

When documenting office habits, it can be much easier to solve problems if they are supported by live photographs. The next two chapters, using the system's own camera API, add the ability to shoot crime scene photos for criminalintent applications.

Although the Camera API is powerful, it's not easy to use it well. Not only to write a large number of implementation code, but also struggling to learn and understand a lot of new concepts. Therefore, it is easy to produce a question is: "Just take a snapshot, there is no convenient standard interface can be used?" ”

The answer is yes. We can interact with the camera through implicit intent. Most Android devices will have a built-in camera app. The camera app automatically listens for intent created by Mediastore.action_image_capture. The 21st chapter describes how to use implicit intent.

This chapter will create an activity based on fragment, and then use the Surfaceview class with the camera hardware to show live video previews in real time, as shown in 19-1.

Figure 19-1 Real-time preview of the camera in viewfinder

Again, we can refer to figure 19-2 for a preview of the new object that will be created later.

Figure 19-2 Object plots for the Criminalintent Application camera Section

The camera instance provides a call to the device's camera hardware level. A camera is an exclusive resource: Only one activity can invoke the camera at a time.

The Surfaceview instance is the viewfinder of the camera. Surfaceview is a special view that renders output to the device's screen directly from what will be displayed.

First, we will create the layout of the Crimecamerafragment view, the Crimecamerafragment class, and the Crimecameraactivity class. Then, create and manage a viewfinder for taking pictures in the Crimecamerafragment class. Finally, configure Crimefragment to start the crimecameraactivity instance. 19.1 Create a Fragment layout

First, in Strings.xml, add a string resource for the camera button we're about to add, as shown in Listing 19-1.

Code Listing 19-1 Adding a string resource to the camera button (Strings.xml)

Next, create a layout file named Fragment_crime_camera.xml with framelayout as the root element. Then refer to Figure 19-3 to complete the addition of each component.

Figure 19-3 Layout of crimecamerafragment (Fragment_crime_camera.xml)

As you can see, in a new layout file, Framelayout contains only one linearlayout child element, which causes Android lint to report linearlayout warning messages that are not useful. Temporarily ignoring it, the 20th chapter adds a second child view for Framelayout.

In the Surfaceview component definition, we use the property combination of Layout_width and layout_weight to lay out its child views. Because the android:layout_width= "wrap_content" property value is set, the button component consumes only the space it needs, and according to the property value of Android:layout_width= "0DP", The Surfaceview component does not occupy any space. However, from the perspective of the remaining space, because the Layout_weight attribute is used, the Surfaceview component uses all the space outside the button component.

Figure 19-4 shows the preview interface for the new layout.

Figure 19-4 Viewfinder and button interface 19.2 create crimecamerafragment

Create a new class named Crimecamerafragment with Android.support.v4.app.Fragment as the superclass. In the subsequent open Crimecamerafragment.java, add the variable as shown in Listing 19-2. Then, overwrite the Oncreateview (...) method to instantiate the layout and reference each component.

Note: Android.hardware.Camera is obsolete ,import Android. hardware. Camera;;

Now, set an event listener for the button, exit the currently hosted activity and return to the list item detail interface when the user taps the button.

Code Listing 19-2 Initial Camera fragment class (Crimecamerafragment.java)

19.3 Create Crimecameraactivity

To SingleFragmentActivity create a new class named for the superclass CrimeCameraActivity . In Crimecameraactivity.java, the override createFragment() method returns one CrimeCameraFragment , as shown in Listing 19-3.

Code Listing 19-3 Creating a Camera activity Class (Crimecameraactivity.java)

Statement Activity and add allow to call camera settings

Next, you need to add the element node in the configuration file uses-permission to get permission to use the camera. Update the Androidmanifest.xml configuration file with reference to listing 19-4.

Code Listing 19-4 Declaring the activity of the camera and adding allow to call camera settings (Androidmanifest.xml)

uses-featureelement is used to specify a feature of a feature device used by the app. Via Android. Hardware.camera features are set up to ensure that only those devices equipped with the camera feature will be able to see the apps you post on Google Play.

Note that in the activity statement, in order to prevent the user from taking a photo at the angle of adjustment, the device screen spins freely, and we use android:screenOrientation properties to force the activity interface to always show in horizontal mode.

Property android:screenOrientation also has many other optional property values. For example, you can set the display orientation of activity to be consistent with its parent class, or you can choose to display only in horizontal mode based on device sensor sensing when the device is in a different direction. You can view the elements of the development document for <activity> more information about other available property values. 19.4 using the camera API

So far, we've been working on basic activity creation. Now it's time to learn to understand camera-related concepts and start using the camera class. 19.4.1 Open and release the camera

First, the management of the camera resources. We have CrimeCameraFragment added an instance to the Camera . The camera is an important resource at the system level, so the key point is that it needs to be used and released in time. If you forget to release, other apps will not be able to use the camera unless you restart your device.

Here are the methods that will be used to manage Camera instances:

public static Camera open (int cameraid)

public static Camera open ()

Public final void release ()

open(int)This method is introduced at level 9th of the API, so if the device's API level is less than level 9th, then only the method without parameters is used open() .

In the CrimeCameraFragment life cycle, we should onResume() onPause() open and release the camera resources in and callback methods. These two methods determine the time boundary that the user can interact with the fragment view, and the camera can only be used when the user is able to interact with the fragment view. (Note that the onResume() method will be called even if the fragment first appears on the screen.) )

In the CrimeCameraFragment.onResume() method, use a Camera.open(int) static method to initialize the camera. Then pass in parameter 0 to open the first camera available to the device (usually the rear camera). If the device does not have a rear-facing camera (such as a Nexus 7 model), the front camera will open.

For devices at level 8th of the API, you need to invoke a method without parameters Camera.open() . onResume()Use annotation protection for the method, @TargetApi and then check the compiled version of the device, depending on the version number of the device, to determine whether to call the Camera.open(0) method or Camera.open() method, as shown in Listing 19-5.

Code Listing 19-5 Opening the camera in a onResume() method (Crimecamerafragment.java)

FragmentWhen destroyed, the camera resources should be released in a timely manner so that they can be used when needed by other applications. The override onPause() method releases the camera resource, as shown in Listing 19-6.

Code Listing 19-6 Implementation life cycle approach (Crimecamerafragment.java)

Note that release() before invoking a method, you must first make sure that there is an Camera instance. This check should be done before calling the camera-related code. Be aware that the camera may not be available even if you request access to the camera. For example, another activity is using it, or because it is a virtual device, the camera does not exist at all. In summary, no matter what the reason, when the camera instance does not exist, a null check can prevent the app from accidentally crashing. 19.4.2 SurfaceView , SurfaceHolder with Surface

SurfaceViewclass implements the SurfaceHolder interface. In Crimecamerafragment.java, add the following code to get SurfaceView the SurfaceHolder instance, as shown in Listing 19-7.

Code Listing 19-7 Get SurfaceHolder instance (Crimecamerafragment.java)

setType(...)Methods and SURFACE_TYPE_PUSH_BUFFERS constants have been deprecated, so the compiler will prompt a warning message for obsolete code. Android Studio The deprecated code is also marked with a strikethrough .

Why use them now that they are deprecated code? The camera preview works without the setType(...) support of methods and constants on devices running prior to Honeycomb SURFACE_TYPE_PUSH_BUFFERS . In code listing 19-7, we use @SuppressWarnings annotations to eliminate deprecated code-related warning messages. This seems like a weird process, but it's the best way to deal with deprecated code and compatibility issues. For a more in-depth discussion of deprecated code in Android, see the Deep Learning section at the end of chapter 20th. (It may also be Google's way of promoting a new version of Android, after all, developers are not enthusiastic about it!) )

SurfaceHolderis the link between us and Surface the object. Surfacethe object represents the buffer of the raw pixel data.

SurfaceObjects also have a life cycle: they are SurfaceView created when they appear on the screen, Surface SurfaceView and are destroyed when they disappear from the screen Surface . Surfacewhen it does not exist, you must ensure that nothing is drawn on it.

Figure 19-5 SurfaceView , SurfaceHolder and Surface

Unlike other view objects, SurfaceView and their co-working objects, they do not self-draw content. For any object that wants to draw the content into the Surface buffer, we call it Surface the client . In the CrimeCameraFragment class, the Camera instance is Surface the client.

Remember that Surface when it does not exist, you must ensure that nothing is Surface drawn in the buffer. Figure 19-6 shows two possible scenarios that need to be handled, Surface after the creation is complete, the connection will be made to the top, and Camera SurfaceHolder Surface then disconnected from the top after the destruction Camera SurfaceHolder .

Figure 19-6 the ideal working condition

To complete the above tasks, SurfaceHolder another interface is provided: SurfaceHolder.Callback . This interface listens Surface for events in the life cycle, so that it can control the Surface work with its clients.

In Crimecamerafragment.java, the SurfaceHolder.Callback interface is implemented so that the camera preview and Surface life cycle methods work together, as shown in Listing 19-8.

Code Listing 19-8 Implementation SurfaceHolder.Callback Interface (Crimecamerafragment.java)

Note that when the preview fails to start, we release the camera resource through the exception control mechanism. At any time, after opening the camera and completing the task, you must remember to release it in a timely manner, even when an exception occurs.

In the surfaceChanged(...) implementation method, we set the camera preview size to null. This is only a temporary assignment until the acceptable preview size is determined. The camera's preview size cannot be set arbitrarily, and if an unacceptable value is set, the app throws an exception. 19.4.3 determine the preview interface size

First, you Camera.Parameters get a list of camera preview sizes supported by the system through nested classes. Camera.Parametersclass includes the following methods:

Public list<camera.size> getsupportedpreviewsizes ()

This method returns android.hardware.Camera.Size a list of class instances, each of which encapsulates a specific picture width and height dimension.

To find a suitable Surface preview size, you can compare the preview size in the list to the surfaceChanged() Surface width and height of the incoming method.

In the CrimeCameraFragment class, add the method shown in Listing 19-9. This method takes a set of preview dimensions and then finds the dimensions with the largest number of pixels. To illustrate, it is not elegant to calculate the optimal size of the implementation code, but it is well-adapted to our usage needs.

Code Listing 19-9 Find the best size for device support (Crimecamerafragment.java)

surfaceChanged(...)call the method in the method to set the preview size, as shown in Listing 19-10.

Code Listing 19-10 Call getBestSupportedSize(...) method (Crimecamerafragment.java)

19.4.4 StartCrimeCameraActivity

To use the viewfinder, you need to CrimeFragment add a camera call button in the user interface. Click the camera button to CrimeFragment launch an CrimeCameraActivity instance. Figure 19-7 shows the view interface for the added camera button (inside the red box) CrimeFragment .

Figure 19-7 The camera button was added CrimeFragment

To implement the component Reflow user interface shown in Figure 19-7, you need to add three LinearLayout and one ImageButton . Refer to Figure 19-8 to Modify the CrimeFragment layout file fragment_crime.xmlbelow Res\layout and Res\layout-land, respectively.

Figure 19-8 Add a camera button and rearrange the layout ( Layout/fragment_crime.xml )

Follow figure 19-9 to complete a similar horizontal layout adjustment.

Figure 19-9 Add a camera button and rearrange the layout ( Layout-land/fragment_crime.xml )

In the CrimeFragment class, add a member variable, reference the Picture button through the resource ID, and then set it to OnClickListener start CrimeCameraActivity , as shown in Listing 19-11.

Code Listing 19-11 start CrimeCameraActivity (Crimefragment.java)

For devices without a camera, the photo button ( mPhotoButton ) should be disabled. You can check to PackageManager see if the device comes with a camera. In the onCreateView(...) method, for devices that do not have a camera, add the code that disables the Take photo button, as shown in Listing 19-12.

Code Listing 19-12 Check if the device has a camera (Crimefragment.java)

After getting to PackageManager , call the hasSystemFeature(String) method and pass in constants that represent the features of the device. FEATURE_CAMERAA constant represents a rear camera, and a FEATURE_CAMERA_FRONT constant represents a front-facing camera. For devices that do not have a camera, call ImageButton the button's setEnabled(false) property method.

Run the Criminalintent app. View a crime detail record, then click the Take photo button to view the camera Live preview screen. but now it is not possible to take pictures and save, this type of feature will be completed in the next chapter , now click the "Forensics" button will return to the CrimeFragment view, 19-10 shows.

Figure 19-10 Real-time preview screen from the camera

We've already forced the interface in the configuration file CrimeCameraActivity to always show in horizontal mode. If you try to rotate the device, you can see that the preview and photo buttons are locked in horizontal mode, even if the device is in vertical mode.

Hide the status bar and action Bar

As shown in 19-10, the activity's Action bar and status bar mask some of the viewfinder windows. In general, users only focus on the screen in the viewfinder, and will not stay in the photo screen for a long time, so the action bar and the status bar is not useful, and even hinder the photo framing, if you can hide them it is best.

Interestingly, we can only hide the CrimeCameraActivity CrimeCameraFragment Action Bar and the status bar in the middle instead of in. Open the Crimecameraactivity.java file, and in the code listing 19-13, onCreate(Bundle) add the hidden function code to the method.

Code Listing 19-13 Configuring activity (Crimecameraactivity.java)

Why does it have to be hidden in activity? Called in the method that is called in the Activity.setContentView(...) CrimeCameraActivity onCreate(Bundle) Superclass version method of the class. Before you create activity a view, you must call requestWindowFeature(...) methods and addFlags(...) methods. Fragment cannot be added before its managed activity view is created, so it is necessary to invoke the relevant method of hiding the action bar and the status bar in the activity.

Run the Criminalintent app again. Now you see an unobstructed viewfinder window, shown in 19-11.

Figure 19-11 the status bar and action Bar are hidden. Activity Screen

The next chapter will cover more camera API-related content, enabling you to save image files locally and display them in the Crimefragment view.

19th Camera I: Viewfinder

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.