How to Download Facebook Videos to your Android Phone

A very powerful app can be done and easy to use. Look down.

look at it detail:

Video Downloader for Facebook

Video Downloader for Facebook allows you to browse through your Facebook account, your news feed and your friends/pages walls using a built-in browser that allows you to select the video you want to download and save them so you can watch it later and share it with your friends via different apps.

How to use(Recommand: Watch the video above)

  1. Click Browse facebook On the home page.
  • Login it Click the video Play button you want to download.
  • then click to download button on Bottom right corner

Important: Which video you want to download must click on its play button in advance. Super simple!!

Features:

1- Easy to download video.Browse facebook page like original facebook app.
2- Safe & light weight. less than 5M
3- Allows you to save videos to watch them later.
4- Multi-task download
5- Can search for videos and enter url to download
6- Protect your videos and privacy with password
7- Find and download any video by browsing directly the Facebook website
8- Save facebook Videos In SD Card
9- Download videos from any page, even the pages that are not liked by you.
10- Play video offline using Video downloader for facebook.
11- Share video using whatsapp, facebook messanger, and facebook lite. Also you can share it using other social networks like twitter, instagram and Snapchat.
12- Batch video downloader from faceook

Install Video Downloader for Facebook and start downloading videos from Facebook now!

If you liked this application recommend it to your friends by sharing it using facebook, twitter and messanger and communication applications like snapchat. Don’t forget to share it to your followers in instagram.

Free application Video Downloader for Facebook as well as Save Videos from Facebook

version 1.0.2 update:

1 Optimize the download process, automatic retry

2 When you find the video download button will shake around

3 Download is simpler

Important Notes:

  • This app is NOT affiliated with or endorsed by the Facebook official network.
  • Any unauthorized re-uploading or downloading of contents and/or violations of Intellectual property rights is the sole responsibility of the user.

 

Advertisements

Android drawable detail

We all know that in the Android project which, drawable folders are used to place picture resources, whether it is jpg, png, or 9.png, can be placed here. In addition, there are xml files like the selector can also be placed under the drawable folder.

But if you are using Android Studio to create a new project, you will find the following directory structure:

20160422203208418.png

Ok? How will there be so many mipmap at the beginning of the folder, and their naming rules and drawable folder is very similar, but also hdpi, mdpi, xhdpi, etc., and which really is put the picture, is the Android project placed in the picture location has been changed?

Developers who have just switched from Eclipse to Android Studio may be unfamiliar with the mipmap folder. In fact, there is no need to worry that our usual programming habits do not need to be changed because the mipmap folder is only used to place the application’s icon’s.

Then before we all put the icon of the application and the ordinary picture resources together into the drawable folder, so it will look more messy, and sometimes want to find a picture from a bunch of picture resources within half a day Can not find, and more than one file is also prone to leakage of the situation, but just Android is extremely recommended that we in each resolution folder below put a corresponding size of the icon, so they are independent Put mimap folder which is a good solution to this problem.

In addition, the icon placed in the mipmap folder can also let our program launcher icon automatically have the ability to display across the device density, for example, a screen density is xxhdpi device can automatically load mipmap-xxxhdpi icon as an application Launcher icon, so the icon will look more delicate.

In addition, for each density of the icon should be designed into what size In fact, Android is also given the best advice, icon size is best not to design, because too low resolution will cause the icon is blurred, and too high The resolution will only increase the size of APK. The recommended dimensions are shown in the following table:

density Recommended size
mipmap-mdpi 48 * 48
mipmap-hdpi 72 * 72
mipmap-xhdpi 96 * 96
mipmap-xxhdpi 144 * 144
mipmap-xxxhdpi 192 * 192

Then we refer to the mipmap method and the way before the drawable is exactly the same, in the resource to use @ mipmap / res_id, in the code to use R.mipmap.res_id. For example, AndroidManifest.xml is like this reference ic_launcher icon:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

Then let’s introduce some of the drawable techniques you do not know: First I prepared a picture of 270 * 480 pixels: 20160424154510643.png Name the image android_logo.png and place it under the drawable-xxhdpi folder. Why should I put it in this folder? Because the density of my mobile phone screen is xxhdpi. So how can you know the density of your own mobile phone screen? You can use the following method to get the value of the screen to the value:

float xdpi = getResources().getDisplayMetrics().xdpi;
float ydpi = getResources().getDisplayMetrics().ydpi;

Where xdpi represents the value of the screen width, ydpi represents the screen height of the dpi value, usually these two values are almost equal or very close to the two values on my phone are about 403. What does 403 mean? We directly refer to the following table to know:

dpi range density
0dpi ~ 120dpi ldpi
120dpi ~ 160dpi mdpi
160dpi ~ 240dpi hdpi
240dpi ~ 320dpi xhdpi
320dpi ~ 480dpi xxhdpi
480dpi ~ 640dpi xxxhdpi

From the table can be seen, 403dpi is between 320dpi to 480dpi, so belong to the scope of xxhdpi.
After the picture is gone, I quote this picture in the layout file as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/android_logo"
        />

</LinearLayout>

In the ImageView control to specify the load android_logo this map, and the ImageView control are set to wrap_content width, so how much the picture, how much of our control will be. Now run the program, the effect is as follows: 20160423155934999.png Because my mobile phone resolution is 1080 * 1920 pixels, and this picture resolution is 270 * 480 pixels, just a quarter of the resolution of the phone, so from the figure can also be seen, android_logo picture The width and height are probably occupied by the screen width of about a quarter, the size of the basic is more accurate. So far everything is fine, is not it? Here we try to make some changes, android_logo.png this map moved to the drawable-xhdpi folder, not to copy a copy to the drawable-xhdpi folder, but the picture moved to the drawable-xhdpi folder, and then Re-run the program, the effect as shown below:

20160423160735251.png

Ok? How do you feel like the picture becomes bigger, is it ill Then we will move this picture to the drawable-mdpi folder try, re-run the program, the effect as shown below:

20160423161009361.png

This is certainly not the illusion, it is too obvious, the picture was enlarged! So why is a good end of the picture will be automatically zoom? And this magnification is not a bit too much. In fact, Android does these scaling operations have its strict rules and algorithms. There may be a lot of friends do not for many years Android did not pay attention to the rules of these zoom, because these details are too small, then this micro-skills to explore inside, we come to these details reasonable. First explain why the picture will be enlarged, when we use the resource id to refer to a picture, Android will use some rules to help us match the most suitable picture. What is the most suitable picture? For example, my mobile phone screen density is xxhdpi, then drawable-xxhdpi folder under the picture is the most suitable picture. So when I quote this image with android_logo, if the drawable-xxhdpi folder has this picture, it will be used first, in which case the picture will not be scaled. However, if the drawable-xxhdpi folder does not have this picture, the system will automatically go to other folders to find this map, and priority to the higher density of the folder to find this picture, our current scene is Drawable-xxxhdpi folder, and then found here android_logo this map, then try to find a higher density of the folder and found no higher density, and this time will go to the drawable-nodpi folder to find this picture , And found no, then it will go to the lower density of the folder to find, followed by drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi. The general match rule is the case, then for example, now finally in the drawable-mdpi folder to find android_logo this map, but the system will think that you this picture is designed specifically for low-density devices designed, if the direct map In the current high-density devices on the use of pixels may be too low, so the system automatically help us to do such an amplification operation. Then the same reason, if the system is in the drawable-xxxhdpi folder below to find this picture, it will think that this picture is designed for higher density devices, if the map directly on the current use of the device There may be pixels too high, so will automatically help us to do a shrinking operation. So, we can try to move the android_logo map to the drawable-xxxhdpi folder below to get this result:

20160423172553614.png

You can see, now the picture width and height are not up to a quarter of the phone screen, indicating that the picture is really reduced. In addition, just introduced the rules when the mention of a drawable-nodpi folder, this folder is a density-free folder, where the picture system will not automatically scale it, the original picture is how much will be the actual Show how much. But should pay attention to the order of a load, drawable-nodpi folder is in the matching density folder and higher density folder can not find the case will go here to find pictures, so placed in the drawable-nodpi folder Pictures are usually not recommended to put other folders inside the folder. The picture is the reason for the amplification Now we have figured out, then there is a question that is how to enlarge the magnification is how to determine it? Unfortunately, I did not find the relevant documentation, but I summed up a law, here to share with you. Or just look at the range of dpi – density table:

dpi density
0dpi ~ 120dpi ldpi
120dpi ~ 160dpi mdpi
160dpi ~ 240dpi hdpi
240dpi ~ 320dpi xhdpi
320dpi ~ 480dpi xxhdpi
480dpi ~ 640dpi xxxhdpi

It can be seen that the dpi of each density has a maximum value, and the ratio between the maximum is the proportion of the picture that will be automatically enlarged by the system. I said that we have to verify through the example, modify the layout of the document code, as follows:

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

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/android_logo"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取图片宽高"
        android:onClick="buttonClick"
        />

</LinearLayout>

You can see that we have added a button and registered a click event for the button. And then deal with this click event in MainActivity:

public class MainActivity extends AppCompatActivity {

    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.image);
    }


    public void buttonClick(View view) {
        Toast.makeText(this, "width:" + imageView.getWidth(), Toast.LENGTH_SHORT).show();
        Toast.makeText(this, "height:" + imageView.getHeight(), Toast.LENGTH_SHORT).show();
    }
}

Here in the click event, respectively, to obtain the picture width and height and use Toast prompted out. The code can be modified so much, and then move the picture to the drawable-mdpi folder.

Here we begin to analyze, mdpi density of the highest dpi value is 160, and xxhdpi density of the highest dpi value is 480, so it is a 3 times the relationship, then we can guess, put the drawable-mdpi folder under the picture Xxhdpi density display on the device will be enlarged 3 times. Corresponding to android_logo this picture, the original pixel is 270 * 480, 3 times after amplification should be 810 * 1440 pixels. Run the program below, the effect is as follows:

20160423175803621.gif

Verification passed. Let’s try again and move the image to the drawable-xxxhdpi directory. Xxxhdpi density of the highest dpi value is 640,480 is its 0.75 times, then we can guess, put the drawable-xxxdpi folder under the image in the xxhdpi density device display will be reduced to 0.75 times. 270 * 480 0.75 times should be 202.5 * 360, because the pixels do not support the decimal point, then rounding should be 203 * 360 pixels. Re-run the program, the effect as shown below:

20160423180631696

Re-pass through. If you are interested, you can use several other types of dpi drawable folder to try, should be suitable for this set of zoom rules. So that we put the picture why will be scaled, as well as the specific zoom times are clear, drawable related details you have to explore the very subtle.

But this article is not finished here, the following I am going to talk about our actual development which will encounter the scene. According to the development of Android recommendations, we prepare the picture resources as much as possible to each density of equipment should be prepared a set, so that the program can be the best fit. But the reality is that the company’s UI are usually only to a set of picture resources, want them for each density of equipment design a set of picture resources, and still in accordance with the scale of the rules we have to design, Think too happy. Yes, this is the reality, then in this case, we should only have this set of picture resources on which the density of the folder under it?

Can be analyzed in this way, according to what we have just learned, if a picture on the low density folder, then the high-density devices will be automatically displayed when the picture is enlarged, and if a picture on the high Density folder, then the low-density devices will be automatically displayed when the picture is reduced. Then we can assess the way through the cost of a picture was reduced after the show is actually no side effects, but a picture is enlarged after the show means to take up more memory. Because the picture is enlarged, the pixels will become more, and each pixel is to take up memory.

We can still intuitively through the example to experience, first android_logo.png picture moved to the drawable-xxhdpi directory, run the program after we through the Android Monitor to observe the program memory usage:

20160423221840743.png

You can see that the program takes up about 19.45M of memory. And then move the android_logo.png picture to the drawable-mdpi directory, rerun the program, the results as shown below:

20160423222108212.png

Now rose to 23.40M, and occupied a significant increase in memory. If you move the picture to the drawable-ldpi directory, you will find that taking up memory will be higher.

This example also verifies a problem, I believe that there are a lot of more experienced Android programmers may have encountered this situation, that is, when your project becomes more and more, sometimes loaded a drawable- Hdpi under the picture, the program directly OOM collapse, but if this map into the drawable-xhdpi or drawable-xxhdpi will not collapse under the fact that this is the truth.
Then after a series of the above analysis, the answer will naturally come out, the picture resources should be placed in the high-density folder, so you can save the picture memory costs, and UI in the design of the picture should also try to face high-density screen Equipment to design. For now, the best place to put the picture resources folder is drawable-xxhdpi. Then some friends may ask, is not there a higher density of drawable-xxxhdpi? Why not put it here? This is because the market 480dpi to 640dpi device is too small, if the screen for this level of density to design pictures, the picture is not in the case of scaling itself has been great, and basically can not save memory The role of expenditure.

How to Submit the code to github or gitlab

Create a new project in gitlab:

20161221101832138.png

After creating it will generate a .Git path.

 Switch the local project file directory:

 

  1. Right click on git bash
  2. In git bash inside the implementation of  git init initialization
  3. git add .  Submitted to the current
  4. git commit -m “init commit”

Add a remote association

git remote add origin Your remote git address when creating a project.

Push to the remote repository

git push --set-upstream origin master

After the above are completed will get the following:

  • Generate local branch master
  • Remote Warehouse associated with the local repository
  • A remote branch associated with a local branch
  • The local code is all submitted to the remote repository, and others can share it

Refresh gitlab to view the submitted items

 

How to use Android Dialog,Toast, Snackbar

Dialog and Toast all certainly not unfamiliar, this we usually use is too much. Snackbar is a new control provided in the Design Support library, some friends may have been used, and some friends may not have to understand. But do you really know when to use Dialog, when should you use Toast, when should I use Snackbar? In this article, we will learn about the timing of the use of the three, in addition to introduce some additional skills.

Dialog

First of all to introduce the use of Dialog it, in fact, very simple, I believe most people are often used:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
       .setMessage("Dialog content.")
       .setPositiveButton("OK", new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, 
               int which) {
               }
       })
       .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog,
                int which) {
               }
        })
       .show();

This code can pop up a very beautiful Dialog, as shown below:

20160717190208018

Now this Dialog is Material Design style, because I was running on the 6.0 system, it will automatically give such a style. But if the old version of the system to run, for example, 2.3 system, what will be the effect? Run to know, as shown below:20160717190240159.png

This effect is more ugly, but no way, this is the 2.3 system was the style of the way !

People’s aesthetic is always in progress, we have no way in the old version of the system also use Material Design style Dialog it? Of course, Google has taken full account of this, in the appcompat-v7 library also provides an AlertDialog class, the full path is:

android.support.v7.app.AlertDialog

 

We use this package AlertDialog, will be able to make the dialog box in all the system version to maintain a consistent style. Now re-run in the 2.3 system, the effect is as follows:

20160717190351520

You can see that the effect is now quite good, it can be considered a little trick it.

Dialog’s role is to give users a message, and let the user make a judgment based on the prompts. The characteristic of Dialog is that it will prevent you from doing what you are doing and you have to stop working on Dialog. However, most people may not like this is interrupted, perhaps the user is dealing with an important operation, suddenly pop up a Dialog to block his original operation, this time the user will become very annoying.

Therefore, the use of Dialog when the time is still cautious, try not to give users a bad sense of experience.

Toast

Speaking will not block the user’s ongoing operation, which extends to our second topic today, Toast. Toast will only pop up a message to tell the user that something has happened, after a period of time will automatically disappear. It will not block any user’s operation, and even the user can completely ignore the Toast.

So let’s take a look at the basic usage of Toast, as shown below:

Toast.makeText(context, "things happened", Toast.LENGTH_SHORT).show();

 

The last parameter is used to specify the length of the Toast display. Toast.LENGTH_SHORT indicates that the display time is short and Toast.LENGTH_LONG indicates that the display time is longer.

But not to say that the use of Toast on the depth of a little, for example, the above-mentioned wording will exist as shown in the following figure:

20160717190636909.png

You can see, here I quickly click on the button five times, Toast triggered five times. This experience is really bad, because perhaps the user is a little more shaking a few times, resulting in Toast on a long time can not afford to shut down. Or we actually have other operations, and should pop up a new Toast prompt, and on a Toast but not show the end.

Therefore, the best practice is to encapsulate the Toast call into an interface written in a public class as follows:

public class Util {

    private static Toast toast;

    public static void showToast(Context context, 
        String content) {
        if (toast == null) {
            toast = Toast.makeText(context,
                         content, 
                         Toast.LENGTH_SHORT);
        } else {
            toast.setText(content);
        }
        toast.show();
    }

}

 

You can see here and we usually use Toast way is not the same, here will first determine whether Toast object is empty, if it is empty will call makeText () method to generate a Toast object, or call directly SetText () method to set the display of the content, and finally call the show () method to Toast displayed. Since the new Toast object will not be generated every time it is called, the problem we have just encountered will not appear here.

Call the time is also very simple, only the Context object and Toast to display the contents of the incoming can be:

Util.showToast(context, "things happened");

Now we re-run the program again, the effect as shown below:

20160717190747269.png

You can see, now no matter how many times we trigger Toast call, will only continue Toast show the length of time, which can be considered a little trick it.

Toast’s role is to tell the user what happened now, will not block the user’s operation, but at the same time the user can only passively accept this thing, because there is no way to let the user choose to agree or refuse.

Although Toast in the user experience than Dialog better, but also with caution, especially when involved in some sensitive operations. For example, delete the data, only to the user a prompt: “your data has been deleted”, and not to the user to choose whether to delete the opportunity, this time the user may be runaway.

Snackbar

If Dialog and Toast are two extremes, then Snackbar is in the middle of the position. Snackbar and Toast are similar, but the use is more extensive, and it is able to interact with the user. Snackbar uses an animation effect from the bottom of the screen to pop out, after a period of time will automatically disappear.

Before using Snackbar, you first need to add the appropriate dependencies in app / build.gradle:

dependencies { compile 'com.android.support:design:23.4.0' }

 

And then you can use Snackbar, and its usage and Toast is more similar:

Snackbar.make(view, "data deleted",Snackbar.LENGTH_LONG)
        .setAction("Undo", new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                }
            })
        .show();

 

Here the call to Snackbar’s make () method to create a Snackbar object, make () method of the first parameter needs to be passed into a view, as long as the current interface layout of any view can be, Snackbar will use this view to automatically find the most The outer layout is used to show Snackbar. The second argument is what Snackbar displays, and the third argument is the length of the Snackbar display. These are similar to Toast.

Then there is a setAction () method to set an action, so that Snackbar is not just a hint, but can interact with the user. Finally call the show () method to let Snackbar be displayed.

Now re-run the program, the effect as shown below:

 

20160717191403222

You can see, Snackbar effect is somewhat similar to Toast, but it is from the bottom of the screen pop out. In addition Snackbar above can join and user interaction button, such as delete the data when the user to an Undo option, from these small details can enhance a lot of user experience.

sum up

Now you have three ways to give users tips, Dialog, Toast and Snackbar, the following we use the three ways to make a summary of the time it.

  1. Dialog: Use Dialog when the prompt message is critical and must be made by the user to make a decision.
  2. Toast: When the message tells the user that something has happened, the user does not need to respond to this matter when using Toast.
  3. Snackbar: Any of the other scenes above, Snackbar may be your best choice.

Android service (2)

In the previous article, we learned about the important aspects of the Android Service, including the basic usage of the Service, the communication between Service and Activity, the way the Service was destroyed, the relationship between Service and Thread, and how to create the front service. The above mentioned knowledge points, basically covered most of the daily development work which may be used to the Service technology. However, there is actually a more high-end on the use of skills did not introduce, that is, the use of remote Service. Use the remote service can even achieve the function of Android cross-process communication, let us look at the following specific.

If you have not read the previous article, it is recommended to read Android service (1), because this article is involved in the code on the basis of the previous article To be modified.

In the previous article we know, Service is actually running in the main thread, if directly in the Service to deal with some time-consuming logic, it will lead to the program ANR.

Let’s take an experiment to verify it, modify the ServiceTest project created in the previous article, let the thread sleep for 60 seconds in MyService’s onCreate () method, as follows:

Let’s take an experiment to verify it, modify the ServiceTest project created in the previous article, let the thread sleep for 60 seconds in MyService’s onCreate () method, as follows:

public class MyService extends Service {  
  
    ......  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
        try {  
            Thread.sleep(60000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
      
    ......  
  
}

After re-running, click the Start Service button or Bind Service button, the program will block and can not carry out any other operation, after a period of time will pop up ANR prompt box.

Before we mentioned that you should open the thread in the service to perform time-consuming tasks, so that you can effectively avoid the emergence of ANR.

Then the theme of this article is to introduce the use of remote Service, if the MyService into a remote Service, there will be no ANR situation? Let’s try it out.

Will be a common Service into a remote Service is actually very simple, only need to register the Service when it android: process attribute specified as: remote on it, the code is as follows:

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="com.example.servicetest"  
    android:versionCode="1"  
    android:versionName="1.0" >  
  
    ......  
      
    <service  
        android:name="com.example.servicetest.MyService"  
        android:process=":remote" >  
    </service>  
  
</manifest>  

Will be a common Service into a remote Service is actually very simple, only need to register the Service when it android: process attribute specified as: remote on it, the code is as follows:

Why will the conversion of MyService into a remote service will not lead to the procedure ANR? This is because, after using the remote Service, MyService has been running in another process, so it will only block the process of the main thread, and will not affect the current application.

In order to confirm that MyService is now running in another process, we are in the MainActivity onCreate () method and MyService onCreate () method to add a log, print out their respective process id, as follows:

Log.d("TAG", "process id is " + Process.myPid());  

Re-run the program again, and then click the Start Service button, you will find a different print id.

You can see that not only the process id is different, and even the application package name is not the same, MyService print the log, package name followed by: remote logo.

That since the remote Service so easy to use, simply after we put all the Service are converted into a remote Service bar, but also save and then open the thread. In fact, the remote Service is not only easy to use, or even can be called more difficult to use. In general, if you can not use the remote Service, try not to use it.

Here to look at its drawbacks, first of all MyService onCreate () method to allow the thread to sleep code removed, and then re-run the program, and click on the Bind Service button, you will find the program crashes! Why click on the Start Service button program will not crash, and click the Bind Service button will crash it? This is due to the Bind Service button in the click event which we will make MainActivity and MyService to establish association, but the current MyService is a remote service, Activity and Service running in two different processes, then you can no longer use the traditional The way to establish the association, the program will collapse.

So how can we let Activity and a remote service to establish a link? This will use AIDL for cross-process communication (IPC).

AIDL (Android Interface Definition Language) is the meaning of the Android interface definition language, it can be used to allow a service and multiple application components between the cross-process communication, which can achieve multiple applications share the same service function.

Here we take a step by step to see what the use of AIDL in the end is what First need to create a new AIDL file, in this document defines the need to Communicate with the Service method. Create a new MyAIDLService.aidl file with the following code:

package com.example.servicetest;  
interface MyAIDLService {  
    int plus(int a, int b);  
    String toUpperCase(String str);  
} 

Click Save, gen directory will generate a corresponding Java file, as shown below:

And then modify the code in MyService, which we have just defined the MyAIDLService interface, as follows:

public class MyService extends Service {  
  
    ......  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        return mBinder;  
    }  
  
    MyAIDLService.Stub mBinder = new Stub() {  
  
        @Override  
        public String toUpperCase(String str) throws RemoteException {  
            if (str != null) {  
                return str.toUpperCase();  
            }  
            return null;  
        }  
  
        @Override  
        public int plus(int a, int b) throws RemoteException {  
            return a + b;  
        }  
    };  
  
}  

Here first MyAIDLService.Stub was implemented, rewrite the toUpperCase () and plus () these two methods. The two methods are to convert all the strings into an uppercase format, and add the two incoming integers, respectively. And then returns the implementation of MyAIDLService.Stub in the onBind () method. Why can you write here? Because Stub is actually a subclass of Binder, so in the onBind () method can be directly returned to the implementation of Stub.

Next, modify the code in MainActivity as follows:

public class MainActivity extends Activity implements OnClickListener {  
  
    private Button startService;  
  
    private Button stopService;  
  
    private Button bindService;  
  
    private Button unbindService;  
      
    private MyAIDLService myAIDLService;  
  
    private ServiceConnection connection = new ServiceConnection() {  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  
  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            myAIDLService = MyAIDLService.Stub.asInterface(service);  
            try {  
                int result = myAIDLService.plus(3, 5);  
                String upperStr = myAIDLService.toUpperCase("hello world");  
                Log.d("TAG", "result is " + result);  
                Log.d("TAG", "upperStr is " + upperStr);  
            } catch (RemoteException e) {  
                e.printStackTrace();  
            }  
        }  
    };  
  
    ......  
  
}  

We just modified the code in the ServiceConnection. As you can see, here first use the MyAIDLService.Stub.asInterface () method to pass the incoming IBinder object into the MyAIDLService object, and then you can call all the interfaces defined in the MyAIDLService.aidl file. Here we first call the plus () method, and passed the 3 and 5 as a parameter, and then call the toUpperCase () method, and pass the hello world string as a parameter, and finally call the method to return the results printed out.

Now rerun the program and click the Bind Service button then you can see;

result is 8
Upperstr is Hello World

Thus, we have indeed successfully achieved cross-process communication, and in a process to access another process in the method.

But you can also see that the current cross-process communication in fact does not have any real effect, because it is only in an Activity called the same application in the Service method. The real meaning of cross-process communication is to allow an application to access another application in the Service, in order to achieve the function of sharing Service. So now we naturally have to learn about how to call in other applications to MyService Lane method.

In the previous article we already know that if you want to make the association between Activity and Service, you need to call the bindService () method, and pass Intent as a parameter, specify the Intent to bind the Service, the sample code as follows:

Intent bindIntent = new Intent(this, MyService.class);  
bindService(bindIntent, connection, BIND_AUTO_CREATE); 

Here in the construction of Intent when using MyService.class to specify which service to bind, but in another application to bind the service when there is no MyService this class, then you must use the implicit Intent The Now modify the code in AndroidManifest.xml to add an action to MyService as follows:

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="com.example.servicetest"  
    android:versionCode="1"  
    android:versionName="1.0" >  
  
    ......  
  
    <service  
        android:name="com.example.servicetest.MyService"  
        android:process=":remote" >  
        <intent-filter>  
            <action android:name="com.example.servicetest.MyAIDLService"/>  
        </intent-filter>  
    </service>  
  
</manifest> 

This means that MyService can respond to an intent with the action com.example.servicetest.MyAIDLService.

Now re-run the program, so that the remote Service side of the work done.

And then create a new Android project, named ClientTest, we try to call this method in the remote method MyService.

Activity in ClientTest If you want to establish association with MyService is not difficult, first of all need to MyAIDLService.aidl file from the ServiceTest project copy over, pay attention to the original package path to copy together.

MyAidlService.png

And then open or create activity_main.xml, in the layout file also add a Bind Service button:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
     >  
  
   <Button   
       android:id="@+id/bind_service"  
       android:layout_width="match_parent"  
       android:layout_height="wrap_content"  
       android:text="Bind Service"  
       />  
  
</LinearLayout>  

Then open or create a new MainActivity, in which to join and MyService to establish the associated code, as follows:

public class MainActivity extends Activity {  
  
    private MyAIDLService myAIDLService;  
  
    private ServiceConnection connection = new ServiceConnection() {  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  
  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            myAIDLService = MyAIDLService.Stub.asInterface(service);  
            try {  
                int result = myAIDLService.plus(50, 50);  
                String upperStr = myAIDLService.toUpperCase("comes from ClientTest");  
                Log.d("TAG", "result is " + result);  
                Log.d("TAG", "upperStr is " + upperStr);  
            } catch (RemoteException e) {  
                e.printStackTrace();  
            }  
        }  
    };  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        Button bindService = (Button) findViewById(R.id.bind_service);  
        bindService.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Intent intent = new Intent("com.example.servicetest.MyAIDLService");  
                bindService(intent, connection, BIND_AUTO_CREATE);  
            }  
        });  
    }  
  
}  

This part of the code we will be very familiar, right? Yes, this is almost exactly the same as the code in the MainActivity of ServiceTest, except that when we associate the Activity and Service with an implicit Intent, specify the Intent action as com.example.servicetest.MyAIDLService.

After the current Activity and MyService are associated, we still call both the plus () and toUpperCase () methods. The remote MyService will process the incoming parameters and return the results, and then print the results.

In this case, the code in ClientTest is all done, and now run the project, and then click the Bind Service button, this time will be and remote MyService to establish association.

I do not have to say, we have seen that our cross-process communication has been a perfect realization.

However, there is a need to note that, because it is in the process of passing data between different processes, Android format support for such data is very limited, basically only can pass Java basic data type, string, List or Map and so on. So what if i want to pass a custom class? This must be made to achieve this class Parcelable interface, and to give this class also defines a name of the AIDL file. This part of the content is not complicated, and the relationship with the Service is not, so no longer explain in detail, and interested friends can check their own relevant information.

Well, combined with the upper and lower, this is what you need to know about Service.

Android service (1)

Service as one of the four components of Android, in every application plays a very important role. It is mainly used in the background to deal with some time-consuming logic, or to perform some of the tasks that require long-term operation. When necessary, we can even exit the program in the case, so that Service in the background to keep running.

Basic usage of Service

Service on the most basic usage is how to start a Service, and start the Service method and start the Activity is very similar, need to use Intent to achieve, the following we through a specific example to look at.

Create a new Android project, the project name is called MyService Project, where I chose to use the 4.0 API.

And then create a new service inherited from the Service, and rewrite the parent class onCreate (), onStartCommand () and onDestroy () method, as follows:

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  
      
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        return null;  
    }  
  
}  

You can see that we just printed a word in the onCreate (), onStartCommand (), and onDestroy () methods, and did nothing else.

And then open or create activity_main.xml as the main layout file for the program, as follows:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical" >  
  
    <Button  
        android:id="@+id/start_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Start Service" />  
  
    <Button  
        android:id="@+id/stop_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Stop Service" />  
  
</LinearLayout> 

We added two buttons in the layout file, one for starting Service, one for stopping Service. And then open or create a MainActivity as the main activity of the program, in which to join the Start Service and stop the Service logic, the code is as follows:

public class MainActivity extends Activity implements OnClickListener {  
  
    private Button startService;  
  
    private Button stopService;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        startService = (Button) findViewById(R.id.start_service);  
        stopService = (Button) findViewById(R.id.stop_service);  
        startService.setOnClickListener(this);  
        stopService.setOnClickListener(this);  
    }  
  
    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.start_service:  
            Intent startIntent = new Intent(this, MyService.class);  
            startService(startIntent);  
            break;  
        case R.id.stop_service:  
            Intent stopIntent = new Intent(this, MyService.class);  
            stopService(stopIntent);  
            break;  
        default:  
            break;  
        }  
    }  
  
}  

You can see that in the click event of the Start Service button, we build an Intent object and call the startService () method to start MyService. Then in the Stop Serivce button’s click event, we also constructed an Intent object and called the stopService () method to stop MyService. Code logic is very simple, I believe I do not need to do more to explain it.

Also note that every service in the project must be registered in the AndroidManifest.xml, so you need to edit the AndroidManifest.xml file, the code is as follows:

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="com.example.servicetest"  
    android:versionCode="1"  
    android:versionName="1.0" >  
  
    <uses-sdk  
        android:minSdkVersion="14"  
        android:targetSdkVersion="17" />  
  
    <application  
        android:allowBackup="true"  
        android:icon="@drawable/ic_launcher"  
        android:label="@string/app_name"  
        android:theme="@style/AppTheme" >  
          
    ……  
  
        <service android:name="com.example.servicetest.MyService" >  
        </service>  
    </application>  
  
</manifest>

In this case, a simple program with Service function is written, and now we will run the program, and click the Start Service button, you can see LogCat print log.

You will see that when you start a Service, it will call the Service onCreate () and onStartCommand () method.

So what if I click on the Start Service button again?

You can see that this time only onStartCommand () method is implemented, onCreate () method is not implemented, why is this? This is because the onCreate () method will only be called when the Service is first created. If the current Service has already been created, the onCreate () method will not be executed anyway, regardless of how the startService () method is called. So you can click on the Start Service button several more times, each time there will only be onStartCommand () method in the print log.

We can also go to the phone’s application management interface to check myService is not running.

Go back to the ServiceTest program and click the Stop Service button to stop MyService.

Service and Activity communication

Above we learned the basic usage of the Service, after starting Service, you can in the onCreate () or onStartCommand () method to perform some specific logic. But then the relationship between Service and Activity is not large, but Activity notice Service about: “You can start.” Then Service to busy their own things. Then there is no way to make the two of them more related to it? For example, in the Activity can be specified to allow Service to perform what task. Of course, only need to make Activity and Service to establish a link just fine.

Observe the code in MyService, you will find that there is always an onBind () method we have not used, this method is used to establish association with the Activity, modify the code in MyService, as follows:

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    private MyBinder mBinder = new MyBinder();  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "onStartCommand() executed");  
        return super.onStartCommand(intent, flags, startId);  
    }  
  
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        Log.d(TAG, "onDestroy() executed");  
    }  
  
    @Override  
    public IBinder onBind(Intent intent) {  
        return mBinder;  
    }  
  
    class MyBinder extends Binder {  
  
        public void startDownload() {  
            Log.d("TAG", "startDownload() executed");  
            // Perform a specific download task
        }  
  
    }  
  
}  

Here we add a MyBinder class inherited from the Binder class, and then add a MyBinder startDownload () method used to perform the download task in the background, of course, here is not really to download something, just a test, so The startDownload () method simply prints a row of logs.

And then modify the code in activity_main.xml to add buttons for binding services and unbind services in the layout file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical" >  
  
    <Button  
        android:id="@+id/start_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Start Service" />  
  
    <Button  
        android:id="@+id/stop_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Stop Service" />  
  
    <Button  
        android:id="@+id/bind_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Bind Service" />  
      
    <Button   
        android:id="@+id/unbind_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Unbind Service"  
        />  
      
</LinearLayout> 

Next, modify the code in MainActivity to associate the MainActivity and MyService with the following code:

public class MainActivity extends Activity implements OnClickListener {  
  
    private Button startService;  
  
    private Button stopService;  
  
    private Button bindService;  
  
    private Button unbindService;  
  
    private MyService.MyBinder myBinder;  
  
    private ServiceConnection connection = new ServiceConnection() {  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  
  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            myBinder = (MyService.MyBinder) service;  
            myBinder.startDownload();  
        }  
    };  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        startService = (Button) findViewById(R.id.start_service);  
        stopService = (Button) findViewById(R.id.stop_service);  
        bindService = (Button) findViewById(R.id.bind_service);  
        unbindService = (Button) findViewById(R.id.unbind_service);  
        startService.setOnClickListener(this);  
        stopService.setOnClickListener(this);  
        bindService.setOnClickListener(this);  
        unbindService.setOnClickListener(this);  
    }  
  
    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.start_service:  
            Intent startIntent = new Intent(this, MyService.class);  
            startService(startIntent);  
            break;  
        case R.id.stop_service:  
            Intent stopIntent = new Intent(this, MyService.class);  
            stopService(stopIntent);  
            break;  
        case R.id.bind_service:  
            Intent bindIntent = new Intent(this, MyService.class);  
            bindService(bindIntent, connection, BIND_AUTO_CREATE);  
            break;  
        case R.id.unbind_service:  
            unbindService(connection);  
            break;  
        default:  
            break;  
        }  
    }  
  
}  

You can see that here we first create an anonymous class of ServiceConnection, which rewrites the onServiceConnected () method and the onServiceDisconnected () method, which are invoked when the Activity is associated with the service and associated with the service. In the onServiceConnected () method, we have passed down to get an instance of MyBinder. With this example, the relationship between Activity and Service becomes very tight. Now we can in the Activity in accordance with the specific scene to call MyBinder in any public method, that is, to achieve the Activity Command Service Service What to do what function.

Of course, now Activity and Service is not linked to it, this feature is in the Bind Service button to complete the click event. You can see that here we are still building an Intent object, and then call the bindService () method to bind the Activity and Service. BindService () method to receive three parameters, the first parameter is just to build the Intent object, the second parameter is created in front of the ServiceConnection instance, the third parameter is a flag, where the incoming BIND_AUTO_CREATE said in the Activity And Service established after the association automatically create Service, which will make MyService onCreate () method to be implemented, but onStartCommand () method will not be implemented.

And then how do we want to relieve the association between Activity and Service? Call the unbindService () method on it, this is the Unbind Service button click event to achieve the logic.

Now let’s run the program again, click on the Bind Service button in MainActivity.

Also note that any Service is generic across the entire application, that is, MyService can not only be associated with MainActivity, but also can be associated with any of the activities, and in the establishment of the association they can get to the same MyBinder instance.

How to destroy Service

In this part of the basic usage of Service, we introduced the simplest case of Destroy Service, click the Start Service button to start Service, and then click the Stop Service button to stop Service, so MyService was destroyed.

So if we are clicking on the Bind Service button? Because the binding service when the designated bit is BIND_AUTO_CREATE, indicating that the Bind Service button when the Service will be created, then how should destroy the Service? In fact, it is very simple, click on the Unbind Service button, the association between the Activity and Service can be lifted.

The above two kinds of destruction methods are well understood. So what if we both clicked the Start Service button and clicked on the Bind Service button? This time you will find that, whether you are a single click on the Stop Service button or Unbind Service button, Service will not be destroyed, the need to click the two buttons, Service will be destroyed. In other words, click the Stop Service button will only stop the Service, click the Unbind Service button will only let Service and Activity release association, a Service must be in any and no association and deal with the stop state will be destroyed.

To confirm that we add a line of print log to the Stop Service and Bindservice button’s click event:

public void onClick(View v) {  
    switch (v.getId()) {  
    case R.id.start_service:  
        Intent startIntent = new Intent(this, MyService.class);  
        startService(startIntent);  
        break;  
    case R.id.stop_service:  
        Log.d("MyService", "click Stop Service button");  
        Intent stopIntent = new Intent(this, MyService.class);  
        stopService(stopIntent);  
        break;  
    case R.id.bind_service:  
        Intent bindIntent = new Intent(this, MyService.class);  
        bindService(bindIntent, connection, BIND_AUTO_CREATE);  
        break;  
    case R.id.unbind_service:  
        Log.d("MyService", "click Unbind Service button");  
        unbindService(connection);  
        break;  
    default:  
        break;  
    }  
}  

And then re-run the program, first click the Start Service button, and then click the Bind Service button, so the service will start up, and the establishment of an association with the Activity. And then click the Stop Service button Service will not be destroyed, and then click the Unbind Service button, Service will be destroyed.

We should always remember in the Service’s onDestroy () method to clean up those no longer use the resources to prevent the Service is destroyed after some of the objects are no longer occupied by the memory.

The relationship between Service and Thread

Many Android beginners may have such doubts, Service and Thread in the end what is the relationship? When should I use Service, when should I use Thread? The answer may be a bit surprised you, because there is no relationship between Service and Thread!

The reason why many people will link them up, mainly because the background of Service background. Thread we all know that is used to open a sub-thread, here to perform some time-consuming operation will not block the main thread of the operation. And Service we initially understand, always think it is used to deal with some background tasks, some of the more time-consuming operation can also be placed here to run, which will make people confused. But if i tell you that Service is actually running in the main thread, do you think it has anything to do with Thread? Let’s take a look at this cruel fact.

In the MainActivity onCreate () method to add a line to print the current thread id statement:

Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());  

And then in the MyService onCreate () method also joined a line to print the current thread id statement:

Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());  

Now re-run the program and click the Start Service button.

You can see that their thread id is exactly the same, which confirmed that the service is indeed running in the main thread, that is, if you are in the Service prepared a very time-consuming code, the program will appear ANR.

Can you exclaim, is not that kidding? What time do I have to use Service? In fact, we should not background and sub-thread together on the line, this is two completely different concepts. Android background means that it’s running is completely dependent on the UI. Even if Activity is destroyed, or the program is closed, as long as the process is still, Service can continue to run. For example, some applications, always need to always maintain a heartbeat connection with the server, you can use Service to achieve. You may ask, the front is not just verified Service is running in the main thread Lane? Where the implementation of the heartbeat has been connected, do not block the main thread of the operation? Of course, but we can create a sub-thread in the service, and then here to deal with time-consuming logic no problem.

Create Front Service

The amount, since in the service also to create a sub-thread, then why not directly created in the Activity? This is because the Activity is difficult to control the Thread, when the Activity is destroyed, there is no other way to re-get to the previously created sub-thread instance. But also in an Activity to create a sub-thread, another Activity can not operate on it. But the Service is different, all the Activity can be associated with the Service, and then can be very convenient to operate the method, even if the Activity was destroyed, and then as long as the re-established with the Service, they can get to the original Service Example of Binder. Therefore, the use of Service to deal with background tasks, Activity can be assured to finish, do not need to worry about the background tasks can not control the situation.

A more standard service can be written as:

@Override  
public int onStartCommand(Intent intent, int flags, int startId) {  
    new Thread(new Runnable() {  
        @Override  
        public void run() {  
            // Start performing background tasks
        }  
    }).start();  
    return super.onStartCommand(intent, flags, startId);  
}  
  
class MyBinder extends Binder {  
  
    public void startDownload() {  
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                // Perform a specific download task
            }  
        }).start();  
    }  
  
}  

Then we look at how to create a front desk Service it, in fact, not complicated, modify the code in MyService, as follows:

public class MyService extends Service {  
  
    public static final String TAG = "MyService";  
  
    private MyBinder mBinder = new MyBinder();  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
        Notification notification = new Notification(R.drawable.ic_launcher,  
                "There is a notice coming", System.currentTimeMillis());  
        Intent notificationIntent = new Intent(this, MainActivity.class);  
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,  
                notificationIntent, 0);  
        notification.setLatestEventInfo(this, "This is the title of the notification", "This is the content of the notice",  
                pendingIntent);  
        startForeground(1, notification);  
        Log.d(TAG, "onCreate() executed");  
    }  
  
    .........  
  
}  

Here is only modify the MyService onCreate () method code. You can see that we first created a Notification object and then called its setLatestEventInfo () method to initialize the layout and data for the notification, and set the click notification to open the MainActivity. And then call the startForeground () method can make MyService into a front service, and will notify the image displayed.

Now run the program again, and click the Start Service or Bind Service button, MyService will be the front service mode to start, and the system status bar will pop up a bar icon, drop the status bar can see the details of the notice.

Android Custom Camera(2)

Through the introduction of an Android custom Camera (一), we have been able to complete a camera based on the demo, of course, there are a lot of attention to the details of the problem, such as the preview direction, set the preview ratio and return the proportion of pictures and so on , The details can see previous blog, this time I will enrich the camera’s function to join the flash mode, square shooting, delay shooting and front and rear camera switching function, then one by one to start it. (There will be a complete source address below).

Flash mode

The camera’s flash mode there are three, automatic, close, open, the code is also better understand, before the camera can switch calls. Note I added a note in code below:

/**
     * turnLightOff
     *
     * @param mCamera
     */
    public void turnLightOff(Camera mCamera) {
        if (mCamera == null) {
            return;
        }
        Camera.Parameters parameters = mCamera.getParameters();
        if (parameters == null) {
            return;
        }
        List<String> flashModes = parameters.getSupportedFlashModes();
        String flashMode = parameters.getFlashMode();
        // Check if camera flash exists
        if (flashModes == null) {
            return;
        }
        if (!Camera.Parameters.FLASH_MODE_OFF.equals(flashMode)) {
            // Turn off the flash
            if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                mCamera.setParameters(parameters);
            } else {
            }
        }
    }

2 automatic mode:

/**
     * turnLightAuto
     *
     * @param mCamera
     */
    public void turnLightAuto(Camera mCamera) {
        if (mCamera == null) {
            return;
        }
        Camera.Parameters parameters = mCamera.getParameters();
        if (parameters == null) {
            return;
        }
        List<String> flashModes = parameters.getSupportedFlashModes();
        // Check if camera flash exists
        if (flashModes == null) {
            // Use the screen as a flashlight (next best thing)
            return;
        }
        String flashMode = parameters.getFlashMode();
        if (!Camera.Parameters.FLASH_MODE_AUTO.equals(flashMode)) {
            // Turn on the flash
            if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                mCamera.setParameters(parameters);
            } else {
            }
        }
    }

3 open

 @param mCamera
     */
    public void turnLightOn(Camera mCamera) {
        if (mCamera == null) {
            return;
        }
        Camera.Parameters parameters = mCamera.getParameters();
        if (parameters == null) {
            return;
        }
        List<String> flashModes = parameters.getSupportedFlashModes();
        // Check if camera flash exists
        if (flashModes == null) {
            // Use the screen as a flashlight (next best thing)
            return;
        }
        String flashMode = parameters.getFlashMode();
        if (!Camera.Parameters.FLASH_MODE_ON.equals(flashMode)) {
            // Turn on the flash
            if (flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                mCamera.setParameters(parameters);
            } else {
            }
        }
    }

Square shot

Here I want to talk about how I do, at present I think because we look at the proportion of framing frames must meet the size of mobile phone support, there are surfaceView and preview the proportion of the same size, so that we can not determine the size of the frame is specific How many, so I achieved a square shot with the way to cover the viewfinder frame, shooting time frame will be covered into a square, in the back of the picture and then cut it into a square can be, in the current project I also In this way, because many mobile phones are directly supporting the square size, where I used two attribute animation to cover the viewfinder, the code is as follows, here is to calculate the height to cover.

/**
     * camera_square
     */
    public void camera_square_0() {
        camera_square.setImageResource(R.drawable.btn_camera_size1_n);

        ValueAnimator anim = ValueAnimator.ofInt(0, animHeight);
        anim.setDuration(300);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int currentValue = Integer.parseInt(animation.getAnimatedValue().toString());
                RelativeLayout.LayoutParams Params = new RelativeLayout.LayoutParams(screenWidth, currentValue);
                Params.setMargins(0, SystemUtils.dp2px(context, 44), 0, 0);
                homeCustom_cover_top_view.setLayoutParams(Params);

                RelativeLayout.LayoutParams bottomParams = new RelativeLayout.LayoutParams(screenWidth, currentValue);
                bottomParams.setMargins(0, screenHeight - menuPopviewHeight - currentValue, 0, 0);
                homeCustom_cover_bottom_view.setLayoutParams(bottomParams);
            }

        });
        anim.start();

        homeCustom_cover_top_view.bringToFront();
        home_custom_top_relative.bringToFront();
        homeCustom_cover_bottom_view.bringToFront();
        index++;
    }

    public void camera_square_1() {
        camera_square.setImageResource(R.drawable.btn_camera_size2_n);

        ValueAnimator anim = ValueAnimator.ofInt(animHeight, 0);
        anim.setDuration(300);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int currentValue = Integer.parseInt(animation.getAnimatedValue().toString());
                RelativeLayout.LayoutParams Params = new RelativeLayout.LayoutParams(screenWidth, currentValue);
                Params.setMargins(0, SystemUtils.dp2px(context, 44), 0, 0);
                homeCustom_cover_top_view.setLayoutParams(Params);

                RelativeLayout.LayoutParams bottomParams = new RelativeLayout.LayoutParams(screenWidth, currentValue);
                bottomParams.setMargins(0, screenHeight - menuPopviewHeight - currentValue, 0, 0);
                homeCustom_cover_bottom_view.setLayoutParams(bottomParams);
            }
        });
        anim.start();
        index = 0;
    }

Delayed shooting

First of all, say the principle of delay shooting, in fact, more than one way to achieve, where I use the thread plus the way the main code is as follows, first recorded a delay time, and then decrement this time every 1s, and finally it is equal to 0 When the implementation of the shooting code, the effect I will not paste it, you can download the code to run to see, that is, a large number of seconds on the screen

new Thread(new Runnable() {
                            @Override
                            public void run() {
                                while (delay_time > 0) {
                                    //Count in seconds
                                    try {
                                        Thread.sleep(1000);
                                    } catch (InterruptedException e) {
                                        mHandler.sendEmptyMessage(AppConstant.WHAT.ERROR);
                                        return;
                                    }
                                    delay_time--;
                                    mHandler.sendEmptyMessage(AppConstant.WHAT.SUCCESS);
                                }
                            }
                        }).start();

Switch the front rear camera

Almost all of the camera program needs this function, must be able to front and rear ah, that in fact, this is also relatively simple to achieve, when the camera is in the process of previewing before and after the switch must first release the camera resources, and then And then open the preview, switch the camera is nothing more than switch cameraId, here look at the next code:

 public void  switchCamera() {
        releaseCamera();
        //This method getNumberOfCameras () is introduced from the API Level 9, get the number of cameras in the normal normal mobile phone only one camera, here I also follow a camera to deal with the
        mCameraId = (mCameraId + 1) % mCamera.getNumberOfCameras();
        mCamera = getCamera(mCameraId);
        if (mHolder != null) {
            startPreview(mCamera, mHolder);
        }
    }

Add watermark

The way to say that the function of the watermark it, plus watermark function is not difficult to achieve, it is rare to draw a good watermark, in fact, watermark is also in the camera to return to the bitmap to join, in fact, is painted with Canvas class, the core The code is as follows, assuming the camera returns the picture shown as bitmap:

Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(tempbitmap, left, top, paint);

Code is generally the case, through the canvas.drawBitmap method to draw up, of course, I am free to draw the position. But you record the location of the watermark when previewing, and then painted up properly.

The following is the source address:

https://github.com/jinguangyue/CustomCamera