Android micro-letter shake-shake function implementation detailed introduction _android

Source: Internet
Author: User
Tags abs sleep static class

Android micro-letter shake function to achieve, the recent learning of sensors, want to realize the function of shaking, the Internet to check some information on the collation. If there is a mistake, please correct me.

Development environment

    1. Android Studio 2.2.1
    2. JDK1.7
    3. API 24
    4. Gradle 2.2.1

Related knowledge points

    1. Acceleration Sensor
    2. Tween Animation
    3. Mobile phone Vibration (vibrator)
    4. Short Sound/Sound playback (Soundpool)

Case:

We then analyze this case, when the user shaking the phone, will trigger the acceleration sensor, the acceleration sensor will call the corresponding interface for us to use, at this time we can do some corresponding animation effects, vibration effects and sound effects. This is the general idea. Specific function points:

The user shakes the two pictures separately, showing the back of the picture
Vibration effect after shaking, sound effect

Based on the simple analysis above, we know what to do, Just now

Build the layout first

Layout has nothing to say, let's look at the code directly

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/" Android "xmlns:tools=" Http://schemas.android.com/tools "android:id=" @+id/activity_main "android:layout_width=" Match_parent "android:layout_height=" match_parent "android:background=" "#ff222222" android:orientation= "vertical" t ools:context= "Com.lulu.weichatshake.MainActivity" > <relativelayout android:layout_width= "match_parent" and 
      roid:layout_height= "Match_parent" > <!--shake the center picture--> <imageview android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" android:layout_centerinparent= "true" android:src= "@mipmap/weichat_ Icon "/> <linearlayout android:gravity=" center "android:orientation=" vertical "android:layout_w Idth= "Match_parent" android:layout_height= "Match_parent" android:layout_alignparenttop= "true" Android:la Yout_alignparentleft= "true" andRoid:layout_alignparentstart= "true" > < top horizontal and picture--> <linearlayout android:gravity= "Center _horizontal|bottom "android:id=" @+id/main_linear_top "android:layout_width=" Match_parent "Android: layout_height= "wrap_content" android:orientation= "vertical" > <imageview android:src= "@mipm Ap/shake_top "android:id=" @+id/main_shake_top "android:layout_width=" Wrap_content "Android:l" ayout_height= "100DP"/> <imageview android:background= "@mipmap/shake_top_line" Android:id
      = "@+id/main_shake_top_line" android:layout_width= "match_parent" android:layout_height= "5DP"/> </LinearLayout> <!--The bottom of the horizontal line and picture--> <linearlayout android:gravity= "Center_horizontal|botto M "android:id=" @+id/main_linear_bottom "android:layout_width=" Match_parent "android:layout_height= "Wrap_content" android:orientation= "vertical" > <imageview android:background= "@mipmap/shake_bottom_line" Android:id= "@+id/main_shake_bottom_line" android:layout_width= "Match_parent" android:layout_height= "5
          DP "/> <imageview android:src=" @mipmap/shake_bottom android:id= "@+id/main_shake_bottom"
    Android:layout_width= "Wrap_content" android:layout_height= "100DP"/> </LinearLayout>

 </LinearLayout> </RelativeLayout> </LinearLayout>

Get the callback interface of the acceleration sensor

Step1: Gets the Sensormanager of the sensor in the OnStart () method

@Override
protected void OnStart () {
  super.onstart ();
  Get Sensormanager responsible for managing sensor
  Msensormanager = ((Sensormanager) Getsystemservice (Sensor_service));
  if (Msensormanager!= null) {
    //Get acceleration sensor
    Maccelerometersensor = Msensormanager.getdefaultsensor (sensor.type_ Accelerometer);
    if (maccelerometersensor!= null) {
      Msensormanager.registerlistener (this, maccelerometersensor, SENSORMANAGER.SENSOR_DELAY_UI);}}

Step2: Then we're going to log out of the sensor in pause.

@Override
protected void OnPause () {
  //Be sure to log out of Msensormanager in pause//
  or it will cause the interface to exit and shake the bug if it is still in effect
  ( Msensormanager!= null) {
    Msensormanager.unregisterlistener (this);
  }
  Super.onpause ();
}

Note: As to why we want to register and unregister the line in OnStart and OnPause, it is because, to prevent the interface exit (including pressing the Home key), the shaking is still in effect (comments in the code)

Step3: In the Registration Listener event method in Step1, we pass in the current Activity object, so that it implements the callback interface, and obtains the following methods

Sensoreventlistener callback Method/////////// @Override public void onsensorchanged (sensorevent

  event) {int type = Event.sensor.getType ();
    if (type = = Sensor.type_accelerometer) {//Get three directional values float[] values = event.values;
    float x = values[0];
    Float y = values[1];

    float z = values[2]; if (Math.Abs (x) > 17 | | Math.Abs (y) > 17 | |
      Math. ABS (z) >) &&!isshake) {isshake = true;
          Todo:2016/10/19 realizes shaking logic, shakes after shaking thread thread = new Thread () {@Override public void run () {
          Super.run ();

            try {log.d (TAG, "onsensorchanged: Shake");
            Start shaking send a hint to show animation effect Mhandler.obtainmessage (Start_shake). Sendtotarget ();
            Thread.Sleep (500); One more jolt. Mhandler.obtainmessage (Again_shake). Sendtotarget ();
            Thread.Sleep (500);

          Mhandler.obtainmessage (End_shake). Sendtotarget ();
          catch (Interruptedexception e) {e.printstacktrace ();
      }
        }
      };
    Thread.Start ();

 @Override public void onaccuracychanged (Sensor Sensor, int accuracy) {}}}}

Note: When the user shaking the phone will call the Onsensorchanged method, you can do some appropriate action

To solve the animation and vibration delay, we opened a child thread to implement.

Child thread will be sent handler message, first start animation effect, and accompanied by vibration and sound, first put the implementation of handler, let's take a look at the vibration and sound initialization animation, vibration and sound implementation

Step 1: First get the vibration-related services, pay attention to the permission. As for the sound effect, we use Soundpool to play, here very thanks to Vincent's post, good initialization soundpool

Shock permission

<uses-permission android:name= "Android.permission.VIBRATE"/>

Initialize Soundpool
msoundpool = new Soundpool (1, Audiomanager.stream_system, 5);
Mweichataudio = Msoundpool.load (This, r.raw.weichat_audio, 1);

Obtain Vibrator Vibration service
Mvibrator = (vibrator) getsystemservice (Vibrator_service);

Note: You may find that Soundpool's construction method is outdated, but don't worry that it is outdated after Api21, so it's not too "outdated"

Step2: Next we will introduce the implementation of the handler, in order to avoid the activity memory leak, the use of soft reference

private static class MyHandler extends Handler {private weakreference<mainactivity> mreference;
  Private Mainactivity mactivity;
    Public MyHandler (mainactivity activity) {mreference = new weakreference<mainactivity> (activity);
    if (mreference!= null) {mactivity = Mreference.get ();
    @Override public void Handlemessage (msg) {super.handlemessage);
        Switch (msg.what) {case Start_shake://this method requires the caller to hold the permission vibrate.
        MActivity.mVibrator.vibrate (300);
        Beep MActivity.mSoundPool.play (Mactivity.mweichataudio, 1, 1, 0, 0, 1);
        MActivity.mTopLine.setVisibility (view.visible);
        MActivity.mBottomLine.setVisibility (view.visible);
      Mactivity.startanimation (false);//Parameter meaning: (not back) that is to say two pictures scattered animation break;
        Case AGAIN_SHAKE:mActivity.mVibrator.vibrate (300);
      Break
 Case End_shake://end of the whole effect, set the vibration to False       Mactivity.isshake = false;
        Show the top and bottom two kinds of picture back effect mactivity.startanimation (true);
    Break

 }
  }
}

Note: The content is not much said, code comments in detail, there is a startanimation method
Let me start by saying its arguments, true indicates that two pictures from the layout are animated from open to closed, and vice versa, false is from off to open, on code

The implementation of Step3:startanimaion method

/** * Open Shake animation * * @param isback is the return of the initial state/private void Startanimation (Boolean isback) {//animation coordinates the position of the movement of the type is relative to their own

  int type = animation.relative_to_self;
  float topfromy;
  float Toptoy;
  float bottomfromy;
  float Bottomtoy;
    if (isback) {topfromy = -0.5f;
    Toptoy = 0;
    bottomfromy = 0.5f;
  Bottomtoy = 0;
    else {topfromy = 0;
    Toptoy = -0.5f;
    bottomfromy = 0;
  Bottomtoy = 0.5f; The animated effect of the above picture translateanimation Topanim = new Translateanimation (type, 0, type, 0, type, topfromy, type, topt
  OY);
  Topanim.setduration (200);

  The animation stops at the last frame, or it returns to the state Topanim.setfillafter (true) before it was executed; The bottom of the animation effect translateanimation Bottomanim = new Translateanimation (type, 0, type, 0, type, bottomfromy, type, Botto
  Mtoy);
  Bottomanim.setduration (200);

  Bottomanim.setfillafter (TRUE); 
      We must not forget that when we come back, the two lines in our midst need to be gone out if (isback) {Bottomanim.setanimationlistener (new Animation.animationlistener () { @Override Public void Onanimationstart (Animation Animation) {} @Override public void Onanimationrepeat (Animation Animation) {} @Override public void Onanimationend (Animation Animation) {//When the animation is over, gone the middle two lines away from the placeholder MTo
        Pline.setvisibility (View.gone);
      Mbottomline.setvisibility (View.gone);
  }
    });
  //Set Animation mtoplayout.startanimation (Topanim);

Mbottomlayout.startanimation (Bottomanim);

 }

The core code has been introduced, but there are some small details to mention

Details

You have to gone the top and bottom two horizontal lines before you initialize the view, and gone is not a placeholder.

Mtopline.setvisibility (View.gone);
Mbottomline.setvisibility (View.gone);

2. Our best shake is only the vertical screen (after all, I have not seen the horizontal screen shaking), plus the following code

Set only vertical screen
Setrequestedorientation (activityinfo.screen_orientation_portrait);

Complete code

Source code I have been sent on the GitHub, I hope that we support a lot!

Thank you for reading, I hope to help you, thank you for your support for this site!

Related Article

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.