Android 第十天重置版 _media_注意事项

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>


 
现在我们播放视频有这几种方式:
  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);
	}

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值