1 计算机表示图形的几种方式
多媒体:(包含文字 图片 音频 视频)
图形的大小 = 图片的总像素 * 每个像素的大小(byte)
单色 :每个像素最多可以表示2种颜色 只需要使用长度为1的二进制位来表示 那么每个 像素占1/8byte
16色 :每个像素最多可以表示16种颜色 0000 - 1111 那么只需要使用长度为4的二进制 表示 那么每个像素占1/2个byte
256色 :每个像素最多可以表示256种颜色 0000 0000 - 1111 1111 那么只需要使用长 度8的二进制位表示 那么每个像素占1byte
24位 :rgb 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1.......
r 1byte 0-255
g 1byte 0-255
b 1byte 0-255 那么一个像素占3byte
jpg 格式
png 格式 Android采用的是png格式
每个图片都会比我们算出来的 实际大小多 一些字节 这一些字节是用来存储一些额外信息的
______________________________________
2 缩放加载加载大图片
00:59:51.813: E/AndroidRuntime(2128): Caused by java.lang.OutOfMemoryError
00:59:51.813: E/dalvikvm-heap(2128): Out of memory on a 30720012-byte allocation.
在Android下采用ARGB来表示颜色 每个像素占4byte
Android下加载图片至于图片的像素有关。与本身图片的大小无关。
图片:2400*3200(这个不能写死)
手机:320*480
宽缩放: 7 2400/230
高缩放: 6 3200/480
我们一般按照大的去缩放。
需要考虑的问题 (1)动态获取图片的分辨率
(2)动态获取手机分辨率
这里的getWidth getHeight方法过时了,代替的方法如下
<span style="font-size:14px;">DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
System.out.println(dm.widthPixels+"..."+dm.heightPixels);</span>
或者官方推荐的:
<span style="font-size:14px;">Point point = new Point();
getWindowManager().getDefaultDisplay().getSize(point);
Log.d("sysout", point.x + "...." + point.y);</span>
____________________________________________________________________
3 创建原图的副本
创建原图副本的目的在于:由于原图不能修改,但是副本可以修改。
步骤如下:
<span style="font-size:14px;">public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]找到我们关心的控件
ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
//[2] 把tomcat.png 转换成bitmap 然后显示到iv_src
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);
//[2.1 test] 修改原图 原图不可以被修改
//srcBitmap.setPixel(20, 30, Color.RED);
iv_src.setImageBitmap(srcBitmap);
//[3]拷贝原图
//[3.1]创建模板
Bitmap copybitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//[3.2]想作画 需要一个画布 以copybitmap为模板
Canvas canvas = new Canvas(copybitmap);
//[3.3]创建一个画笔
Paint paint = new Paint();
//[3.4]开始作画 srcBitmap参考原图去画
canvas.drawBitmap(srcBitmap, new Matrix(), paint);
for (int i = 0; i < 10; i++) {
//[一次修改一个像素]
copybitmap.setPixel(20+i,30, Color.RED);
}
//[4]把copybitmap显示到iv_copy上
iv_copy.setImageBitmap(copybitmap);
}
}</span><span style="font-size: 24px;">
</span>
4 图形处理的api
注意不能两个set属性连用,因为他会覆盖你以前的,也就是说set方法只能改一次,
如果你要出现对图片进行两次操作 第一次用set 第二次用post方法.
______________________________________________
画画板案例:
public class MainActivity extends Activity {
private Bitmap srcBitmap;
private ImageView iv;
private Bitmap copyBitmap;
private Canvas canvas;
private Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]找到imageview 显示我们画的内容
iv = (ImageView) findViewById(R.id.iv);
//[2]把bg转换成bitmap
srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
//[2.1]创建模板
copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//[2.2]以copybitmap为模板 创建一个画布
canvas = new Canvas(copyBitmap);
//[2.3]创建一个画笔
paint = new Paint();
//[2.4]开始作画
canvas.drawBitmap(srcBitmap, new Matrix(), paint);
// canvas.drawLine(20, 20, 30, 50, paint);
//[3]把copybitmap显示到iv上
iv.setImageBitmap(copyBitmap);
//[4]给iv设置一个触摸事件
iv.setOnTouchListener(new OnTouchListener() {
int startX = 0;
int startY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
//[5]获取手指触摸的事件类型
int action = event.getAction();
//[6]具体判断一下是什么事件类型
switch (action) {
case MotionEvent.ACTION_DOWN: //按下
//[7]获取手指按下坐标
startX = (int) event.getX();
startY= (int) event.getY();
System.out.println("按下:"+startX+"---"+startY);
break;
case MotionEvent.ACTION_MOVE://移动
//[8]获取停止的坐标
int stopX = (int) event.getX();
int stopY = (int) event.getY();
System.out.println("移动:"+stopX+"---"+stopY);
//[9]画线
canvas.drawLine(startX, startY, stopX, stopY, paint);
//[9.1]更新一下起点坐标
startX = stopX;
startY = stopY;
//[10]记得更新ui
iv.setImageBitmap(copyBitmap);
break;
case MotionEvent.ACTION_UP: //抬起;
break;
}
//这里一定要设置 true 消费触摸事件,这样才能让监听器 监听到每一次的改变。
return true;
}
});
}
//点击按钮让画笔的颜色 变成红色
public void click1(View v) {
//设置画笔颜色
paint.setColor(Color.RED);
}
//让画笔颜色变粗
public void click2(View v) {
//设置画笔的宽度
paint.setStrokeWidth(15);
}
//保存大作
public void click3(View v) {
/**
* format 保存图片的格式
*
* quality 保存照片的质量
*/
try {
File file = new File(Environment.getExternalStorageDirectory().getPath(),"dazuo.png");
FileOutputStream fos = new FileOutputStream(file);
copyBitmap.compress(CompressFormat.PNG, 100, fos);
//发送一条sd卡挂载上来的广播 欺骗一下系统图库应用 说sd卡被挂载了 你去加载图片吧
Intent intent = new Intent();
//设置action
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
//设置data
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
//发送无序广播
sendBroadcast(intent);
fos.close(); //关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
}
——————————————————————————————
6 撕衣服小案例
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]找到iv 显示我们操作的图片
final ImageView iv = (ImageView) findViewById(R.id.iv);
//[2]把我们要操作的图片转换成bitmap
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre19);
//[3]创建原图的副本
//[3.1]创建模板
final Bitmap alterbBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
//[3.2]以alterbBitmap bitmap为模板创建一个画布
Canvas canvas = new Canvas(alterbBitmap);
//[3.3]创建一个画笔
Paint paint = new Paint();
//[3.4]开始作画 记住这里要按原图画
canvas.drawBitmap(srcBitmap, new Matrix(), paint);
//[4]把alterbitmap显示到iv上
iv.setImageBitmap(alterbBitmap);
//[5]给iv设置一个触摸事件
iv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//[6]获取触摸事件的类型
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE: //移动
for (int i = -7; i < 7; i++) { //改变x
for (int j = -7; j <7; j++) {
//为了 良好的用户体验 撕一个圆
if (Math.sqrt(i*i+j*j)<7) {
//一次修改一个像素
try {
alterbBitmap.setPixel((int)event.getX()+i, (int)event.getY()+j, Color.TRANSPARENT);
} catch (Exception e) {
}
}
}
}
//一定要记得更新iv
iv.setImageBitmap(alterbBitmap);
break;
}
return true;
}
});
}
}
_______________________________________________________
7 使用mediaplayer播放音频文件
[1]作用:这个类用于播放音频或者是视频
播放网络音乐:
这里我们使用异步的去准备播放音乐,因为我们在对网络进行请求的时候,
如果使用同步播放会卡顿一下才能播放。
MediaPlayer有一个监听器,setOnPreparedListener()监听器,
这个监听器的方法就是当你要播放的文件已经准备好的时候才播放。
一般用于我们网络环境不好的时候,先会在这个监听器里面准备一个进度对话框
当准备完成的时候进度对话框就消失,就可以播放了。
_______________________________________________________
8 百度音乐盒完成
一般世面上的应用程序一般都在 服务中播放,所以我们在之前第八天
写的补充一下就可以了。
seekBar:可以拖动的进度条.
[1]获取当前歌曲进度和总时长
[2]在服务中添加一个播放进度的方法
[3]通过handler 把数据传递到mainActivity
[4]seekbar处理数据
public class MainActivity extends Activity {
private Iservice iservice; // 这个就是我们定义的中间人对象
private MyConn conn;
private static SeekBar sbar;
public static Handler handler = new Handler(){
//当 接收到消息该方法执行
public void handleMessage(android.os.Message msg) {
//[1]获取msg 携带的数据
Bundle data = msg.getData();
//[2]获取当前进度和总进度
int duration = data.getInt("duration");
int currentPosition = data.getInt("currentPosition");
//[3]设置seekbar的最大进度和当前进度
sbar.setMax(duration); //设置进度条的最大值
sbar.setProgress(currentPosition);//设置当前进度
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sbar = (SeekBar) findViewById(R.id.seekBar1);
//[0]先调用startservice 方法开启服务 保证服务在后台长期运行
Intent intent = new Intent(this, MusicService.class);
startService(intent);
// [1]调用bindservice 目的是为了获取我们定义的中间人对象
conn = new MyConn();
// 连接MusicService 服务 获取我们定义的中间人对象
bindService(intent, conn, BIND_AUTO_CREATE);
//[2]给seekbar 设置监听
sbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
//当停止拖动执行
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//设置播放的位置
iservice.callSeekToPosition(seekBar.getProgress());
}
//开始拖动
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
}
// 点击按钮 进行 音乐播放
public void click1(View v) {
// 调用播放音乐的方法
iservice.callPlayMusic();
}
// 暂停音乐
public void click2(View v) {
// 调用暂停音乐的方法
iservice.callPauseMusic();
}
// 继续播放
public void click3(View v) {
// 调用继续播放
iservice.callrePlayMusic();
}
// 当Activity销毁的时候调用
@Override
protected void onDestroy() {
// 在Activity销毁的时候 取消绑定服务
unbindService(conn);
super.onDestroy();
}
private class MyConn implements ServiceConnection {
// 当连接成功时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 获取我们定义的中间人对象
iservice = (Iservice) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
//音乐播放服务
public class MusicService extends Service {
private MediaPlayer player;
//[2]把我们定义的中间人对象 返回
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
//服务第一次开启的是调用
@Override
public void onCreate() {
//[1]初始化mediaplayer
player = new MediaPlayer();
super.onCreate();
}
//当服务销毁的时候调用
@Override
public void onDestroy() {
super.onDestroy();
}
//设置播放音乐指定位置的方法
public void seekToPosition(int position){
player.seekTo(position);
}
//专门用来播放音乐的
public void playMusic(){
System.out.println("音乐播放了");
//[2]设置要播放的资源 path 可以是本地也可是网络路径
try {
player.reset();
player.setDataSource("/mnt/sdcard/xpg.mp3");
//[3]准备播放
player.prepare();
//[4]开始播放
player.start();
//[5]更新进度条
updateSeekBar();
} catch (Exception e) {
e.printStackTrace();
}
}
//更新进度条的方法
private void updateSeekBar() {
//[1]获取当前歌曲总时长
final int duration = player.getDuration();
//[2]一秒钟获取一次当前进度
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
@Override
public void run() {
//[3]获取当前歌曲的进度
int currentPosition = player.getCurrentPosition();
//[4]创建message对象
Message msg = Message.obtain();
//[5]使用msg携带多个数据
Bundle bundle = new Bundle();
bundle.putInt("duration", duration);
bundle.putInt("currentPosition", currentPosition);
msg.setData(bundle);
//发送消息 MainActivity的handlemessage方法会执行
MainActivity.handler.sendMessage(msg);
}
};
//300毫秒后 每隔1秒钟获取一次当前歌曲的进度
timer.schedule(task, 300, 1000);
//[3]当歌曲播放完成的时候 把timer 和task 取消
player.setOnCompletionListener(new OnCompletionListener() {
//当歌曲播放完成的回调
@Override
public void onCompletion(MediaPlayer mp) {
System.out.println("歌曲播放完成了 ");
timer.cancel();
task.cancel();
}
});
}
//音乐暂停了
public void pauseMusic(){
System.out.println("音乐暂停了");
//暂停
player.pause();
}
//音乐继续播放的方法
public void rePlayMusic(){
System.out.println("音乐继续播放了");
player.start();
}
//[1]定义一个中间人对象(IBinder)
private class MyBinder extends Binder implements Iservice{
//调用播放音乐的方法
@Override
public void callPlayMusic() {
playMusic();
}
//调用暂停音乐的方法
@Override
public void callPauseMusic() {
pauseMusic();
}
//调用继续播放的方法
@Override
public void callrePlayMusic() {
rePlayMusic();
}
//调用设置播放指定位置的方法
@Override
public void callSeekToPosition(int position) {
seekToPosition(position);
}
}
}
MediaPlayer有一个监听器,setOnCompletionListener();这个监听器的作用,
就是在你播放的文件,播放完成后会执行这个方法。一般用于关闭类
_______________________________________________________
9 mediaplayer的生命周期
MediaPlayer这个类是用来播放音频和视频的,如果你用来播放图片就会走。
onErrorListener()监听器 END
如果你使用releas()方法的时候也会走 END
SetDataSource()后就初始化了,然后就可以进行同步的prepared();
或者进行异步的preparedAsync();
播放网络的时候我们使用异步的准备,因为异步就相当于开了一个子线程,不需要等待响应再去执行。
当我们调用stop()方法的时候我们可以发现,一旦调用stop方法就是一个单向的
停止。
这样我们想再要播放只能重新调用reset()方法进行重新开始播放。
_______________________________________________________
10 (播放视频)surfaceview介绍(游戏中才用得到)了解
当我们要播放视频的时候我们要用到。MediaPlayer类的setDisplay()方法
里面需要接受一个surfaceHolder()这个接口。我们要拿到这个实例,我们可以通过
surfaceView这个控件。
[1]surfaceview 控件是一个重量级控件
[2]内部维护了2个线程
A 获取数据 负责显示
B 负责显示 获取数据
一般用于播放帧播放要求比较高的文件。
[3]他可以直接在子线程更新ui 与进度相关的控件可以直接在子线程更新ui
public class MainActivity extends Activity {
private MediaPlayer player;
private int currentPosition; //当前视频播放的位置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
final SurfaceView sfv = (SurfaceView) findViewById(R.id.sfv);
final SurfaceHolder surfaceHolder = sfv.getHolder();
//添加一个callback
surfaceHolder.addCallback(new Callback() {
//当surfaceview销毁的时候调用
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("surfaceDestroyed");
if (player!=null && player.isPlaying()) {
//获取当前视频播放的位置
currentPosition = player.getCurrentPosition();
player.stop();
}
}
//当surfaceview 初始化了
@Override
public void surfaceCreated(SurfaceHolder holder) {
//[1]初始化mediaplayer
player = new MediaPlayer();
//[2]设置要播放的资源 path 可以是本地也可是网络路径
try {
player.setDataSource("http://192.168.13.89:8080/cc.MP4");
//[2.1]设置播放视频的内容 SurfaceHolder 是用来维护视频播放的内容
player.setDisplay(surfaceHolder);
//[3]准备播放
// player.prepare();
player.prepareAsync();
//设置一个准备完成的监听
player.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//[4]开始播放
player.start();
//[5]继续上次的位置继续播放
player.seekTo(currentPosition);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
});
}
}
_______________________________________________________
补充1 :VideoView
[1]这个控件就是对surfaceview 和 meidiaplayer进行封装
[2]meidiaplayer 播放视频他只支持 3gp MP4格式 。
其他的格式只能播放声音。
补充2 :vitamio框架
使用步骤:
1 引入vitamio框架 以library、
2 在布局中定义VideoView
<io.vov.vitamio.widget.VideoView
android:id="@+id/vv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
3 mainactivity代码
插件vitamio框架检查是否可用
if (!LibsChecker.checkVitamioLibs(this)) {
return;
}
final VideoView vv = (VideoView) findViewById(R.id.vv);
vv.setVideoPath("http://192.168.1.2:8080/haha.avi");
vv.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
vv.start();
}
});
//设置video的控制器
vv.setMediaController(new MediaController(this));
4 一定要在清单文件初始化InitActivity
<activity android:name="io.vov.vitamio.activity.InitActivity"></activity>
2 在布局中定义VideoView
<io.vov.vitamio.widget.VideoView
android:id="@+id/vv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
3 mainactivity代码
插件vitamio框架检查是否可用
if (!LibsChecker.checkVitamioLibs(this)) {
return;
}
final VideoView vv = (VideoView) findViewById(R.id.vv);
vv.setVideoPath("http://192.168.1.2:8080/haha.avi");
vv.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
vv.start();
}
});
//设置video的控制器
vv.setMediaController(new MediaController(this));
4 一定要在清单文件初始化InitActivity
<activity android:name="io.vov.vitamio.activity.InitActivity"></activity>
现在我们播放视频有这几种方式:
1 .MediaPlayer
2 .VideoView
3.vitamio框架
视频解码我们用到了这个开源项目: ffmpeg 是由好几十个C大神写的
一般市面上有比较好的开源项目,我们都直接使用它,不需要重新去写。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// [1]插件vitamio框架检查是否可用
if (!LibsChecker.checkVitamioLibs(this)) {
return;
}
final VideoView vv = (VideoView) findViewById(R.id.vv);
// 设置播放的路径
vv.setVideoPath("http://192.168.13.89:8080/aa.avi");
vv.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
vv.start();
}
});
// 设置video的控制器 设置一个进度条
vv.setMediaController(new MediaController(this));
}
}
——————————————————————————————————
11 照相和录像
我们直接调用系统 自带的 软件就可以了。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 点击按钮 进行照相
public void click1(View v) {
// 照相 创建意图
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 存放图片的路径
File file = new File(Environment.getExternalStorageDirectory()
.getPath(), "haha.png");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the
// image
// file
// name
// 开启一个activity 并获取结果
startActivityForResult(intent, 1);
}
// 点击按钮 进行录像
public void click2(View v) {
// 照相 创建意图
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
// 存放图片的路径
File file = new File(Environment.getExternalStorageDirectory()
.getPath(), "haha.3gp");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the
// image
// file
// name
// 开启一个activity 并获取结果
startActivityForResult(intent, 2);
}
// 当开启的这个Activity页面的关闭的时候调用
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
System.out.println("哈哈 方法调用了");
super.onActivityResult(requestCode, resultCode, data);
}
}
______________________________________________________
补充:
Timer这个类:定时器类
一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
两个参数的意思就是,每相隔一段时间 重复执行一次。
这个定时器主要用在我们的百度音乐播放器的进度获取,
因为我们的当前进度要时时刻刻的拿,所以我们用这个类来设置多少秒获取一次进度。
public class MainActivity extends Activity {
private Timer timer;
private TimerTask task;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建定时器
timer = new Timer();
//创建task
task = new TimerTask() {
@Override
public void run() {
System.out.println("啊哈哈 我执行了");
}
};
//2秒钟后 执行run方法
timer.schedule(task, 5000,1000);
}
@Override
protected void onDestroy() {
//当Activity销毁的时候取消timer
timer.cancel();
task.cancel();
super.onDestroy();
}
}
_______________________________________________________
传感器
获取手机的所有传感器
//获取手机上面的所有传感器
List<Sensor> sensors = manager.getSensorList(Sensor.TYPE_ALL);
StringBuilder sBuilder = new StringBuilder();
for (Sensor s : sensors) {
String name = s.getName();
int type = s.getType();
sBuilder.append("name=="+name+"--type="+type+"\r\n");
}
tv.setText(sBuilder.toString());
final TextView tv = (TextView)findViewById(R.id.tv);
//1.得到传感器管理者
SensorManager manager = (SensorManager) getSystemService(SENSOR_SERVICE);
//2.得到光线传感器对象
Sensor sensor = manager.getDefaultSensor(Sensor.TYPE_LIGHT);
//3.监听一个传感器的数据。 这里的第三个参数 是速率
manager.registerListener(new SensorEventListener() {
//数据发生了改变的时候调用
@Override
public void onSensorChanged(SensorEvent event) {
float value = event.values[0]; //得到当前的亮度值
tv.setText("当前的亮度是---》:"+value);
}
//精度发生了改变的时候调用 这个方法用在 定位GPS 当你在室内的时候定位的进度就低
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, sensor, SensorManager.SENSOR_DELAY_NORMAL);
______________________________________________________
补充:
指南针:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv = (TextView)findViewById(R.id.tv);
SensorManager manager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor sensor = manager.getDefaultSensor(3);
manager.registerListener(new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
// values[0]: 手机的Y轴与正北方向的夹角 . 如果是 :0=North, 如果是: 90=East, 如果是:180=South,如果是:270=West
int value = (int) event.values[0];
String str = "";
if (value == 0) {
str = "正北方向:" + value;
} else if (value == 90) {
str = "正东方向:" + value;
} else if (value == 180) {
str = "正南方向:" + value;
} else if (value == 270) {
str = "正西方向:" + value;
} else if (value > 0 && value < 90) {
str = "东北方向:" + value;
} else if (value > 90 && value < 180) {
str = "东南方向:" + value;
} else if (value > 180 && value < 270) {
str = "西南方向:" + value;
} else if (value > 270 && value < 360) {
str = "西北方向:" + value;
}
tv.setText(str);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}