Android入门

  1. android studio的配置

    1. view: 位于android.view包中 View的子类位于android.widget包中
      • 属性
        1. id
        2. background
        3. padding 内边距 上下左右
    2. viewGroup 控制view如何拜访
      1. layoutParams
        1. layout_height match_pa rent 与容器相同 wrap_content与内容为主
        2. layout_width
      2. marginLayoutParams 外边距
        1. layout_marginTop
        2. layout_marginBottom
        3. layout_marginStart
        4. layout_marginEnd
  2. 布局管理器

    1. 相对布局管理器RelativeLayout
      1. 布局管理器属性
        1. gravity子组件摆放
        2. ignoregravity:[组件id] 无视
      2. 子组件属性
        1. layout_above[组件id] 组件相对于参考位置
        2. layout_alignParentBottom [bool] 组件相对于父容器
        3. layout_alingnBottom [组件id] 组件相对于参考位置的边界
        4. layout_centerHorizontal 位于布局管理器的位置
    2. 线性布局管理器LinearLayout
      1. 布局管理器的属性
        1. orientation
          1. vertical 垂直
          2. horizontal 水平
        2. gravity 显示效果 center,right|bottom
      2. 组件属性
        1. layout_weight:
    3. 帧布局管理器FrameLayout
      1. 布局管理器的属性
        1. foreground 最前端图片
        2. foregroundGravity前端图片位置
    4. 表格布局管理器TableLayout [可跨列]
      1. 布局管理器的属性
        1. TableRow 行
        2. collapseColumns 隐藏列
        3. stretchColumns 允许被拉伸
        4. shrinkColumns 允许被收缩
    5. 网格布局管理器GridLayout [可跨行列]
      1. 布局管理器的属性
        1. columnCount 列数
        2. orientation 水平或垂直排列
        3. rowCount 行数
      2. 组件属性
        1. layout_column 指定位于第几列
        2. layout_columnSpan 指定横向跨几列
        3. layout_columnWeight 水平方向权重
        4. layout_gravity 方式
        5. layout_row 指定位于第几行
        6. layout_rowSpan 指定跨几行
        7. layout_rowWeight 指定垂直方向权重
  3. 组件

    1. 文本框组件textView

      1. text [string values]
      2. textSize [sp]
      3. textColor
      4. singleLine 单行文本框
    2. 编辑框组件EditText

      1. hint 提示文本
      2. inputType 输入类型 [textMutline]
      3. drawableLeft/drawableStart/drawableEnd/drawableBottom/drawablePadding
      4. lines
      5. getText()获取编辑框内容
    3. 按钮Button

      1. Text 内容
      2. 监听器
      3. 匿名内部类
      4. xml中指定
    4. 图片按钮 ImageButton

    5. 单选框radioButton

      1. radioGroup 遍历getChildAt 获取单个radioButton
      2. radioGroup onCheckedChangeListener checkedId–>radioButton
    6. 复选框checkBox

    7. 时间dataPicker

      1. init() 初始化
      2. onDataChange 事件
    8. TimePicker时钟

    9. 计时器Chronometer

      1. setBase 设置起始时间
      2. setFormat 设置显示时间格式
      3. start 指定开始计时
      4. stop 指定停止计时
      5. onChrometerTick
    10. 进度条progressBar

      1. style
        1. style="?android:attr/progressBarStyleHorizontal"
        2. style="@android:style/Widget.ProgressBar.Horizontal
        3. style="@android:style/Widget.ProgressBar.Inverse
      2. max 最大值
      3. progress 当前值
    11. 拖动条SeekBar

    12. 星级评分条

      1. numstarts 星星总数
      2. rating 点亮个数
      3. stepSize
      4. isIndicator 是否不可更改
    13. 图像视图 ImageView

      1. scaleType
        1. center 保持图像大小 以ImageView为中心 图像大截取
        2. centerInside 原图大按照比例缩放 原图小 居中显示
        3. centerCrop 原图大按比例缩放 原图小 按宽高比例放大
        4. matrix 原图大小显示在左上角
        5. fitXy 填充
        6. fitStart 以ImageView的高度放大缩小 显示在上方
        7. fitCenter 以ImageView的高度放大缩小 显示在中间
        8. fitEnd 以ImageView的高度放大缩小 显示在下方
      2. adjustViewBounds 是否调整
      3. maxHeight
      4. maxWidth
    14. GridView视图管理器

      1. numColumn 几列
      2. columnWidth 每列宽度
      3. verticalSpace 横向空隙
      4. Adapter 适配器
        1. BaseAdapter
                      public class ImageAdapter extends BaseAdapter {
                      private Context imageContext;
          
                  public ImageAdapter(Context c) {
                          imageContext = c;
                      }
          
                      @Override
                  public int getCount() {
                          return imageResource.length;
                      }
          
                      @Override
                  public Object getItem(int position) {
                          return null;
                      }
          
                      @Override
                  public long getItemId(int position) {
                          return 0;
                      }
          
                      @Override
                      public View getView(int position, View convertView, ViewGroup parent) {
                          ImageView imageView;
                          if (convertView == null) {
                              imageView = new ImageView(imageContext);
                              imageView.setLayoutParams(new GridView.LayoutParams(300, 150));
                              imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                          } else {
                              imageView = (ImageView) convertView;
                          }
                          imageView.setImageResource(imageResource[position]);
                      return imageView;
                  }
              }
          
          
        2. SimpleAdapter
              List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
              for (int i = 0; i < imageResource.length; i++) {
                  Map<String, Object> map = new HashMap<>();
                  map.put("img", imageResource[i]);
                  list.add(map);
          }
          SimpleAdapter simpleAdapter = new SimpleAdapter(this, list, R.layout.cell, new String[]{"img"}, new int[]{R.id.image});
          gridView.setAdapter(simpleAdapter);
          
        3. ArrayAdapter
        4. SimpleCursorAdapter
    15. Spinner 下拉列表

      1. setOnItemSelectedListener 选中监听器
      2. entries 数组资源
    16. ScrollView 滚动条

      1. 向下滚动条
      2. 横向滚动条HorizontalScrollView
    17. 选项卡

      1. TabHost
      2. TabWidget
      3. TabContent
        <?xml version="1.0" encoding="utf-8"?>
        <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        android:orientation="vertical">
        
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
            android:layout_height="wrap_content"></TabWidget>
        
            <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        </LinearLayout>
        </TabHost>
        
        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/left1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
            android:gravity="center"
                android:text="Hello World"
                android:textSize="30sp" />
        </LinearLayout>
        
        package com.example.tabhost;
        
        import android.os.Bundle;
            import android.view.LayoutInflater;
        import android.widget.TabHost;
        
        import androidx.appcompat.app.AppCompatActivity;
        
            public class MainActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                TabHost tabHost = findViewById(android.R.id.tabhost);
                //初始化
                tabHost.setup();
                LayoutInflater layoutInflater = LayoutInflater.from(this);
                layoutInflater.inflate(R.layout.tab1, tabHost.getTabContentView());
                layoutInflater.inflate(R.layout.tab2, tabHost.getTabContentView());
                layoutInflater.inflate(R.layout.tab3, tabHost.getTabContentView());
                tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("测试1").setContent(R.id.left1));
                tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("测试2").setContent(R.id.right));
                tabHost.addTab(tabHost.newTabSpec("tab3").setIndicator("测试3").setContent(R.id.left3));
            }
        }
        
        
  4. activity

    1. 概述 代表手机屏幕的一屏

    2. 4种状态度

      1. 运行
      2. 暂停
      3. 停止
      4. 销毁
    3. 生命周期

      1. onCreate
      2. onStart
      3. onResume
      4. onPause
      5. onStop
      6. onDestory
      7. onRestart
    4. 创建并配置

      1. 创建类
      2. 继承Activity
      3. 重写onCreate方法
      4. setContent
    5. 启动与关闭

      1. startActivity(Intent)
      2. finish()
        package com.example.activity;
        
        import android.content.Intent;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.View;
        import android.widget.Button;
        import android.widget.Toast;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        public class MainActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                Button button = findViewById(R.id.bt);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "测试", Toast.LENGTH_SHORT).show();
                        Log.i("测试", "测试");
                        Intent intent = new Intent(MainActivity.this, MyActivity.class);
                        startActivity(intent);
        
                    }
                });
                Button button1 = findViewById(R.id.bt1);
                button1.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        finish();
                    }
                });
        
            }
        

      }
      ```

    6. 多个Activity交换数据

      • 储存值

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button button = findViewById(R.id.save);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //获取数据
                    String name = ((EditText) (findViewById(R.id.name))).getText().toString();
                    String phone = ((EditText) (findViewById(R.id.phone))).getText().toString();
                    String adress = ((EditText) (findViewById(R.id.adress))).getText().toString();
                    String deatilAdress = ((EditText) findViewById(R.id.deatilAdress)).getText().toString();
                    //验证
                    if (!"".equals(name) && !"".equals(phone) && !"".equals(adress) && !"".equals(deatilAdress)) {
                        //创建intent
                        Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                        Bundle bundle = new Bundle();
                        //储存值
                        bundle.putCharSequence("name", name);
                        bundle.putCharSequence("phone", phone);
                        bundle.putCharSequence("adress", adress);
                        bundle.putCharSequence("deatilAdress", deatilAdress);
                        intent.putExtras(bundle);
                        startActivity(intent);
                    } else {
                        Toast.makeText(MainActivity.this, "请将收货地址填写完整!!", Toast.LENGTH_SHORT).show();
            }
        
                }
            });
        }
        
        
      • 获取值

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main2);
                Bundle bundle = getIntent().getExtras();
                String name = bundle.getString("name");
                String phone = bundle.getString("phone");
                String adress = bundle.getString("adress");
                String deatilAdress = bundle.getString("deatilAdress");
                ((TextView) findViewById(R.id.name)).setText(name);
                ((TextView) findViewById(R.id.phone)).setText(phone);
                ((TextView) findViewById(R.id.adress)).setText(adress + deatilAdress);
            }
        }
        
        
    7. 切换Activity返回结果

          @Override
          protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
              super.onActivityResult(requestCode, resultCode, data);
              //返回后的操作
              if (requestCode == 0x1234 && resultCode == 0x1234) {
                  //获取数据包
                  Bundle bundle = data.getExtras();
                  int imageId = bundle.getInt("imageId");
                  //设置头像
                  ImageView imageView = findViewById(R.id.image);
                  imageView.setImageResource(imageId);
          }
          }
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              Button button = findViewById(R.id.choose);
              button.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                      startActivityForResult(intent, 0x1234);
                  }
              });
          }
      
          private int[] imageResource = new int[]{
                  R.drawable.img1, R.drawable.img1, R.drawable.img1, R.drawable.img1, R.drawable.img1, R.drawable.img1
          };
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main2);
              GridView gridView = findViewById(R.id.gridView);
              List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
              for (int i = 0; i < imageResource.length; i++) {
                  Map<String, Object> map = new HashMap<>();
                  map.put("image", imageResource[i]);
                  list.add(map);
              }
              SimpleAdapter simpleAdapter = new SimpleAdapter(this, list, R.layout.model, new String[]{"image"}, new int[]{R.id.img});
              gridView.setAdapter(simpleAdapter);
              gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                      Intent intent = getIntent();
                      Bundle bundle = new Bundle();
                      bundle.putInt("imageId", imageResource[position]);
                      intent.putExtras(bundle);
                      setResult(0x1234, intent);
                      finish();
                  }
              });
          }
      
    8. Fragment

      1. 生命周期
      2. Fragment的创建
      3. 在Activity中添加Fragment
      4. 实例代码
        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
        
            <LinearLayout
                android:id="@+id/test"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"></LinearLayout>
            <!--按钮-->
            <GridLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:columnCount="6"
                android:paddingBottom="5dp">
        
                <TextView
                    android:layout_width="20dp"
                    android:layout_height="wrap_content"
                    android:layout_column="0" />
        
                <ImageButton
                    android:id="@+id/message"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="1"
                    android:layout_columnWeight="1"
                    android:layout_marginStart="20dp"
                    android:background="#00FFFFFF"
                    android:scaleType="center"
                    android:src="@drawable/message" />
        
                <ImageButton
                    android:id="@+id/contact"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="2"
                    android:layout_columnWeight="1"
                    android:background="#00FFFFFF"
                    android:scaleType="center"
                    android:src="@drawable/contact" />
        
                <ImageButton
                    android:id="@+id/discovery"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="3"
                    android:layout_columnWeight="1"
                    android:layout_gravity="center"
                    android:background="#00FFFFFF"
                    android:src="@drawable/discovery" />
        
                <ImageButton
                    android:id="@+id/my"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="4"
                    android:layout_columnWeight="1"
                    android:background="#00FFFFFF"
                    android:scaleType="center"
                    android:src="@drawable/my" />
        
                <TextView
                    android:layout_width="20dp"
                    android:layout_height="wrap_content"
                    android:layout_column="5" />
            </GridLayout>
        </RelativeLayout>	
        
        package com.example.test;
        
        import android.app.Fragment;
        import android.os.Bundle;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        
        import androidx.annotation.Nullable;
        
        /** 创建Fragment */
        public class ContactFrament extends Fragment {
        @Nullable
        @Override
        public View onCreateView(
            LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.contact, container, false);
            return view;
        }
        }
        
        
        package com.example.test;
        
        import android.app.Fragment;
        import android.app.FragmentTransaction;
        import android.os.Bundle;
        import android.view.View;
        import android.widget.ImageButton;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        /** * 使用与切换Fragment */
        public class MainActivity extends AppCompatActivity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ImageButton messageButton = findViewById(R.id.message);
        
            View.OnClickListener onClickListener =
                new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
                    Fragment f = null;
                    switch (v.getId()) {
                    case R.id.message:
                        f = new MessageFragment();
                        break;
                    case R.id.contact:
                        f = new ContactFrament();
                        break;
                    case R.id.discovery:
                        f = new DiscoveryFragment();
                        break;
                    case R.id.my:
                        f = new MyFragment();
                        break;
                    default:
                        break;
                    }
                    fragmentTransaction.replace(R.id.test, f);
                    fragmentTransaction.commit();
                }
                };
            messageButton.setOnClickListener(onClickListener);
            ImageButton contactButton = findViewById(R.id.contact);
            contactButton.setOnClickListener(onClickListener);
            findViewById(R.id.discovery).setOnClickListener(onClickListener);
            findViewById(R.id.my).setOnClickListener(onClickListener);
        }
        }
        
        
    9. Intent对象

      1. 属性

        1. Component name
        2. Action与Data
            <uses-permission android:name="android.permission.SEND_SMS" />
            <uses-permission android:name="android.permission.CALL_PHONE" />
        
            ImageButton telButton = findViewById(R.id.tel);
            ImageButton messageButton = findViewById(R.id.message);
            View.OnClickListener onClickListener =
                new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    switch (v.getId()) {
                    case R.id.tel:
                        intent.setAction(Intent.ACTION_DIAL);
                        intent.setData(Uri.parse("tel:1383838438"));
                        startActivity(intent);
                        break;
                    case R.id.message:
                        intent.setAction(Intent.ACTION_SENDTO);
                        intent.setData(Uri.parse("smsto:10086"));
                        intent.putExtra("sms_body", "测试");
                        startActivity(intent);
                    default:
                        break;
                    }
                }
                };
            telButton.setOnClickListener(onClickListener);
            messageButton.setOnClickListener(onClickListener);
        
      2. Extras属性 存放和获取数据

      3. Flag属性 FLAG_ACTIVITY_NO_HISTORY

      4. Intent种类

        1. 显示Intent
        2. 隐式Intent
  5. 事件和手势

    1. 单击事件
    2. 长按事件
      //注册事件
          findViewById(R.id.button)
              .setOnLongClickListener(
                  new View.OnLongClickListener() {
                  @Override
                  public boolean onLongClick(View v) {
                      registerForContextMenu(v);
                      openContextMenu(v);
                      return true;
                  }
                  });
      //创建菜单
      @Override
      public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
          super.onCreateContextMenu(menu, v, menuInfo);
          menu.add("收藏");
          menu.add("举报");
      }
      
    3. 物理按键事件
      //按键事件
      @Override
      public boolean onKeyDown(int keyCode, KeyEvent event) {
      //判断按键
          if (keyCode == KeyEvent.KEYCODE_BACK) {
          exit();
          return true;
          }
          return false;
      }
      //退出
      private void exit() {
          if (System.currentTimeMillis() - exitTime >= 2000) {
          Toast.makeText(MainActivity.this, "再按一次返回键退出", Toast.LENGTH_SHORT).show();
          exitTime = System.currentTimeMillis();
          } else {
          finish();
          System.exit(0);
          }
      }
      
    4. 触摸事件
          final Hat hat = new Hat(this);
          hat.setOnTouchListener(
              new View.OnTouchListener() {
              @Override
              public boolean onTouch(View v, MotionEvent event) {
                  Toast.makeText(MainActivity.this, String.valueOf(hat.hatX), Toast.LENGTH_SHORT).show();
                  Toast.makeText(MainActivity.this, String.valueOf(event.getX()), Toast.LENGTH_SHORT)
                      .show();
                  hat.hatX = event.getX() - 310;
                  hat.hatY = event.getY() - 200;
                  hat.invalidate();
                  return true;
              }
              });
          ((FrameLayout) findViewById(R.id.frameLayout)).addView(hat);
      
      package com.jamin.event;
      
      import android.content.Context;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.graphics.Canvas;
      import android.graphics.Paint;
      import android.view.View;
      
      /**
      * @author Jamin <br>
      * @date 2019 /10/2 16:19 <br>
      * @desc 帽子 <br>
      */
      public class Hat extends View {
      public float hatX;
      public float hatY;
      
      public Hat(Context context) {
      
          super(context);
          hatX = 100;
          hatY = 100;
      }
      
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
          Paint paint = new Paint();
          Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.hat);
          canvas.drawBitmap(bitmap, hatX, hatY, paint);
          if (bitmap.isRecycled()) {
          bitmap.recycle();
          }
      }
      }
      
      
    5. 单击事件与触摸事件的区别
      1. 单击事件只触发一次
      2. 触摸事件触发两次
      3. 先触发单击事件的按下再抬起 如果返回true结束,返回false会再触发单击事件
    6. 手势检测 [查看相册的实例]
      package com.jamin.event;
      
      import android.os.Bundle;
      import android.view.GestureDetector;
      import android.view.MotionEvent;
      import android.widget.ImageView;
      import android.widget.ViewFlipper;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      public class Main2Activity extends AppCompatActivity implements GestureDetector.OnGestureListener {
          final int DISTANCE = 50;
          private int[] imageResource =
              new int[] {
              R.mipmap.img1, R.mipmap.img2, R.mipmap.img3, R.mipmap.img4, R.mipmap.img5, R.mipmap.img6
              };
          private GestureDetector detector;
          private ViewFlipper viewFlipper;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main2);
          detector = new GestureDetector(Main2Activity.this, this);
          viewFlipper = findViewById(R.id.viewFlipper);
          for (int i = 0; i < imageResource.length; i++) {
              ImageView imageView = new ImageView(Main2Activity.this);
              imageView.setImageResource(imageResource[i]);
              viewFlipper.addView(imageView);
          }
          }
      
          @Override
          public boolean onDown(MotionEvent e) {
          return false;
          }
      
          @Override
          public void onShowPress(MotionEvent e) {}
      
          @Override
          public boolean onSingleTapUp(MotionEvent e) {
          return false;
          }
      
          @Override
          public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
          return false;
          }
      
          @Override
          public void onLongPress(MotionEvent e) {}
      
          @Override
          public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
          // 向右边划
          if (e1.getX() - e2.getX() > DISTANCE) {
      
              viewFlipper.showPrevious();
              return true;
          } else if (e2.getX() - e1.getX() > DISTANCE) {
              viewFlipper.showNext();
              return true;
          }
          return false;
          }
      
          @Override
          public boolean onTouchEvent(MotionEvent event) {
          return detector.onTouchEvent(event);
          }
      }
      
      
  6. android应用的资源

    1. 字符串资源

    2. 颜色资源

    3. 尺寸资源dimans

    4. drawable资源

          <?xml version="1.0" encoding="utf-8"?>
          <selector xmlns:android="http://schemas.android.com/apk/res/android">
              <item android:color="#f60" android:state_focused="true" />
              <item android:color="#0a0" android:state_focused="false" />
          </selector>	
      
    5. mipmap资源

    6. 主题资源 Theme按钮,自定义style

    7. 菜单资源文件

      1. 选项菜单
        • 重写onCreateOptionsMenu()方法 getMenuInflater().inflate();new Intent(),startActivity()}
        • 重写onOptionsItemSelected()方法switch (item.getItemId()) {new Intent(),startActivity()}
      2. 上下文菜单
        • 重写onCreateContextMenu() getMenuInflater().inflate(R.menu.menu, menu);
        • 重写onContextItemSelected() switch(item.getItemId())
    8. android 国际化

      1. values-en-rUS
      2. values-Zh-rCN
      3. values-zh-rTW
  7. ActionBar 未完成

    1. 显示与关闭ActionBar
      1. 使用themeandroid:theme="@style/Theme.AppCompat.Light.NoActionBar"
    2. ActionBar Tab
    3. 层级式导航
          //开启返回按钮
          if (NavUtils.getParentActivityName(Main2Activity.this) != null) {
          getSupportActionBar().setDisplayHomeAsUpEnabled(true);
      }
      
  8. 消息,通知

    1. 提示Toast
    2. 对话框AlertDialog
      1. 确定取消对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
                        alertDialog.setIcon(R.drawable.ic_launcher_background);
                        alertDialog.setTitle("标题");
                        alertDialog.setMessage("内容");
                        alertDialog.setButton(
                            DialogInterface.BUTTON_NEGATIVE,
                            "取消",
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(MainActivity.this, "您点击了取消按钮", Toast.LENGTH_SHORT).show();
                            }
                            });
        
                        alertDialog.setButton(
                            DialogInterface.BUTTON_POSITIVE,
                            "确定",
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(MainActivity.this, "您点击了确定按钮", Toast.LENGTH_SHORT).show();
                            }
                            });
                        alertDialog.show();
                    }
        
      2. 列表对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setIcon(R.drawable.ic_launcher_background);
                        builder.setTitle("请选择");
                        builder.setItems(
                            strings,
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(
                                        MainActivity.this, "您选择的是" + strings[which], Toast.LENGTH_SHORT)
                                    .show();
                            }
                            });
                        builder.create().show();
                    }
        
      3. 单选对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setTitle("测试");
                        builder.setSingleChoiceItems(
                            strings,
                            0,
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(
                                        MainActivity.this, "您选择的是" + strings[which], Toast.LENGTH_SHORT)
                                    .show();
                            }
                            });
                        builder.setPositiveButton("确认", null);
                        builder.create().show();
                    }
        
      4. 多选对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setTitle("测试");
                        final boolean[] booleans = new boolean[] {true, false, false, true};
                        builder.setMultiChoiceItems(
                            strings,
                            booleans,
                            new DialogInterface.OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                                Toast.makeText(
                                        MainActivity.this, "您选择的是" + booleans[which], Toast.LENGTH_SHORT)
                                    .show();
                            }
                            });
                        builder.setPositiveButton("确认", null);
                        builder.create().show();
                    }
        
    3. 通知Notification
      // 通知管理器
          NotificationManager notificationManager =
              (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
          // 通知对象
          Notification.Builder notification = new Notification.Builder(MainActivity.this);
          // 打开后自动关闭
          notification.setAutoCancel(true);
          // 标题
          notification.setContentTitle("通知标题");
          // 内容
          notification.setContentText("通知内容");
          // 图标
          notification.setSmallIcon(R.mipmap.ic_launcher);
          // 通知发送时间
          notification.setWhen(System.currentTimeMillis());
          // 设置声音和振动
          notification.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
          //    创建一个启动的Intent
          Intent intent = new Intent(MainActivity.this, Main2Activity.class);
          PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
          notification.setContentIntent(pendingIntent);
          notificationManager.notify(NOTIFYID, notification.build());
      
    4. 广播
      //  发送广播
      Intent intent = new Intent();
      intent.setAction("ceshi");
      sendBroadcast(intent);
      
      package com.jamin.boardcastreceiver;
      import android.app.AlertDialog;
      import android.content.BroadcastReceiver;
      import android.content.Context;
      import android.content.DialogInterface;
      import android.content.Intent;
      import android.view.WindowManager;
      import android.widget.Toast;
      
      /**
      * @author Jamin <br>
      * @date 2019/10/8 10:45 <br>
      * @desc 接收广播 <br>
      */
      public class Receiver extends BroadcastReceiver {
      private static final String ACTION1 = "ceshi";
      
      @Override
      public void onReceive(final Context context, Intent intent) {
      //      收到广播回复
      if (intent.getAction().equals(ACTION1)) {
      AlertDialog alertDialog = new AlertDialog.Builder(context).create();
      alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST);
      alertDialog.setIcon(R.mipmap.ic_launcher);
      alertDialog.setTitle("测试");
      alertDialog.setMessage("测试内容");
      alertDialog.setButton(
      DialogInterface.BUTTON_NEGATIVE,
      "取消",
      new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
      Toast.makeText(context, "收到测试信息", Toast.LENGTH_SHORT).show();
      }
      });
      alertDialog.setButton(
      DialogInterface.BUTTON_POSITIVE,
      "确定",
      new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
      Toast.makeText(context, "收到测试信息", Toast.LENGTH_SHORT).show();
      }
      });
      alertDialog.show();
      }
      }
      }
      
    5. 设置闹钟
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          final TimePicker timePicker = findViewById(R.id.timePicker);
          timePicker.setIs24HourView(true);
          findViewById(R.id.setting)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      // 创建intent对象
                      Intent intent = new Intent(MainActivity.this, AlarmActivity.class);
                      // 获取显示闹钟的pendingIntent对象
                      PendingIntent pendingIntent =
                          PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
                      // 获取AlarmManager对象
                      AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                      //                设置闹钟时间
                      Calendar calendar = Calendar.getInstance();
                      calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
                      calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());
                      calendar.set(Calendar.SECOND, 0);
                      //   设置一个闹钟
                      alarmManager.set(
                          AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
                      Toast.makeText(MainActivity.this, "设置成功", Toast.LENGTH_SHORT).show();
                      }
                  });
          }
      
  9. 画图与动画

    1. 绘制矩形
      Paint paint = new Paint();
          paint.setColor(0xFFFF0000);
          paint.setAntiAlias(true);
          paint.setTextAlign(Paint.Align.LEFT);
          paint.setTextSize(30);
          canvas.drawText("测试", 105, 102, paint);
      
    2. 绘制文字
      Paint paint = new Paint();
          String path = Environment.getExternalStorageDirectory() + "/1.jpg";
          Bitmap bitmap = BitmapFactory.decodeFile(path);
          canvas.drawBitmap(bitmap, 0, 0, paint);
      
    3. 绘制图片
      Paint paint = new Paint();
          String path = Environment.getExternalStorageDirectory() + "/1.jpg";
          Bitmap bitmap = BitmapFactory.decodeFile(path);
          canvas.drawBitmap(bitmap, 0, 0, paint);
      
    4. 绘制路径
      Paint paint = new Paint();
      paint.setColor(0xFF000000);
      paint.setAntiAlias(true);
      paint.setStrokeWidth(1);
      paint.setTextSize(30);
      paint.setStyle(Paint.Style.STROKE);
      Path path = new Path();
      path.addCircle(100, 200, 60, Path.Direction.CW);
      //    canvas.drawPath(path, paint);canvas.drawPath(path, paint);
      canvas.drawTextOnPath("中华人民共和国", path, 100, 200, paint);
      
    5. 逐帧动画
          <?xml version="1.0" encoding="utf-8"?>
          <!--逐帧动画资源文件-->
          <animation-list xmlns:android="http://schemas.android.com/apk/res/android">
              <item
                  android:drawable="@mipmap/img1"
                  android:duration="60" />
              <item
                  android:drawable="@mipmap/img2"
                  android:duration="60" />
              <item
                  android:drawable="@mipmap/img3"
                  android:duration="60" />
              <item
                  android:drawable="@mipmap/img4"
                  android:duration="60" />
          </animation-list>
      
      <!--使用动画资源-->
          android:background="@drawable/anim"
      
    6. 补间动画
      1. 透明度渐变动画
            <?xml version="1.0" encoding="utf-8"?>
            <set xmlns:android="http://schemas.android.com/apk/res/android">
                <!-- 持续时间 完全透明到完全不透明-->
                <alpha
                    android:duration="2000"
                    android:fromAlpha="0"
                    android:toAlpha="1" />
            </set>
        
                //              使用动画资源
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim4);
                imageView.startAnimation(animation);
        
    7. 旋转动画
          <?xml version="1.0" encoding="utf-8"?>
          <set xmlns:android="http://schemas.android.com/apk/res/android">
              <!--开始角度 最终角度   xy轴  持续时间-->
              <rotate
                  android:duration="2000"
                  android:fromDegrees="0"
                  android:pivotX="50%"
                  android:pivotY="50%"
                  android:toDegrees="360" />
          </set>
      
    8. 缩放动画
      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
          <!--持续时间 从xy的0.5到1 中心点-->
          <scale
              android:duration="2000"
              android:fromXScale="0.5"
              android:fromYScale="0.5"
              android:pivotX="50%"
              android:pivotY="50%"
              android:toXScale="1"
              android:toYScale="1" />
      </set>
      
      
    9. 平移动画
      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
      <!--起始点到终点 持续时间-->
      <translate
      android:duration="2000"
      android:fromXDelta="0"
      android:fromYDelta="0"
      android:toXDelta="300"
      android:toYDelta="0" />
      </set>
      
  10. 音频视频

    1. 音频
      package com.example.musicvideo;
      
      import android.media.MediaPlayer;
      import android.net.Uri;
      import android.os.Bundle;
      import android.os.Environment;
      import android.util.Log;
      import android.view.View;
      import android.widget.ImageButton;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      /**
          * @author Jamin
          * @date 2019/10/9
          * @desc 使用mediaPlayer简易播放器
          */
      public class MainActivity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          final MediaPlayer mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.mp31);
          findViewById(R.id.start)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      //                  音频播放
                      mediaPlayer.start();
                      }
                  });
          findViewById(R.id.pause)
              .setOnClickListener(
                  new View.OnClickListener() {
                      //                音频暂停
                      @Override
                      public void onClick(View v) {
                      mediaPlayer.pause();
                      }
                  });
          findViewById(R.id.stop)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      //                  音频停止
                      mediaPlayer.pause();
                      mediaPlayer.seekTo(0);
                      }
                  });
      
          String path = Environment.getExternalStorageDirectory() + "/mp31.mp3";
          Log.i("测试", path);
          final MediaPlayer mediaPlayer1 = MediaPlayer.create(MainActivity.this, Uri.parse(path));
          final ImageButton playPause = findViewById(R.id.play);
          playPause.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  if (mediaPlayer1.isPlaying()) {
                      mediaPlayer1.pause();
                      ((ImageButton) v).setImageDrawable(getResources().getDrawable(R.mipmap.start));
                  } else {
                      mediaPlayer1.start();
                      ((ImageButton) v).setImageDrawable(getResources().getDrawable(R.mipmap.pause));
                  }
                  }
              });
          ImageButton stop = findViewById(R.id.stop2);
          stop.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  mediaPlayer1.pause();
                  mediaPlayer1.seekTo(0);
                  playPause.setImageDrawable(getResources().getDrawable(R.mipmap.start));
                  }
              });
          }
      }
      
      
          ListView listView = findViewById(R.id.listView);
          // 音频属性,使用场景 音效类型
          AudioAttributes audioAttributes =
              new AudioAttributes.Builder()
                  .setUsage(AudioAttributes.USAGE_MEDIA)
                  .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                  .build();
          // 创建soundPool对象 配置相关参数
          final SoundPool soundPool =
              new SoundPool.Builder().setAudioAttributes(audioAttributes).setMaxStreams(10).build();
          //    将音频资源放入hashMap中
          final HashMap<Integer, Integer> hashMap = new HashMap<>();
          //    加载音频,优先权 值越大优先权越高
          hashMap.put(0, soundPool.load(MainActivity.this, R.raw.nomatter, 1));
          hashMap.put(1, soundPool.load(MainActivity.this, R.raw.nextofkin, 1));
          hashMap.put(2, soundPool.load(MainActivity.this, R.raw.makingmefeel, 1));
          listView.setOnItemClickListener(
              new AdapterView.OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                  //              资源文件,左声道音量0-1,右声道音量,优先级值越大优先级越高,循环,速率0.5-2
                  soundPool.play(hashMap.get(position), 1, 1, 0, 0, 1);
                  }
              });        
      
    • MediaPlayer与SoundPool区别
      1. MediaPlayer 延迟长,占用资源多,不支持同时播放多个音频
      2. SoundPool延迟短,占用资源少,支持多音频播放
    1. 视频

      package com.example.musicvideo;
      
      import android.media.MediaPlayer;
      import android
      .os.Bundle;
      import android.os.Environment;
      import android.util.Log;
      import android.widget.MediaController;
      import android.widget.Toast;
      import android.widget.VideoView;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.io.File;
      
      public class Main2Activity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main2);
          VideoView videoView = findViewById(R.id.videoView);
          //    控制组件
          videoView.setMediaController(new MediaController(Main2Activity.this));
          String path = Environment.getExternalStorageDirectory() + "/mp41.mp4";
          Log.i("测试", path);
          File file = new File(path);
          if (file.exists()) {
              videoView.setVideoPath(file.getAbsolutePath());
              Toast.makeText(Main2Activity.this, "文件存在", Toast.LENGTH_SHORT).show();
          } else {
              Toast.makeText(Main2Activity.this, "文件不存在", Toast.LENGTH_SHORT).show();
          }
          //    获取焦点
          videoView.requestFocus();
          videoView.start();
          //    播放完毕触发事件
          videoView.setOnCompletionListener(
              new MediaPlayer.OnCompletionListener() {
                  @Override
                  public void onCompletion(MediaPlayer mp) {
                  Toast.makeText(Main2Activity.this, "播放完毕", Toast.LENGTH_SHORT).show();
                  }
              });
          }
      }
      
      
      package com.example.musicvideo;
      
      import android.media.AudioManager;
      import android.media.MediaPlayer;
      import android.os.Bundle;
      import android.os.Environment;
      import android.view.SurfaceHolder;
      import android.view.SurfaceView;
      import android.view.View;
      import android.widget.ImageButton;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.io.IOException;
      
      /**
          * @author Jamin
          * @date 2019/10/10
          * @desc 使用mediaPlayer+surfaceView实现播放视频
          */
      public class Main3Activity extends AppCompatActivity {
          private boolean isPause = false;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main3);
          SurfaceView surfaceView = findViewById(R.id.surfaceView);
          final SurfaceHolder surfaceHolder = surfaceView.getHolder();
          final MediaPlayer mediaPlayer = new MediaPlayer();
          //    设置多媒体类型
          mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
          try {
      
              mediaPlayer.setDataSource(Environment.getExternalStorageDirectory() + "/mp41.mp4");
              //                  预加载
              mediaPlayer.prepare();
          } catch (IOException e) {
              e.printStackTrace();
          }
      
          final ImageButton playButton = findViewById(R.id.start3);
          playButton.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  if (mediaPlayer.isPlaying()) {
                      mediaPlayer.pause();
                      playButton.setImageDrawable(getResources().getDrawable(R.mipmap.start));
                  } else {
                      //                将视频输出到surfaceView
                      mediaPlayer.setDisplay(surfaceHolder);
                      mediaPlayer.start();
                      playButton.setImageDrawable(getResources().getDrawable(R.mipmap.pause));
                  }
                  }
              });
      
          findViewById(R.id.stop3)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      mediaPlayer.pause();
                      mediaPlayer.seekTo(0);
                      playButton.setImageDrawable(getResources().getDrawable(R.mipmap.start));
                      }
                  });
          }
      }
      
      
    2. 控制相机

      
      package com.example.musicvideo;
      
      import android.Manifest;
      import android.app.Activity;
      import android.content.Intent;
      import android.content.pm.ActivityInfo;
      import android.content.pm.PackageManager;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.graphics.PixelFormat;
      import android.hardware.Camera;
      import android.net.Uri;
      import android.os.Bundle;
      import android.os.Environment;
      import android.provider.MediaStore;
      import android.view.SurfaceHolder;
      import android.view.SurfaceView;
      import android.view.View;
      import android.view.Window;
      import android.widget.ImageButton;
      import android.widget.Toast;
      
      import androidx.core.content.ContextCompat;
      
      import java.io.File;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      /**
          * @author Jamin
          * @date 2019/10/10
          * @desc 拍照与录像
          */
      public class Main4Activity extends Activity implements SurfaceHolder.Callback {
      
          private Camera camera;
          private SurfaceView surfaceView;
          private SurfaceHolder surfaceViewHolder;
          private int cameraId = 0;
          private ImageButton takePhoto;
          private Camera.PictureCallback pictureCallback =
              new Camera.PictureCallback() {
              @Override
              public void onPictureTaken(byte[] data, Camera camera) {
                  //        根据拍照数据创建位图
                  Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                  //        停止预览
                  camera.stopPreview();
                  File dir = new File(Environment.getExternalStorageDirectory() + "/DCIM/Camera/");
                  if (!dir.exists()) {
                  //            创建文件夹
                  dir.mkdir();
                  }
                  String fileName = System.currentTimeMillis() + ".jpeg";
                  File file = new File(dir, fileName);
                  try {
                  FileOutputStream fileOutputStream = new FileOutputStream(file);
                  bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
                  fileOutputStream.flush();
                  fileOutputStream.close();
                  } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  } catch (IOException e) {
                  e.printStackTrace();
                  }
                  // 将图片添加到系统图库
                  try {
                  MediaStore.Images.Media.insertImage(
                      Main4Activity.this.getContentResolver(), file.getAbsolutePath(), fileName, null);
                  } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  }
                  // 通知图库更新
                  Main4Activity.this.sendBroadcast(
                      new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + "")));
                  //          保存图片
                  Toast.makeText(Main4Activity.this, "照片保存至" + file, Toast.LENGTH_SHORT).show();
                  camera.startPreview();
              }
              };
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          requestWindowFeature(Window.FEATURE_NO_TITLE);
          setContentView(R.layout.activity_main4);
          this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
          initView();
          initButton();
          }
      
          private void initButton() {
          takePhoto = findViewById(R.id.imgbt1);
          takePhoto.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  camera.takePicture(null, null, pictureCallback);
                  }
              });
          }
      
          private void initView() {
          surfaceView = findViewById(R.id.surface);
          surfaceViewHolder = surfaceView.getHolder();
          surfaceViewHolder.addCallback(this);
          }
      
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
          if (ContextCompat.checkSelfPermission(Main4Activity.this, Manifest.permission.CAMERA)
              != PackageManager.PERMISSION_GRANTED) {
              Toast.makeText(Main4Activity.this, "请先打开权限", Toast.LENGTH_LONG).show();
          } else {
              cameraOpen();
          }
          }
      
          private void cameraOpen() {
          try {
              //      打开相机
              camera = Camera.open(cameraId);
              //    反转
              camera.setDisplayOrientation(90);
              camera.setPreviewDisplay(surfaceViewHolder);
              camera.startPreview();
              //      自动对焦
              camera.autoFocus(null);
          } catch (IOException e) {
              e.printStackTrace();
              camera.release();
              camera = null;
              Toast.makeText(Main4Activity.this, "不能打开摄像机", Toast.LENGTH_SHORT).show();
          }
          }
      
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
          //    设置参数
          Camera.Parameters parameters = camera.getParameters();
          parameters.setPictureFormat(PixelFormat.JPEG);
          parameters.set("jpeg-quality", 80);
          camera.setParameters(parameters);
          camera.startPreview();
          }
      
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
          camera.stopPreview();
          camera.release();
          camera = null;
          }
      
          @Override
          protected void onPause() {
          super.onPause();
          //    释放资源
          if (camera != null) {
              camera.stopPreview();
              camera.release();
          }
          }
      }
      
      
      package com.example.musicvideo;
      
      import android.Manifest;
      import android.content.pm.PackageManager;
      import android.hardware.Camera;
      import android.media.MediaRecorder;
      import android.os.Bundle;
      import android.os.Environment;
      import android.os.SystemClock;
      import android.util.Log;
      import android.view.SurfaceHolder;
      import android.view.SurfaceView;
      import android.view.View;
      import android.widget.Chronometer;
      import android.widget.ImageButton;
      import android.widget.Toast;
      
      import androidx.appcompat.app.AppCompatActivity;
      import androidx.core.content.ContextCompat;
      
      import java.io.File;
      import java.io.IOException;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.List;
      
      /**
          * @author Jamin
          * @date 2019/10/11
          * @desc 视频录制
          */
      public class Main5Activity extends AppCompatActivity implements SurfaceHolder.Callback {
          private File videoFile;
          private MediaRecorder mediaRecorder;
          private Camera camera;
          private SurfaceView surfaceView;
          private SurfaceHolder surfaceHolder;
          private int cameraId = 0;
          private Camera.Parameters parameters;
          private Chronometer chronometer;
          private ImageButton stopVideo;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main5);
          surfaceView = findViewById(R.id.surface2);
          surfaceHolder = surfaceView.getHolder();
          surfaceHolder.addCallback(this);
          chronometer = findViewById(R.id.chronometer);
          final ImageButton videoButton = findViewById(R.id.imgbt2);
          videoButton.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
      
                  record();
                  // 开始录像后开始按钮不可点击
                  videoButton.setEnabled(false);
                  //            停止按钮可点击
                  stopVideo.setEnabled(true);
                  }
              });
          stopVideo = findViewById(R.id.imgbt3);
          // 设置停止按钮不可点击
          stopVideo.setEnabled(false);
          stopVideo.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  mediaRecorder.stop();
                  chronometer.stop();
                  chronometer.setBase(SystemClock.elapsedRealtime());
                  Toast.makeText(
                          Main5Activity.this, "视频保存至" + videoFile.getAbsolutePath(), Toast.LENGTH_SHORT)
                      .show();
                  //            录像结束后开始按钮可点击
                  videoButton.setEnabled(true);
                  stopVideo.setEnabled(false);
                  }
              });
          }
      
          @Override
          protected void onResume() {
          super.onResume();
          camera = Camera.open();
          }
      
          @Override
          protected void onPause() {
          super.onPause();
          camera.stopPreview();
          camera.release();
          }
      
          /** 开始录制 */
          private void record() {
          settingMediaRecorder();
          //    准备录像
          try {
              mediaRecorder.prepare();
          } catch (IOException e) {
              e.printStackTrace();
          }
      
          //    开始录像
          mediaRecorder.start();
          chronometer.setBase(SystemClock.elapsedRealtime());
          chronometer.start();
          }
      
          /** 录像配置 */
          public void settingMediaRecorder() {
          File path = new File(Environment.getExternalStorageDirectory() + "/MyVideo");
          if (!path.exists()) {
              path.mkdir();
          }
          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
          String fileName = simpleDateFormat.format(new Date()) + ".mp4";
          videoFile = new File(path, fileName);
          mediaRecorder = new MediaRecorder();
          //    camera.setDisplayOrientation(90);
          //    解锁相机
          camera.unlock();
          //    使用相机
          mediaRecorder.setCamera(camera);
          mediaRecorder.reset();
          //    使用麦克风和相机获取视频音频
          mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
          //    输出格式
          mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
          //    编码格式
          mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
          mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
          //   设置比特率
          mediaRecorder.setVideoEncodingBitRate(1080 * 1920);
          //    设置分辨率
          List<Camera.Size> supportedVideoSizes = parameters.getSupportedVideoSizes();
          for (Camera.Size size : supportedVideoSizes) {
              if (size.width / 16 == size.height / 9) {
      
              mediaRecorder.setVideoSize(size.width, size.height);
      
              Log.d("setPictureSize", "SET width:" + size.width + " height " + size.height);
      
              break;
              }
          }
      
          // 设置帧率
          mediaRecorder.setVideoFrameRate(24);
          // 输出路径
          mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
          // 预览
          mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
          //    调整角度
          mediaRecorder.setOrientationHint(90);
          }
      
          /**
          * 权限检测
          *
          * @param holder
          */
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
          if (ContextCompat.checkSelfPermission(Main5Activity.this, Manifest.permission.CAMERA)
                  != PackageManager.PERMISSION_GRANTED
              && ContextCompat.checkSelfPermission(Main5Activity.this, Manifest.permission.RECORD_AUDIO)
                  != PackageManager.PERMISSION_GRANTED) {
              Toast.makeText(Main5Activity.this, "请先打开权限", Toast.LENGTH_LONG).show();
          } else {
              cameraOpen();
          }
          }
      
          /** 打开相机 */
          private void cameraOpen() {
          try {
              //      打开相机
              camera = Camera.open(cameraId);
              //    反转
              camera.setDisplayOrientation(90);
              camera.setPreviewDisplay(surfaceHolder);
              camera.startPreview();
          } catch (IOException e) {
              e.printStackTrace();
              camera.release();
              camera = null;
              Toast.makeText(Main5Activity.this, "不能打开摄像机", Toast.LENGTH_SHORT).show();
          }
          }
      
          /**
          * 设置相机参数
          *
          * @param holder
          * @param format
          * @param width
          * @param height
          */
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
          parameters = camera.getParameters();
          parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
          camera.setParameters(parameters);
          camera.startPreview();
          }
      
          /**
          * 销毁操作
          *
          * @param holder
          */
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
          if (camera != null) {
              camera.release();
              camera = null;
          }
          }
      }
      
      
  11. 数据存储

    1. sharePreferences: Android提供用来以最原生的方式对数据进行永久保存的方法,保存文件格式为xml,储存在data/data/包名/shared_prefs
      1. 获取sharePreferences对象
        1. getSharedPreferences(String name,int mode)
          • name 文件名
          • mode MODE_PRIVATE 被本应用读写
          • MODE_MULTI_PROCESS 跨应用读写
        2. getPerences(int mode)
      2. 获取SharedPreferences.Editor对象 edit()
      3. 向SharedPreferences.Editor对象添加数据 putBoolean(),putString(),putInt()
      4. 提交数据commit()
      5. 使用对象SharedPreferences类提供的getxx()方法获取数据
      package com.jamin.datastorage;
      
      import android.content.Intent;
      import android.content.SharedPreferences;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.View;
      import android.widget.EditText;
      import android.widget.Toast;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      public class MainActivity extends AppCompatActivity {
      private static final String account = "user";
      private static final String pwd = "123456";
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          final EditText editAccount = findViewById(R.id.account);
          final EditText editPwd = findViewById(R.id.pwd);
          final SharedPreferences sharedPreferences = getSharedPreferences("userInfo", MODE_PRIVATE);
          final SharedPreferences.Editor editor = sharedPreferences.edit();
          String user = sharedPreferences.getString("user", null);
          String password = sharedPreferences.getString("pwd", null);
          //    判断本地是否有数据
          if (user != null && pwd != null && user.equals(account) && password.equals(pwd)) {
          Intent intent = new Intent(MainActivity.this, Main2Activity.class);
          startActivity(intent);
          }
      
          findViewById(R.id.login)
              .setOnClickListener(
                  new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      String editAccountText = editAccount.getText().toString();
                      String editPwdText = editPwd.getText().toString();
                      //                验证
                      if (editAccountText.equals(account) && editPwdText.equals(pwd)) {
                      Toast.makeText(MainActivity.this, "login success", Toast.LENGTH_SHORT).show();
                      //                  储存数据
                      editor.putString("user", editAccountText);
                      editor.putString("pwd", editPwdText);
                      editor.commit();
                      Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                      startActivity(intent);
                      } else {
                      Toast.makeText(MainActivity.this, "login failed", Toast.LENGTH_SHORT).show();
                      Log.i("账号", editAccountText);
                      Log.i("密码", editPwdText);
                      editAccount.setText("");
                      editPwd.setText("");
                      }
                  }
                  });
      }
      }
      
    2. 内部存储 应用的data/data/包名/files/内部储存文件
      package com.jamin.datastorage;
      
      import android.os.Bundle;
      import android.view.View;
      import android.widget.Button;
      import android.widget.EditText;
      import android.widget.Toast;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      
      /**
      * @author Jamin 
      *  @date 2019/10/11
      * @desc 使用内部储存
      * */
      public class Main3Activity extends AppCompatActivity {
      private FileOutputStream fos = null;
      private FileInputStream fis = null;
      
      private byte[] buffer = null;
      private EditText editText2;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main3);
          final EditText editText = findViewById(R.id.editText);
          editText2 = findViewById(R.id.editText2);
          //    保存文件
          findViewById(R.id.saveButton)
              .setOnClickListener(
                  new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      String content = editText.getText().toString();
                      try {
                      fos = openFileOutput("test", MODE_PRIVATE);
                      fos.write(content.getBytes());
                      fos.flush();
                      } catch (FileNotFoundException e) {
                      e.printStackTrace();
                      } catch (IOException e) {
                      e.printStackTrace();
                      } finally {
                      if (fos != null) {
                          try {
                          fos.close();
                          Toast.makeText(Main3Activity.this, "保存成功", Toast.LENGTH_SHORT).show();
                          } catch (IOException e) {
                          e.printStackTrace();
                          }
                      }
                      }
                  }
                  });
      
          Button cancelButton = findViewById(R.id.cancelButton);
          cancelButton.setOnClickListener(
              new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  finish();
              }
              });
          // 打开保存的文件
          Button openButton = findViewById(R.id.openButton);
          openButton.setOnClickListener(
              new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  try {
                  fis = openFileInput("test");
                  buffer = new byte[fis.available()];
                  fis.read(buffer);
                  } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  } catch (IOException e) {
                  e.printStackTrace();
                  } finally {
                  if (fis != null) {
                      try {
                      fis.close();
                      String data = new String(buffer);
                      editText2.setText(data);
                      } catch (IOException e) {
                      e.printStackTrace();
                      }
                  }
                  }
              }
              });
      }
      }
      
    3. 使用外部存储
      package com.jamin.datastorage;
      
      import android.os.Bundle;
      import android.os.Environment;
      import android.view.View;
      import android.widget.Button;
      import android.widget.EditText;
      import android.widget.Toast;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      
      /**
      * @author Jamin
      * @date 2019/1012
      * @desc 外部存储
      */
      public class Main5Activity extends AppCompatActivity {
      private EditText editText3;
      private EditText editText4;
      private Button saveButton;
      private Button cancelButton;
      private Button openButton;
      private FileInputStream fis;
      private FileOutputStream fos;
      private byte[] buffer;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main5);
          editText3 = findViewById(R.id.editText3);
          editText4 = findViewById(R.id.editText4);
          saveButton = findViewById(R.id.saveButton2);
          cancelButton = findViewById(R.id.cancelButton2);
          openButton = findViewById(R.id.openButton2);
          saveButton.setOnClickListener(
              new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  String content = editText3.getText().toString();
                  File file = new File(Environment.getExternalStorageDirectory(), "/test.txt");
                  try {
                  fos = new FileOutputStream(file);
                  fos.write(content.getBytes());
                  fos.flush();
                  } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  } catch (IOException e) {
                  e.printStackTrace();
                  } finally {
                  if (fos != null) {
                      try {
                      fos.close();
                      Toast.makeText(Main5Activity.this, "保存成功", Toast.LENGTH_SHORT).show();
                      } catch (IOException e) {
                      e.printStackTrace();
                      }
                  }
                  }
              }
              });
          openButton.setOnClickListener(
              new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  try {
                  fis = new FileInputStream(Environment.getExternalStorageDirectory() + "/test.txt");
                  buffer = new byte[fis.available()];
                  fis.read(buffer);
                  } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  } catch (IOException e) {
                  e.printStackTrace();
                  } finally {
                  if (fis != null) {
                      try {
                      fis.close();
                      String content = new String(buffer);
                      editText4.setText(content);
                      } catch (IOException e) {
                      e.printStackTrace();
                      }
                  }
                  }
              }
              });
      }
      }
      
    4. 使用sqlite数据库
      1. 在内部储存下新建文件夹dataBase,创建数据库,建表
      2. 实例代码
        package com.jamin.datastorage;
        
        import android.content.ContentValues;
        import android.os.Bundle;
        import android.view.View;
        import android.widget.EditText;
        import android.widget.Toast;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        /**
        * @author Jamin
        * @date 2019/10/12
        * @desc 使用sqlite数据库进行添加
        */
        public class Main7Activity extends AppCompatActivity {;
        private DBOpenHelper dbOpenHelper;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main7);
            //    初始化对象
            dbOpenHelper = new DBOpenHelper(Main7Activity.this, "db_dict", null, 1);
            final EditText eeditText = findViewById(R.id.eeditText);
            final EditText ceditText = findViewById(R.id.ceditText);
            findViewById(R.id.add)
                .setOnClickListener(
                    new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String en = eeditText.getText().toString();
                        String cn = ceditText.getText().toString();
                        //                保存数据
                        ContentValues contentValues = new ContentValues();
                        contentValues.put("word", en);
                        contentValues.put("deatil", cn);
                        dbOpenHelper.getReadableDatabase().insert("t_dictionary", null, contentValues);
                        Toast.makeText(Main7Activity.this, "add success", Toast.LENGTH_SHORT).show();
                    }
                    });
        }
        
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (dbOpenHelper != null) {
            dbOpenHelper.close();
            }
        }
        }
        
        package com.jamin.datastorage;
        
        import android.content.Intent;
        import android.database.Cursor;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.View;
        import android.widget.Button;
        import android.widget.EditText;
        import android.widget.ListView;
        import android.widget.SimpleAdapter;
        import android.widget.Toast;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        import java.util.ArrayList;
        import java.util.HashMap;
        import java.util.List;
        import java.util.Map;
        
        /**
        * @author Jamin
        * @date 2019/10/12
        * @desc 使用sqlite数据库进行查询
        */
        public class Main6Activity extends AppCompatActivity {
        private DBOpenHelper dbOpenHelper;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main6);
            //    实例化dbOpenHelper对象 上下文对象,数据库名,游标工厂,版本号
            dbOpenHelper = new DBOpenHelper(Main6Activity.this, "db_dict", null, 1);
        
            final ListView listView = findViewById(R.id.listView);
            final EditText trEditText = findViewById(R.id.treditText);
            Button translationButton = findViewById(R.id.translation);
            Button newWordsButton = findViewById(R.id.newWords);
            //    跳转添加生词
            newWordsButton.setOnClickListener(
                new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startActivity(new Intent(Main6Activity.this, Main7Activity.class));
                }
                });
            // 查询操作
            translationButton.setOnClickListener(
                new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d("test", "in");
                    String en = trEditText.getText().toString();
                    //          查询
                    Cursor cursor =
                        dbOpenHelper
                            .getReadableDatabase()
                            .query("t_dictionary", null, "word=?", new String[] {en}, null, null, null);
                    List<Map<String, String>> maps = new ArrayList<>();
                    //            遍历放入集合
                    while (cursor.moveToNext()) {
                    HashMap<String, String> map = new HashMap<>();
                    map.put("word", cursor.getString(1));
                    map.put("deatil", cursor.getString(2));
                    //              Toast.makeText(Main6Activity.this, map.toString(),
                    // Toast.LENGTH_SHORT).show();
                    Log.d("test", map.toString());
                    maps.add(map);
                    }
                    if (maps == null || maps.size() == 0) {
                    Toast.makeText(Main6Activity.this, "没有查询到数据", Toast.LENGTH_SHORT).show();
                    }
                    SimpleAdapter simpleAdapter =
                        new SimpleAdapter(
                            Main6Activity.this,
                            maps,
                            R.layout.result_main,
                            new String[] {"word", "deatil"},
                            new int[] {R.id.result_en, R.id.result_cn});
                    //             适配器输出
                    listView.setAdapter(simpleAdapter);
                }
                });
        }
        
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (dbOpenHelper != null) {
            dbOpenHelper.close();
            }
        }
        }
        
    5. 使用contentProvider 在不同应用程序间实现数据共享
      1. URI与URL
        1. URL: https://me.csdn.net/weixin_43891731 URL协议/网站域名/网站资源
        2. URI: content://com.jamin.test/person/oo1 Android规定/权限(类名)/路径
          package com.jamin.datastorage;
          
          import android.content.ContentResolver;
          import android.database.Cursor;
          import android.os.Bundle;
          import android.provider.ContactsContract;
          import android.widget.TextView;
          
          import androidx.appcompat.app.AppCompatActivity;
          
          /**
          * @author Jamin
          * @date 2019/10/12
          * @desc contentProvider
          */
          public class Main8Activity extends AppCompatActivity {
          
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main8);
              StringBuilder stringBuilder = new StringBuilder();
              ContentResolver contentResolver = getContentResolver();
              //    查询
              Cursor cursor =
                  contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
              int columnIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
              //    遍历查询结果
              for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
              String cursorString = cursor.getString(columnIndex);
              stringBuilder.append(cursorString + "\n");
              }
              TextView textView = findViewById(R.id.textView);
              textView.setText(stringBuilder.toString());
          }
          }
          
  12. Handler消息处理

    1. 安卓中的多线程
      1. 进程
        1. 进程: 一个android应用就是一个进程
      2. 线程
        1. 线程: 比进程更小的独立运行的基本单位,一个进程可以包含多个进程
      3. 实例代码
    2. Handler对象
          package com.jaminhandlermessage;
      
          import android.os.Bundle;
          import android.os.Handler;
          import android.os.Message;
          import android.view.View;
          import android.widget.Button;
          import android.widget.TextView;
      
          import androidx.annotation.NonNull;
          import androidx.appcompat.app.AppCompatActivity;
      
          public class MainActivity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              final TextView textView = findViewById(R.id.textView);
              final Handler handler =
                  new Handler() {
                  @Override
                  public void handleMessage(@NonNull Message msg) {
                      super.handleMessage(msg);
                      //            判断消息
                      if (msg.what == 0x1234) {
                      //                执行操作
                      textView.setText("测试2");
                      }
                  }
                  };
              Button button = findViewById(R.id.bt1);
              button.setOnClickListener(
                  new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      Thread thread =
                          new Thread(
                              new Runnable() {
                              @Override
                              public void run() {
                                  //                          发送消息
                                  handler.sendEmptyMessage(0x1234);
                              }
                              });
                      thread.start();
                  }
                  });
          }
          }
      
          package com.jamin.handlermessage;
      
          import android.os.Bundle;
          import android.os.Handler;
          import android.os.Message;
          import android.widget.ProgressBar;
          import android.widget.Toast;
      
          import androidx.appcompat.app.AppCompatActivity;
      
          import com.jaminhandlermessage.R;
      
          /**
          * @author Jamin
          * @date 2019/10/13
          * @desc 使用Handler实现进度条
          */
          public class Main2Activity extends AppCompatActivity {
          final int MSG = 0x1234;
          final int MSG2 = 0x1243;
          private int progress = 0;
          private int progress2 = 60;
          private ProgressBar progressBar;
          private ProgressBar progressBar2;
      
          Handler handler =
              new Handler() {
                  @Override
                  public void handleMessage(Message msg) {
                  super.handleMessage(msg);
                  if (msg.what == MSG) {
                      if (progress < 100) {
                      progressBar.setProgress(++progress);
                      handler.sendEmptyMessageDelayed(MSG, 1000);
                      } else {
                      Toast.makeText(Main2Activity.this, "加载完成", Toast.LENGTH_SHORT).show();
                      }
                  } else if (msg.what == MSG2) {
                      if (progress2 > 0) {
                      progressBar2.setProgress(--progress2);
                      handler.sendEmptyMessageDelayed(MSG2, 1000);
                      } else {
                      Toast.makeText(Main2Activity.this, "游戏结束!!", Toast.LENGTH_SHORT).show();
                      }
                  }
                  }
              };
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main2);
              progressBar = findViewById(R.id.progressBar);
              handler.sendEmptyMessage(MSG);
              progressBar2 = findViewById(R.id.progressBar2);
              handler.sendEmptyMessage(MSG2);
          }
          }
      
    3. Message对象
      1. 属性
        1. arg1 arg2 整形
        2. obj Object类型
        3. replyTo 发送到何处
        4. what 自定义消息代码
      2. 创建
        1. Mesage.obtain()
        2. Handler.obtainMessage()
    4. Looper对象
      package com.jamin.handlermessage;
      
      import android.os.Handler;
      import android.os.Looper;
      import android.os.Message;
      import android.util.Log;
      
      import androidx.annotation.NonNull;
      
      /**
      * @author Jamin <br>
      * @date 2019/10/13 18:02 <br>
      * @desc Loop <br>
      */
      public class LooperThread extends Thread {
      private final int MSG = 0x1234;
      private Handler handler;
      
      @Override
      public void run() {
          super.run();
          Looper.prepare();
          handler =
              new Handler() {
              @Override
              public void handleMessage(@NonNull Message msg) {
                  super.handleMessage(msg);
      
                  Log.e("looper", "test" + String.valueOf(MSG));
              }
              };
          Message message = handler.obtainMessage();
          message.what = MSG;
          handler.sendMessage(message);
          Looper.loop();
      }
      }
      
      package com.jamin.handlermessage;
      
      import android.os.Bundle;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import com.jaminhandlermessage.R;
      
      public class Main4Activity extends AppCompatActivity {
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main4);
          LooperThread looperThread = new LooperThread();
          looperThread.start();
      }
      }
      
  13. Service

    1. 概述: 能够在后台长时间运行,并且没有用户界面的应用程序组件
    2. 分类
      1. started service:Activity使用startService通知服务启动才启动 生命周期onCreate->onStartCommand()–>Service运行–>stopSelf()/stopService–>service停止–>onDestory()–>service被关闭
      2. boundService: bindService()与Activity同生共死 生命周期 onCrate()–> onBind()–>绑定到Service–>unbindService()–>解绑Service()–>onUnbind()–>onDestory()–>service关闭()
    3. StartedService
      package com.jamin.service;
      
      import android.app.ActivityManager;
      import android.app.Service;
      import android.content.Context;
      import android.content.Intent;
      import android.os.IBinder;
      import android.util.Log;
      
      import java.util.ArrayList;
      
      /**
      * @author Jamin
      * @date 2019/10/13
      * @desc 后台打印
      */
      public class MyService extends Service {
      private int i = 0;
      
      public MyService() {}
      
      @Override
      public IBinder onBind(Intent intent) {
          // TODO: Return the communication channel to the service.
          throw new UnsupportedOperationException("Not yet implemented");
      }
      
      @Override
      public void onCreate() {
          super.onCreate();
      }
      
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
      
          new Thread(
                  new Runnable() {
                  @Override
                  public void run() {
                      while (isRunning()) {
                      Log.d("CESHI", String.valueOf(++i));
                      try {
                          Thread.sleep(1000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      }
                  }
                  })
              .start();
          return super.onStartCommand(intent, flags, startId);
      }
      
      @Override
      public void onDestroy() {
          super.onDestroy();
      }
      
      public boolean isRunning() {
          ActivityManager systemService = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
          //    获取正在运行的服务
          ArrayList<ActivityManager.RunningServiceInfo> runningServiceInfos =
              (ArrayList<ActivityManager.RunningServiceInfo>) systemService.getRunningServices(100);
          for (ActivityManager.RunningServiceInfo runningServiceInfo : runningServiceInfos) {
          //      判断是否是当前服务
          if (runningServiceInfo
              .service
              .getClassName()
              .toString()
              .equals("com.jamin.service.MyService")) {
              return true;
          }
          }
          return false;
      }
      }
      
      package com.jamin.service;
      
      import android.content.Intent;
      import android.os.Bundle;
      import android.view.View;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      public class ServiceActivity extends AppCompatActivity {
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_service);
          final Intent intent = new Intent(ServiceActivity.this, MyService.class);
          findViewById(R.id.open)
              .setOnClickListener(
                  new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      startService(intent);
                  }
                  });
          findViewById(R.id.close)
              .setOnClickListener(
                  new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      stopService(intent);
                  }
                  });
      }
      }
      
      package com.jamin.service;
      
      import android.app.Service;
      import android.content.Intent;
      import android.media.MediaPlayer;
      import android.os.IBinder;
      
      /**
      * @author Jamin
      * @date 2019/10/13
      * @desc 后台音乐播放
      */
      public class MusicService extends Service {
      private MediaPlayer mediaPlayer;
      
      public MusicService() {}
      
      @Override
      public IBinder onBind(Intent intent) {
          // TODO: Return the communication channel to the service.
          throw new UnsupportedOperationException("Not yet implemented");
      }
      
      @Override
      public void onCreate() {
          mediaPlayer = MediaPlayer.create(this, R.raw.mp31);
          super.onCreate();
      }
      
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          if (mediaPlayer.isPlaying()) {
      
          mediaPlayer.pause();
          } else {
      
          mediaPlayer.start();
          }
      
          return super.onStartCommand(intent, flags, startId);
      }
      
      @Override
      public void onDestroy() {
          //      停止播放
          mediaPlayer.pause();
          mediaPlayer.seekTo(0);
          //     释放资源
          mediaPlayer.release();
          super.onDestroy();
      }
      }
      
      package com.jamin.service;
      
      import android.content.Intent;
      import android.os.Bundle;
      import android.view.View;
      import android.widget.Button;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      /**
      * @author Jamin 
      * @date 2019/10/13
      * @desc 后台播放音乐
      */
      public class BackgroundSoundActivity extends AppCompatActivity {
      private Button button;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_background_sound);
          button = findViewById(R.id.openClose);
          final Intent intent = new Intent(BackgroundSoundActivity.this, MusicService.class);
          button.setOnClickListener(
              new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  /* MediaPlayer mediaPlayer = MediaPlayer.create(BackgroundSoundActivity.this, R.raw.mp31);
                  mediaPlayer.start();*/
                  startService(intent);
              }
              });
      }
      }
      
    4. BoundService
      package com.jamin.service;
      
      import android.app.Service;
      import android.content.Intent;
      import android.os.Binder;
      import android.os.IBinder;
      
      import java.util.ArrayList;
      import java.util.List;
      import java.util.Random;
      
      /**
      * @author Jamin
      * @date 2019/10/14 BinderService
      */
      public class BinderService extends Service {
      public BinderService() {}
      
      // 销毁
      @Override
      public void onDestroy() {
          super.onDestroy();
      }
      
      @Override
      public IBinder onBind(Intent intent) {
          return new MyBinder();
      }
      /** 产生随机数的方法 */
      public List<String> randomNumber() {
          List list = new ArrayList<String>();
          String s = "";
          for (int i = 0; i < 7; i++) {
          int j = new Random().nextInt(33) + 1;
          if (j >= 10) {
              s = String.valueOf(j);
          } else {
              s = "0" + String.valueOf(j);
          }
          list.add(s);
          }
          return list;
      }
      /** 创建MyBinder内部类 */
      public class MyBinder extends Binder {
          // 创建获取Service的方法
          public BinderService getBinderService() {
          return BinderService.this;
          }
      }
      }
      
      package com.jamin.service;
      
      import android.content.ComponentName;
      import android.content.Intent;
      import android.content.ServiceConnection;
      import android.os.Bundle;
      import android.os.IBinder;
      import android.view.View;
      import android.widget.Button;
      import android.widget.TextView;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.util.List;
      
      /**
      * @author Jamin
      * @date 2019/10/14
      */
      public class Main2Activity extends AppCompatActivity {
      private BinderService binderService;
      /** textView的id */
      private int[] textViewArr =
          new int[] {R.id.t0, R.id.t1, R.id.t2, R.id.t3, R.id.t4, R.id.t5, R.id.t6};
      
      private Button button;
      /** service连接对象 */
      private ServiceConnection serviceConnection =
          new ServiceConnection() {
              @Override
              public void onServiceConnected(ComponentName name, IBinder service) {
              binderService = ((BinderService.MyBinder) service).getBinderService();
              }
      
              @Override
              public void onServiceDisconnected(ComponentName name) {}
          };
      
      @Override
      protected void onStart() {
          super.onStart();
          Intent intent = new Intent(Main2Activity.this, BinderService.class);
          //    绑定Service
          bindService(intent, serviceConnection, BIND_AUTO_CREATE);
      }
      
      @Override
      protected void onStop() {
          super.onStop();
          //    解绑service
          unbindService(serviceConnection);
      }
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main2);
          button = findViewById(R.id.bt0);
          button.setOnClickListener(
              new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  List<String> list = binderService.randomNumber();
                  for (int i = 0; i < list.size(); i++) {
                  TextView textView = findViewById(textViewArr[i]);
                  textView.setText(list.get(i));
                  }
              }
              });
      }
      }
      
    5. IntantService 普通service不能自动开启线程,自动销毁,IntentService可以
      package com.jamin.service;
      
      import android.app.IntentService;
      import android.content.Intent;
      import android.util.Log;
      
      import androidx.annotation.Nullable;
      
      /**
      * @author Jamin <br>
      * @date 2019/10/14 16:53 <br>
      * @desc IntentService <br>
      */
      public class MyIntentService extends IntentService {
      /**
      * Creates an IntentService. Invoked by your subclass's constructor.
      *
      * @param name Used to name the worker thread, important only for debugging.
      */
      public MyIntentService(String name) {
          super(name);
      }
      
      public MyIntentService() {
          super("MyIntentService");
      }
      
      @Override
      protected void onHandleIntent(@Nullable Intent intent) {
          Log.d("intentService", "开始");
          long endTime = System.currentTimeMillis() + 20 * 1000;
          while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
              wait(endTime - System.currentTimeMillis());
              } catch (InterruptedException e) {
              e.printStackTrace();
              }
          }
          }
      }
      
      @Override
      public void onDestroy() {
          super.onDestroy();
          Log.d("service", "jieshu");
      }
      }
      
      package com.jamin.service;
      
      import android.app.Service;
      import android.content.Intent;
      import android.os.IBinder;
      import android.util.Log;
      
      /**
      * @author Jamin
      * @date 2019/10/14
      * @desc 普通Service
      */
      public class MyService2 extends Service {
      public MyService2() {}
      
      @Override
      public IBinder onBind(Intent intent) {
          // TODO: Return the communication channel to the service.
          throw new UnsupportedOperationException("Not yet implemented");
      }
      
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          Log.d("service", "开始");
          long endTime = System.currentTimeMillis() + 20 * 1000;
          while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
              wait(endTime - System.currentTimeMillis());
              } catch (InterruptedException e) {
              e.printStackTrace();
              }
          }
          }
      
          return super.onStartCommand(intent, flags, startId);
      }
      
      @Override
      public void onDestroy() {
          super.onDestroy();
          Log.d("service", "jieshu");
      }
      }
      
  14. 传感器

    1. 分类
      1. 光线传感器
      2. 磁场传感器
      3. 加速传感器
      4. 方向传感器
    2. 光线传感器实例代码
      package com.jamin.sensor;
      
      import android.content.Context;
      import android.hardware.Sensor;
      import android.hardware.SensorEvent;
      import android.hardware.SensorEventListener;
      import android.hardware.SensorManager;
      import android.os.Bundle;
      import android.widget.TextView;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      /**
      * @author Jamin
      * @date 2019/10/14
      * @desc 光线传感器
      */
      public class LightActivity extends AppCompatActivity implements SensorEventListener {
      private SensorManager sensorManager;
      private TextView textView;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_light);
          //    获取传感器管理器
          sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
          textView = findViewById(R.id.textView);
      }
      
      @Override
      protected void onResume() {
          super.onResume();
          //    注册监听器
          sensorManager.registerListener(
              this, sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_GAME);
      }
      
      @Override
      protected void onPause() {
          super.onPause();
          // 取消注册监听器
          sensorManager.unregisterListener(this);
      }
      
      @Override
      public void onSensorChanged(SensorEvent event) {
          float[] values = event.values;
          int type = event.sensor.getType();
          if (type == Sensor.TYPE_LIGHT) {
          textView.setText("光线传感器:" + values[0]);
          }
      }
      
      @Override
      public void onAccuracyChanged(Sensor sensor, int accuracy) {}
      }
      
    3. 磁场传感器实例代码
      package com.jamin.sensor;
      
      import android.content.Context;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.graphics.Canvas;
      import android.graphics.Paint;
      import android.hardware.Sensor;
      import android.hardware.SensorEvent;
      import android.hardware.SensorEventListener;
      import android.hardware.SensorManager;
      import android.util.AttributeSet;
      import android.view.View;
      
      import androidx.annotation.Nullable;
      
      /**
      * @author Jamin <br>
      * @date 2019/10/14 21:28 <br>
      * @desc 指针 <br>
      */
      public class PointView extends View implements SensorEventListener {
      private SensorManager sensorManager;
      
      private Bitmap bitmap;
      private float[] value;
      private float floatX;
      private float floatY;
      
      public PointView(Context context, @Nullable AttributeSet attrs) {
          super(context, attrs);
          sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
          //    监听器
          sensorManager.registerListener(
              this,
              sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
              SensorManager.SENSOR_DELAY_NORMAL);
          //    加载资源
          bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass);
      }
      
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
          if (bitmap != null) {
          //      设置画布选择角度
          canvas.translate(super.getWidth() / 2, super.getWidth() / 2);
      
          if (floatY == 0 && floatX > 0) {
              canvas.rotate(90);
          } else if (floatY == 0 && floatX < 0) {
              canvas.rotate(-90);
          } else {
              if (floatY > 0) {
              canvas.rotate((float) Math.tanh(floatX / floatY) * 90);
              } else {
              canvas.rotate((float) (180 + Math.tanh(floatX / floatY) * 90));
              }
          }
          }
          canvas.drawBitmap(bitmap, -bitmap.getWidth() / 2, -bitmap.getHeight() / 2, new Paint());
      }
      
      @Override
      public void onSensorChanged(SensorEvent event) {
          float[] values = event.values;
      
          int type = event.sensor.getType();
          if (type == Sensor.TYPE_MAGNETIC_FIELD) {
          floatX = values[0];
          floatY = values[1];
          super.postInvalidate();
          }
      }
      
      @Override
      public void onAccuracyChanged(Sensor sensor, int accuracy) {}
      }
      
    4. 方向传感器
      1. 实例代码
        package com.jamin.sensor;
        
        import android.content.Context;
        import android.graphics.Bitmap;
        import android.graphics.Canvas;
        import android.graphics.Paint;
        import android.hardware.Sensor;
        import android.hardware.SensorEvent;
        import android.hardware.SensorEventListener;
        import android.hardware.SensorManager;
        import android.util.AttributeSet;
        import android.util.Log;
        import android.view.View;
        
        import androidx.annotation.Nullable;
        
        /**
        * @author Jamin <br>
        * @date 2019/10/15 19:55 <br>
        * @desc 水平仪 <br>
        */
        public class LevelView extends View implements SensorEventListener {
        /** 最大倾斜角度 */
        private final int MAX_ANGLE = 30;
        
        private SensorManager sensorManager;
        /** 加速度传感器的值 */
        private float[] accelerometerValues;
        /** 磁场传感器的值 */
        private float[] magnticValues;
        /** 小球X坐标 */
        private float bubbleX;
        /** 小球Y坐标 */
        private float bubbleY;
        /** 小球 */
        private Bitmap bubble;
        /**
        * @param context
        * @param attrs
        */
        public LevelView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
            // 注册磁场监听器
            sensorManager.registerListener(
                this,
                sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                SensorManager.SENSOR_DELAY_GAME);
            //    注册加速度监听器
            sensorManager.registerListener(
                this,
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_GAME);
        }
        
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawBitmap(bubble, bubble.getWidth() / 2, bubble.getHeight() / 2, new Paint());
        }
        
        @Override
        public void onSensorChanged(SensorEvent event) {
            // 获取手机触发event的传感器的类型
            int sensorType = event.sensor.getType();
            switch (sensorType) {
            case Sensor.TYPE_ACCELEROMETER:
                accelerometerValues = event.values.clone();
                Log.d("磁场传感器", accelerometerValues.toString());
                break;
            case Sensor.TYPE_MAGNETIC_FIELD:
                magnticValues = event.values.clone();
                Log.d("加速度传感器", magnticValues.toString());
                break;
            default:
                break;
            }
            float[] R = new float[9];
            float[] values = new float[3];
            SensorManager.getRotationMatrix(R, null, accelerometerValues, magnticValues);
            SensorManager.getOrientation(R, values);
            // 手机沿着x轴倾斜 顶部0到-180 底部0-180
            float xAngle = (float) Math.toDegrees(values[1]);
            // 手机沿着y轴倾斜 左侧是0-到-90 右侧是0-90
            float yAngle = (float) Math.toDegrees(values[2]);
            getPostion(xAngle, yAngle);
            super.postInvalidate();
        }
        
        private void getPostion(float xAngle, float yAngle) {
            //  获取小球x,y位于中间位置的x,y坐标
            int x = (super.getWidth() - bubble.getWidth()) / 2;
            int y = (super.getHeight() - bubble.getHeight()) / 2;
        
            if (Math.abs(yAngle) <= MAX_ANGLE) {
            //    y轴倾斜角度越大 小球x坐标越大
            int i = (int) ((super.getWidth() - bubble.getWidth()) / 2 * xAngle / MAX_ANGLE);
            x += i;
            } else if (yAngle > MAX_ANGLE) {
            //      正的倾斜角度超出放在最左边
            x = 0;
            } else {
            //      负的倾斜角度超出放在最右边
            x = super.getWidth() - bubble.getWidth();
            }
        
            if (Math.abs(xAngle) <= y) {
            //      x轴倾斜角度越大小球x坐标越大
            int i = (int) ((super.getHeight() - bubble.getHeight()) / 2 * yAngle / MAX_ANGLE);
            y -= i;
            } else if (xAngle > MAX_ANGLE) {
            y = 0;
            } else {
            y = super.getHeight() - bubble.getHeight();
            }
            bubbleX = x;
            bubbleY = y;
        }
        
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {}
        }
        
  15. 位置服务

    1. LocationProvider
      package com.jamin.locationprovider;
      
      import android.location.Criteria;
      import android.location.LocationManager;
      import android.location.LocationProvider;
      import android.os.Bundle;
      import android.widget.TextView;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.util.Iterator;
      import java.util.List;
      
      public class Main2Activity extends AppCompatActivity {
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main2);
          //  获取位置服务
          LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
          //   获取所有位置服务的提供
          List<String> allProviders = locationManager.getAllProviders();
          StringBuilder stringBuilder = new StringBuilder();
          for (Iterator<String> iterator = allProviders.iterator(); iterator.hasNext(); ) {
          stringBuilder.append(iterator.next() + "\n");
          }
          TextView textView = findViewById(R.id.tv0);
          textView.setText(stringBuilder.toString());
          LocationProvider provider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
          TextView textView1 = findViewById(R.id.tv1);
          textView1.setText(provider.getName());
          //    创建过滤条件对象
          Criteria criteria = new Criteria();
          //    不收费
          criteria.setCostAllowed(false);
          // 精度最精确
          criteria.setAccuracy(Criteria.ACCURACY_FINE);
          //    耗电量最低
          criteria.setPowerRequirement(Criteria.POWER_LOW);
          //    获取最佳位置服务
          String bestProvider = locationManager.getBestProvider(criteria, true);
          TextView textView2 = findViewById(R.id.tv2);
          textView2.setText(bestProvider);
      }
      }
      
    2. 获取经纬度
      package com.jamin.locationprovider;
      
      import android.Manifest;
      import android.content.pm.PackageManager;
      import android.location.Location;
      import android.location.LocationListener;
      import android.location.LocationManager;
      import android.os.Bundle;
      import android.widget.TextView;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      public class Main3Activity extends AppCompatActivity {
      private TextView textView;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main3);
          LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
          textView = findViewById(R.id.lcoation);
          //    检查权限
          if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
                  != PackageManager.PERMISSION_GRANTED
              && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
                  != PackageManager.PERMISSION_GRANTED) {
          // TODO: Consider calling
          //    Activity#requestPermissions
          // here to request the missing permissions, and then overriding
          //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
          //                                          int[] grantResults)
          // to handle the case where the user grants the permission. See the documentation
          // for Activity#requestPermissions for more details.
          return;
          }
          locationManager.requestLocationUpdates(
              //        使用GPS
              LocationManager.GPS_PROVIDER,
              //        间隔时间1s
              1000,
              //  位置间隔1米
              1,
              //        位置更新监听器
              new LocationListener() {
              @Override
              public void onLocationChanged(Location location) {}
      
              @Override
              public void onStatusChanged(String provider, int status, Bundle extras) {}
      
              @Override
              public void onProviderEnabled(String provider) {}
      
              @Override
              public void onProviderDisabled(String provider) {}
              });
          Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
          locationUpdate(lastKnownLocation);
      }
      
      private void locationUpdate(Location location) {
          StringBuilder stringBuilder = new StringBuilder();
          stringBuilder.append("经度" + location.getLongitude());
          stringBuilder.append("纬度" + location.getLatitude());
          textView.setText(stringBuilder.toString());
      }
      }
      
    3. 百度地图的应用
      package com.jamin.baidumap;
      
      import android.location.Location;
      import android.os.Bundle;
      import android.util.Log;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import com.baidu.location.BDLocation;
      import com.baidu.location.BDLocationListener;
      import com.baidu.location.LocationClient;
      import com.baidu.location.LocationClientOption;
      import com.baidu.mapapi.CoordType;
      import com.baidu.mapapi.SDKInitializer;
      import com.baidu.mapapi.map.BaiduMap;
      import com.baidu.mapapi.map.BitmapDescriptor;
      import com.baidu.mapapi.map.BitmapDescriptorFactory;
      import com.baidu.mapapi.map.MapStatus;
      import com.baidu.mapapi.map.MapStatusUpdateFactory;
      import com.baidu.mapapi.map.MapView;
      import com.baidu.mapapi.map.MarkerOptions;
      import com.baidu.mapapi.map.MyLocationData;
      import com.baidu.mapapi.map.OverlayOptions;
      import com.baidu.mapapi.model.LatLng;
      
      /**
      * @author Jamin
      * @date 2019/10/23
      * @desc 初始化地图并配置生命周期
      */
      public class MainActivity extends AppCompatActivity implements BDLocationListener {
      private MapView mapView;
      private BaiduMap baiduMap;
      // 防止每次定位都重新设置中心点和marker
      private boolean isFirstLocation = true;
      // 初始化LocationClient定位类
      private LocationClient mLocationClient = null;
      // 经纬度
      private double lat;
      private double lon;
      
      private boolean isFirst = true;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          //    初始化sdk
          SDKInitializer.initialize(getApplicationContext());
          //   设置经纬度类型
          SDKInitializer.setCoordType(CoordType.GCJ02);
          setContentView(R.layout.activity_main);
          mapView = findViewById(R.id.bmapView);
          //    获取百度地图对象
          baiduMap = mapView.getMap();
          // 声明LocationClient类
          mLocationClient = new LocationClient(this);
          // 注册监听函数
          mLocationClient.registerLocationListener(this);
          initLocation();
          // 开始定位
          mLocationClient.start();
      }
      
      private void locationUpdate(Location location) {
          if (location != null) {
          LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
          Log.d("经纬度", location.getLatitude() + "--------" + location.getLongitude());
          if (isFirst) {
              MapStatus mapStatus = new MapStatus.Builder().target(latLng).zoom(18f).build();
      
              // 设置地图位置
              baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(mapStatus));
              isFirst = false;
              //      构造定位数据
              MyLocationData myLocationData =
                  new MyLocationData.Builder()
                      // 准确性
                      .accuracy(location.getAccuracy())
                      //                方向
                      .direction(100)
                      //                纬度
                      .latitude(location.getLatitude())
                      //                经度
                      .longitude(location.getLongitude())
                      .build();
              //        设置定位数据
              baiduMap.setMyLocationData(myLocationData);
              //        设置图标
              BitmapDescriptor bitmapDescriptor =
                  BitmapDescriptorFactory.fromResource(R.drawable.icon_geo);
              // 构建Marker图标
              BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo);
              // 构建MarkerOption,用于在地图上添加Marker
              OverlayOptions option = new MarkerOptions().position(latLng).icon(bitmap);
              // 在地图上添加Marker,并显示
              baiduMap.addOverlay(option);
          }
          } else {
          Log.d("经纬度", "无法获取");
          }
      }
      
      @Override
      protected void onStart() {
          super.onStart();
          baiduMap.setMyLocationEnabled(true);
      }
      
      @Override
      protected void onStop() {
          super.onStop();
          baiduMap.setMyLocationEnabled(false);
      }
      
      @Override
      protected void onPause() {
          super.onPause();
          mapView.onPause();
      }
      
      @Override
      protected void onDestroy() {
          super.onDestroy();
          mapView.onDestroy();
          mapView = null;
      }
      
      @Override
      protected void onResume() {
          super.onResume();
          mapView.onResume();
      }
      
      @Override
      public void onReceiveLocation(BDLocation bdLocation) {
          if (isFirst) {
          isFirst = false;
          // 设置并显示中心点
          MyLocationData locData =
              new MyLocationData.Builder()
                  .accuracy(bdLocation.getRadius())
                  .direction(bdLocation.getRadius())
                  .latitude(bdLocation.getLatitude())
                  .longitude(bdLocation.getLongitude())
                  .build();
          baiduMap.setMyLocationData(locData);
      
          LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
          MapStatus.Builder builder = new MapStatus.Builder();
          builder.target(ll).zoom(18.0f);
          baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
          }
      }
      /** 配置定位参数 */
      private void initLocation() {
          LocationClientOption option = new LocationClientOption();
          // 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
          option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
          // 可选,默认gcj02,设置返回的定位结果坐标系
          option.setCoorType("bd09ll");
          // 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
          int span = 5000;
          option.setScanSpan(span);
          // 可选,设置是否需要地址信息,默认不需要
          option.setIsNeedAddress(true);
          // 可选,默认false,设置是否使用gps
          option.setOpenGps(true);
          // 可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果
          option.setLocationNotify(true);
          // 可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
          option.setIsNeedLocationDescribe(true);
          // 可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
          option.setIsNeedLocationPoiList(true);
          // 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
          option.setIgnoreKillProcess(false);
          // 可选,默认false,设置是否收集CRASH信息,默认收集
          option.SetIgnoreCacheException(false);
          // 可选,默认false,设置是否需要过滤GPS仿真结果,默认需要
          option.setEnableSimulateGps(false);
          mLocationClient.setLocOption(option);
      }
      /**
      * 设置中心点和添加marker
      *
      * @param map
      * @param bdLocation
      * @param isShowLoc
      */
      public void setPosition2Center(BaiduMap map, BDLocation bdLocation, Boolean isShowLoc) {
          MyLocationData locData =
              new MyLocationData.Builder()
                  .accuracy(bdLocation.getRadius())
                  .direction(bdLocation.getRadius())
                  .latitude(bdLocation.getLatitude())
                  .longitude(bdLocation.getLongitude())
                  .build();
          map.setMyLocationData(locData);
      
          if (isShowLoc) {
          LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
          MapStatus.Builder builder = new MapStatus.Builder();
          builder.target(ll).zoom(18.0f);
          map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
          }
      }
      }
      
      //    将jar和so文件放在libs文件夹下 导入jar包
          sourceSets {
              main {
                  jniLibs.srcDirs = ['libs']
              }
          }
      
      <?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:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context=".MainActivity">
          <!--百度地图的view-->
          <com.baidu.mapapi.map.MapView
              android:id="@+id/bmapView"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:clickable="true" />
      </LinearLayout>
      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jamin_Ye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值