安卓移动-作业8
1 实验目的 (Experiment Purpose)
- Be familiar with the basic usage of GPS positioning and location
manager. - Master the calling method of the camera.
- Be familiar with the method of playing audio.
- Be familiar with the method of playing video.
- Master the method of acquiring wireless signal strength.
- Be familiar with the scanning, monitoring and communication methods
of Bluetooth devices.
1.熟悉GPS定位和位置管理器的基本用法。
2.掌握摄像头的调用方法。
3.熟悉实现播放音频的方法。
4.熟悉实现播放视频的方法。
5.掌握获取无线信号强度的方法。
6.熟悉实现蓝牙设备的扫描、监听以及通信的方法。
2 实验环境 (Experiment Environment)
software:Android Studio 2021.2.1 Patch 2
Operating system:Window 10
3 实验内容 (Experiment content)
3.1 Experimental data
略
3.2 Experimental process
需求
Program to obtain GPS information and display longitude and latitude.
Write a program to call the camera to take a picture.
After taking a picture, open the email sending application to send the picture.
Write program to realize video player. Use services to implement audio players.
Write a program to link the Bluetooth headset to play music.
Write programs to obtain the signal strength of wifi and bluetooth devices. Compile, debug and view program running results.
编写程序获取GPS信息,显示经纬度。
编写程序调用摄像头拍照功能,拍照后打开邮件发送应用,发送照片。
编写程序实现视频播放器。
使用服务实现音频播放器。
编写程序链接蓝牙耳机播放音乐。
编写程序获取wifi和蓝牙设备的信号强度。
编译、调试和查看程序运行结果。
步骤
Set the layout of quiz in Android/app/res/layout.
在 Android/app/res/layout文件中设定问题的布局。


3.3 Experimental results
The results display and code implementation are shown as follows:
结果展示和代码实现如下图:
package com.example.experiment5;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
public class BluetoothActivity extends AppCompatActivity implements
AdapterView.OnItemClickListener {
private static final String TAG = "BluetoothActivity";
// 本地蓝牙适配器
private BluetoothAdapter bluetoothAdapter;
private Button btn_search;
private boolean scanning;
private Handler handler;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 5000;
//搜索到蓝牙显示列表
private ListView mylistview;
// listview的adapter
private ArrayAdapter<String> mylistAdapter;
// 存储搜索到的蓝牙
private List<String> bluetoothdeviceslist = new ArrayList<String>();
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
checkBluetoothPermission();
initview();
SearchBluetoot();
}
private void initview() {
mylistview = (ListView) findViewById(R.id.mylistview);
btn_search = (Button) findViewById(R.id.btn_search);
// 获取本地蓝牙适配器
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
btn_search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setTitle("正在搜索...");
// 判断是否在搜索,如果在搜索,就取消搜索
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
// 开始搜索
bluetoothAdapter.startDiscovery();
}
});
}
public void SearchBluetoot() {
// 判断有没有蓝牙硬件支持
if (bluetoothAdapter == null) {
Log.d(TAG, "设备不支持蓝牙");
Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
finish();
}
else
{
Log.d(TAG, "找到蓝牙");
}
// 判断是否打开了蓝牙
if (!bluetoothAdapter.isEnabled()) {
Log.d(TAG, "没有打开蓝牙");
// 我们通过startActivityForResult()方法发起的Intent将会在onActivityResult()
// 回调方法中获取用户的选择,比如用户单击了Yes开启,
// 那么将会收到RESULT_OK的结果,
// 如果RESULT_CANCELED则代表用户不愿意开启蓝牙
// 弹出对话框提示用户是否打开
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
// 没有提示强制打开蓝牙(用enable()方法来开启,
// 无需询问用户(实惠无声息的开启蓝牙设备),
// 这时就需要用到android.permission.BLUETOOTH_ADMIN权限)
// mBluetoothAdapter.enable();
} else {
// 获的已经配对的设备
Set<BluetoothDevice> myDevices = bluetoothAdapter.getBondedDevices();
/// 判断是否有配对过的设备
if (myDevices.size() > 0) {
for (BluetoothDevice device : myDevices) {
// 遍历到列表中
bluetoothdeviceslist.add(device.getName() + ":" + device.getAddress() + "\n");
}
}
else
Log.d(TAG, "没有找到配对的蓝牙设备");
mylistAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
android.R.id.text1, bluetoothdeviceslist);
mylistview.setAdapter(mylistAdapter);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
scanLeDevice(true);
}
// 找到设备的广播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
// 注册广播
registerReceiver(myreceiver, filter);
// 搜索完成的广播
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
// 注册广播
registerReceiver(myreceiver, filter);
}
}
/**
* 扫描蓝牙设备
* @param enable 开始/停止扫描
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void scanLeDevice(final boolean enable) {
Log.d(TAG, "扫描 LEBluetooth");
handler = new Handler();
if (enable) {
// Stops scanning after a pre-defined scan period.
handler.postDelayed(new Runnable() {
@Override
public void run() {
scanning = false;
bluetoothAdapter.stopLeScan(mLeScanCallback);
BluetoothActivity.this.invalidateOptionsMenu();
}
}, SCAN_PERIOD);
scanning = true;
bluetoothAdapter.startLeScan(mLeScanCallback);
} else {
scanning = false;
bluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
// 设备扫描回调
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
Log.i(TAG, "蓝牙信息强度 rssi: " + rssi);
}
};
// 广播接收器
private final BroadcastReceiver myreceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 收到的广播类型
String action = intent.getAction();
// 发现设备的广播
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 从intent中获取设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 判断是否配对过
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
// 添加到列表
bluetoothdeviceslist.add(device.getName() + ":"+ device.getAddress() + "\n");
mylistAdapter.notifyDataSetChanged();
}
// 搜索完成
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setTitle("搜索完成!");
}
}
};
/*
校验蓝牙权限
*/
private void checkBluetoothPermission() {
if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.M) {
// Android M Permission check
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
},
PERMISSION_REQUEST_COARSE_LOCATION);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED) {
SearchBluetoot();
} else { // 申请失败,可以继续向用户解释。
Toast.makeText(BluetoothActivity.this, "没有权限,无法使用",
Toast.LENGTH_SHORT).show();
}
return;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
结果展示:

package com.example.experiment5;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class CameraActivity extends AppCompatActivity
{
public static final int TAKE_PHOTO = 1; // 声明一个状态码,用于识别返回的结果
private ImageView picture;
private Uri ImageUri;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
requestPermission(); // 权限申请
Button takePhoto = (Button) findViewById(R.id.take_photo);
picture = (ImageView) findViewById(R.id.picture);
takePhoto.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
/*
创建File对象,用于存储拍照后的图片,把这个图片命名为output_image.jpg,
并把它存放在应用关联缓存目录下,调用getExternalCacheDir()可以得到这个目录
由于android6.0开始,读写sd卡列为了危险权限,使用的时候必须要有权限,
应用关联目录则可以跳过这一步
*/
File outputImage = new File(getExternalCacheDir(), "outputImage.jpg");
try
{
// 判断图片是否存在,存在则删除在创建,不存在则直接创建
if (outputImage.exists())
{
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e)
{
e.printStackTrace();
}
// 判断安卓的版本是否高于7.0,高于则调用高于的方法,低于则调用低于的方法
if (Build.VERSION.SDK_INT >= 24)
{
// FileProvider是一种特殊的内容提供器,可以对数据进行保护
ImageUri = FileProvider.getUriForFile(CameraActivity.this,
"com.example.experiment5.fileprovider", outputImage);
}
else
{
ImageUri = Uri.fromFile(outputImage);
}
// 启动相机程序
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, ImageUri);
startActivityForResult(intent, TAKE_PHOTO);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode)
{
case TAKE_PHOTO:
if (resultCode == RESULT_OK)
{
try
{
//将拍摄的照片显示出来
Bitmap bitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(ImageUri));
picture.setImageBitmap(bitmap);
} catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
break;
default:
break;
}
}
/**
* 申请权限
*/
public static final int CAMERA_REQ_CODE = 111;
private void requestPermission()
{
// 判断当前Activity是否已经获得了该权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
// 如果App的权限申请曾经被用户拒绝过,就需要在这里跟用户做出解释
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA))
{
Toast.makeText(CameraActivity.this, "请进入设置-应用管理-打开相机权限", Toast.LENGTH_SHORT).show();
}
else
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQ_CODE);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch (requestCode)
{
case CAMERA_REQ_CODE:
{ // 如果请求被拒绝,那么通常grantResults数组为空
if (grantResults.length > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED)
{
// 申请成功,进行相应操作
}
else
{ // 申请失败,可以继续向用户解释。
Toast.makeText(CameraActivity.this,
"没有相机权限,您可能无法使用相机",
Toast.LENGTH_SHORT).show();
}
return;
}
}
}
}
结果展示:
package com.example.experiment5;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
// 在真机上使用
public class LocationActivity extends AppCompatActivity
{
private static final int REQUEST_CODE = 200;
private TextView positionTextView;
private LocationManager locationManager;
private String provider;
Location location;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(LocationActivity.this,
new String[]{
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
}, REQUEST_CODE);
}
else
{
TestLocation();
}
}
LocationListener locationListener = new LocationListener()
{
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider)
{
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider)
{
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location)
{
showLocation(location);
}
};
public void TestLocation()
{
positionTextView = (TextView) findViewById(R.id.position_text_view);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providerList = locationManager.getProviders(true);
if (providerList.contains(LocationManager.GPS_PROVIDER))
{
provider = LocationManager.GPS_PROVIDER;
}
else if (providerList.contains(LocationManager.NETWORK_PROVIDER))
{
provider = locationManager.NETWORK_PROVIDER;
}
else
{
Toast.makeText(this, "No Location provider to use",
Toast.LENGTH_SHORT).show();
return;
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
// TODO: Consider calling
// ActivityCompat#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 ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(provider, 5000, 1, locationListener);
}
public void getLocation(View view)
{
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
// TODO: Consider calling
// ActivityCompat#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 ActivityCompat#requestPermissions for more details.
return;
}
location = locationManager.getLastKnownLocation(provider);
showLocation(location);
}
private void showLocation(Location location) {
String currentPosition = "latitude is " + location.getLatitude() + "\n"
+ "longitude is " + location.getLongitude();
positionTextView.setText(currentPosition);
}
}
package com.example.experiment5;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class SignalStrengthActivity extends AppCompatActivity {
String wifi_name;
int wifi_rssi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_r_s_s_i);
//定义按键实例
Button btnRSSI = (Button)findViewById(R.id.wifi_rssi);
//定义按钮点击事件
btnRSSI.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取wifi服务
WifiManager wifiManager= (WifiManager)
getApplicationContext().getSystemService(WIFI_SERVICE);
assert wifiManager != null;
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
wifi_name = wifiInfo.getSSID();
wifi_rssi = wifiInfo.getRssi();
Log.d("wifiInfo", wifiInfo.toString());
Log.d("SSID", wifiInfo.getSSID());
//通过Toast输出
Toast.makeText(SignalStrengthActivity.this,
"RSSI:" + wifi_rssi + "---WiFi Id:" + wifi_name,
Toast.LENGTH_SHORT).show();
}
});
}
}
package com.example.experiment5;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;
import java.io.File;
public class VideoActivity extends AppCompatActivity implements View.OnClickListener
{
private VideoView videoView;
private Button videoPlay;
private Button videoPause;
private Button videoReplay;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TestVideo();
}
public void TestVideo()
{
setContentView(R.layout.activity_video);
videoPlay = (Button) findViewById(R.id.video_play);
videoPause = (Button) findViewById(R.id.video_pause);
videoReplay = (Button) findViewById(R.id.video_replay);
videoView = (VideoView) findViewById(R.id.video_view);
videoPlay.setOnClickListener(this);
videoPause.setOnClickListener(this);
videoReplay.setOnClickListener(this);
getVideoPath();
}
private void getVideoPath()
{
// 先将本地的视频上传到模拟器中
// 视频上传路径:/sdcard/Android/data/com.example.experiment5/files/androidstudio.3gp
File file = new File(getExternalFilesDir(null), "1.mp4");
Log.d("Video", file.getAbsolutePath());
if (!file.exists())
{
Toast.makeText(this, "视频文件路径错误", Toast.LENGTH_SHORT).show();
return;
}
else
{
Toast.makeText(this, "视频文件路径正确", Toast.LENGTH_SHORT).show();
}
if (ContextCompat.checkSelfPermission(VideoActivity.this, Manifest.permission.
WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(VideoActivity.this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);//权限返回码为1
}
else
{
// 设置视频文件
videoView.setVideoPath(file.getPath());
videoView.start();
}
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.video_play:
if (!videoView.isPlaying())
{
videoView.start();
}
break;
case R.id.video_pause:
if (videoView.isPlaying())
{
videoView.pause();
}
break;
case R.id.video_replay:
if (videoView.isPlaying())
{
videoView.resume();
}
break;
}
}
}
结果展示:
4 实验小结 (Summary)
My thoughts and experiences
How to operate the camera and various sensing devices?
如何操控摄像头和各种传感设备?
Apply for permission first. After the permission is passed, use startActivityForResult to jump from the current page to the camera and other sensing devices. After taking photos, use onActivityResult to design subsequent actions. Because there may be multiple requests, the requestCode is required. Different requestCodes are used to respond to different requests in the onActivityResult.
先申请权限,权限通过后,使用startActivityForResult从当前页面跳转到相机等传感设备,拍完照后使用onActivityResult进行后续动作的设计。因为可能有多种请求,所以需要requestCode,在onActivityResult通过不同的requestCode对不同的请求进行回应。

浙公网安备 33010602011771号