当模块间互相调用方法的时候,可以使用eventbus库,进行快速调用。
使用方法 参考博客
Github地址
重写返回键方法
private static boolean isSysExit = false;
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
if(!isSysExit){
isSysExit = true;
Toast.makeText(this, "按返回键确认退出", Toast.LENGTH_SHORT).show();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
isSysExit =false;
}
}, 2000);
}else {
finish();
}
}
使用方法 参考博客
第一步现在xml下静态注册广播接收器(英文高版本不支持原因,推荐动态注册)
推荐的静态注册方法 (放在了MainActivity的onCreate方法里)
// 1. 实例化BroadcastReceiver子类 & IntentFilter
USBReceiver mUSBReceiver = new USBReceiver();
IntentFilter intentFilter = new IntentFilter();
// 2. 设置接收广播的类型
intentFilter.addAction("com.example.whitebalance.USBReceiver");
intentFilter.addAction("android.intent.action.BOOT_COMPLETED");
intentFilter.addAction("android.intent.action.MEDIA_MOUNTED");
intentFilter.addAction("android.intent.action.MEDIA_UNMOUNTED");
intentFilter.addAction("android.intent.action.MEDIA_REMOVED" );
intentFilter.addDataScheme("file" );
// 3. 动态注册:调用Context的registerReceiver()方法
registerReceiver(mUSBReceiver, intentFilter);
新建一个接收器类
public class USBReceiver extends BroadcastReceiver {
private static final String TAG = USBReceiver.class.getSimpleName();
private static final String MOUNTS_FILE = "/proc/mounts";
private StorageManager mStorageManager;
@Override
public void onReceive(Context context, Intent intent) {
mStorageManager = (StorageManager) context.getSystemService(Activity.STORAGE_SERVICE);
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
String mountPath = intent.getData().getPath();
Uri data = intent.getData();
Log.d(TAG, "mountPath = " + mountPath);
if (!TextUtils.isEmpty(mountPath)) {
//读取到U盘路径再做其他业务逻辑
SPUtils.getInstance().put("UsbPath", mountPath);
boolean mounted = isMounted(mountPath);
Log.d(TAG, "onReceive: " + "U盘挂载" + mounted);
getUName();
}
} else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED) || action.equals(Intent.ACTION_MEDIA_EJECT)) {
Log.d(TAG, "onReceive: " + "U盘移除了");
} else if (action.equals("android.intent.action.BOOT_COMPLETED")) {
//如果是开机完成,则需要调用另外的方法获取U盘的路径
}
}
/**
* 判断是否有U盘插入,当U盘开机之前插入使用该方法.
* @param path
* @return
*/
public static boolean isMounted(String path) {
boolean blnRet = false;
String strLine = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(MOUNTS_FILE));
while ((strLine = reader.readLine()) != null) {
if (strLine.contains(path)) {
blnRet = true;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
reader = null;
}
}
return blnRet;
}
/**
* 获取U盘的路径和名称
*/
private void getUName() {
Class> volumeInfoClazz = null;
Method getDescriptionComparator = null;
Method getBestVolumeDescription = null;
Method getVolumes = null;
Method isMountedReadable = null;
Method getType = null;
Method getPath = null;
List> volumes = null;
try {
volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo");
getDescriptionComparator = volumeInfoClazz.getMethod("getDescriptionComparator");
getBestVolumeDescription = StorageManager.class.getMethod("getBestVolumeDescription", volumeInfoClazz);
getVolumes = StorageManager.class.getMethod("getVolumes");
isMountedReadable = volumeInfoClazz.getMethod("isMountedReadable");
getType = volumeInfoClazz.getMethod("getType");
getPath = volumeInfoClazz.getMethod("getPath");
volumes = (List>) getVolumes.invoke(mStorageManager);
for (Object vol : volumes) {
if (vol != null && (boolean) isMountedReadable.invoke(vol) && (int) getType.invoke(vol) == 0) {
File path2 = (File) getPath.invoke(vol);
String p1 = (String) getBestVolumeDescription.invoke(mStorageManager, vol);
String p2 = path2.getPath();
Log.d(TAG, "-----------path1-----------------" + p1); //打印U盘卷标名称
Log.d(TAG, "-----------path2 @@@@@-----------------" + p2); //打印U盘路径
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Intent it = new Intent("com.example.whitebalance.PreUSBReceiver");//自定义的广播名称
sendBroadcast(it);
让video组件和父组件大小一致,布局文件
然后设置一个主题样式即可(NoActionBar)
注册
@SuppressLint("HandlerLeak")
Handler toastHandler = new Handler(){
@Override
public void handleMessage(Message msg){
switch (msg.what){
case 1:
Toast.makeText(getApplicationContext(), "PC连接成功", Toast.LENGTH_LONG).show();
break;
}
super.handleMessage(msg);
}
};
使用
ConnectPCService.this.toastHandler.sendEmptyMessage(1);
使用方法 参考博客
private StorageManager mStorageManager;
mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
//获取所有挂载的设备(内部sd卡、外部sd卡、挂载的U盘)
List volumes = mStorageManager.getStorageVolumes();
try {
Class> storageVolumeClazz = Class
.forName("android.os.storage.StorageVolume");
//通过反射调用系统hide的方法
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
for (int i = 0; i < volumes.size(); i++) {
StorageVolume storageVolume = volumes.get(i);//获取每个挂载的StorageVolume
//通过反射调用getPath、isRemovable
String storagePath = (String) getPath.invoke(storageVolume); //获取路径
boolean isRemovableResult = (boolean) isRemovable.invoke(storageVolume);//是否可移除
String description = storageVolume.getDescription(this);
Log.d("jason", " i=" + i + " ,storagePath=" + storagePath
+ " ,isRemovableResult=" + isRemovableResult +" ,description="+description);
}
} catch (Exception e) {
Log.d("jason", " e:" + e);
}
public class ConnectPCService extends Service {
private Socket mSocket;
private SocketConnectThread socketConnectThread;
private OutputStream mOutStream;
private InputStream mInStream;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "服务已经启动", Toast.LENGTH_LONG).show();
socketConnectThread = new SocketConnectThread(USB_config.PCIP);
socketConnectThread.start();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "服务已经停止", Toast.LENGTH_LONG).show();
}
//service 内部类
class SocketConnectThread extends Thread{
private String IP;
public SocketConnectThread(String IP){
this.IP = IP;
}
public void run(){
Log.e("info", "run: ============socket线程启动" );
try {
//指定ip地址和端口号
if(mSocket != null) mSocket.close();
mSocket = new Socket(this.IP, 1989);
Log.e("info", "run: "+ this.IP);
if(mSocket != null){
//获取输出流、输入流
mOutStream = mSocket.getOutputStream();
mInStream = mSocket.getInputStream();
}else {
Log.e("info", "run: =========scoket==null");
}
Log.e("info","connect success========================================");
send(this.IP);
startReader(mSocket);
} catch (Exception e) {
e.printStackTrace();
if(mSocket != null) {
try {
mSocket.close();
}catch (Exception ee) {
ee.printStackTrace();
}
}
return;
}
}
}
private void startReader(final Socket socket) {
new Thread(){
@Override
public void run() {
DataInputStream reader;
try {
// 获取读取流
reader = new DataInputStream(socket.getInputStream());
while (true) {
System.out.println("*等待客户端输入*");
//Thread.currentThread().sleep(1000);
// 读取数据
String msg="";
Log.d("msg", "Read Attempt");
msg = reader.readLine();
if (msg == null)
{
Log.d("msg", "continue");
Thread.currentThread().sleep(1000);
continue;
}
Log.d("msg", "获取到客户端的信息:=" + msg);
}
} catch (IOException e) {
e.printStackTrace();
Log.e("msg", "Read Failed e",e);
} catch(InterruptedException e)
{
Log.e("msg", "Failed ee",e);
}finally {
try {
Log.e("msg", "Read close");
mSocket.close();
}catch (Exception ee) {
ee.printStackTrace();
}
}
}
}.start();
}
public void send(final String str) {
if (str.length() == 0){
return;
}
new Thread() {
@Override
public void run() {
try {
// socket.getInputStream()
DataOutputStream writer = new DataOutputStream(mSocket.getOutputStream());
writer.writeUTF(str); // 写一个UTF-8的信息
System.out.println("发送消息");
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}