A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service
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
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.
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
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
CrimeCameraFragment life cycle, we should
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.) ）
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
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)
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
SurfaceViewclass implements the
SurfaceHolder interface. In Crimecamerafragment.java, add the following code to get
SurfaceHolder instance, as shown in Listing 19-7.
Code Listing 19-7 Get
SurfaceHolder instance (Crimecamerafragment.java)
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,
SurfaceView and are destroyed when they disappear from the screen
Surfacewhen it does not exist, you must ensure that nothing is drawn on it.
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.
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
Surface then disconnected from the top after the destruction
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.
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
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
Surface width and height of the incoming method.
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)
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)
Figure 19-7 The camera button was added
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 )
CrimeFragment class, add a member variable, reference the Picture button through the resource ID, and then set it to
CrimeCameraActivity , as shown in Listing 19-11.
Code Listing 19-11 start
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
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
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
Start building with 50+ products and up to 12 months usage for Elastic Compute Service