Android 快传 文件互传

原创 2016年05月30日 23:50:58

一个月没有更新内容,因为想要实践一下自己的理论知识,于是参加了一个软件类比赛,选题为移动设备之间的文件互传。
不得不说,实践的确是锻炼解决问题能力的最好办法。 遇到了很多自己在一般demo中,并没有发现的问题,并且学习很多新的知识。
这里写图片描述
准备将这个Android实例的开发过程记录。

软件功能:

  • 各类型文件的快速访问
  • 实现手机的文件的快速分享
  • 通过电脑对于手机的文件访问

主要技术:

1.文件阅览:

  • 已安装APK软件:
    这里写图片描述
    通过packageManager这个用于管理应用程序包,便能获取已安装程序的许多相应信息。具体到软件中的实现参考了 郭霖 公众号中推送的这篇仿QQ获取手机中的APK并分享

  • 这里写图片描述 这里写图片描述
    多媒体文档以及office文档:通过MediaStore的方式,根据相应文件类型的Uri来进行查找。MediaStore是android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取。(MediaStore相应基础知识)。
    可以通过相应的SQL语句对数据进行查询。如music则传入
    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
    例PPT则为
    MediaStore.Files.getContentUri("external"),type
    type为查询得的MIME类型
    MediaStore.Files.FileColumns.MIME_TYPE==application/mspowerpoint
    在按上面说明的Cursor,定义一个总的读取数据的方式。

   public synchronized List<TFile> getMediaFiles(Activity cxt , Uri uri,String select) {           //TFile 为一个总的文件管理类,包含文件的信息
        Cursor mCursor = cxt.managedQuery(
                uri,
                new String[] {MediaStore.Audio.Media.DATA}, select,
                null, " date_modified desc");
        cxt.startManagingCursor(mCursor);
        int count = mCursor.getCount();
        if(count>0){
            List<TFile> data = new ArrayList<TFile>();
            if (mCursor.moveToFirst()) {
                do {
                    TFile.Builder builder = new TFile.Builder(mCursor.getString(0));
                    TFile bxfile = builder.build();
                    if(null != bxfile&&bxfile.getFileSize()>819200)
                        data.add(bxfile);
                } while (mCursor.moveToNext());
            }
            return data;
        }else{
            return null;
        }
    }

很大程度上学习了github上TracyZhangLei的FileExplorer,不仅仅是MediaStore,而是很多代码上方式,设计模式,对整个工程上的框架的大体建立。

  • 这里写图片描述
    照片的显示:通过ImageLoader对照片的加载,通过gridview的显示。根据获取的屏幕大小,调节Item的大小。这一块自己写的很失败…..加载过程中总是各种问题不断,最后还是参考了别人的代码才完成。在照片的更新上的显示还存在问题,每次都是对于listview的整体更新,体验比较差,以后有时间修正。

  • 这里写图片描述
    文件阅览的基本功能: 对当前文件夹遍历,读取文件夹下的文件信息,通过ListView的显示。当时遇到的主要问题是,阅览界面作为一个Fragment,对于Activity的back键的监听重载上,网上有很多种办法,但是尝试之后都遇到了问题,最后在Activity中回调函数的方式解决。

    2.电脑互传:
    这里写图片描述
    搜索之后,发现有2种方式实现,一种是通过ftp协议实现,Android手机作为数据传输过程中的ftp服务器;
    一种是通过http协议实现。Android手机作为数据传输过程中的http服务器。
    在这篇Android基于WIFI实现电脑和手机间数据传输的技术方案研究中,对很多例子进行了说明。
    最后选择通过ftp协议的方式,采用Apache FtpServerFTP服务器引擎解决,这种方法的问题是需要的第三方jar包比较多,比较麻烦。参考了android 基于apache ftp server
    实现之后在同一WiFi网络下,便可以通过相应的ftp地址对手机上的文件访问。
    热点模式为通过手机上的APWiFi,电脑与之相连接,同样可以达到访问的效果。

 public boolean setWifiApEnabled(boolean enabled) {   //热点的开启
        WifiManager wifiManager = null;
        wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        if (enabled) { // disable WiFi in any case
            //wifi和热点不能同时打开,所以打开热点的时候需要关闭wifi
            wifiManager.setWifiEnabled(false);
        }
        try {
            //热点的配置类
            WifiConfiguration apConfig = new WifiConfiguration();
            //配置热点的名称(可以在名字后面加点随机数什么的)
            apConfig.SSID = "快传";

            final Myapplication Date = (Myapplication) getApplication();
            if(Date.getName().equals("")){
                apConfig.SSID = Date.getName();
            }
            //配置热点的密码
            //通过反射调用设置热点
            Method method = wifiManager.getClass().getMethod(
                    "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);

            ap_name.setText("用户名");
            ap_name.setVisibility(View.VISIBLE);
            wifi_title.setText(" 连接电脑至本机热点:");

            //返回热点打开状态
            return (Boolean) method.invoke(wifiManager, apConfig, enabled);
        } catch (Exception e) {
            return false;
        }
    }

3.蓝牙分享:
很简单的分享方式,通过手机中自带的bluetooth,传入相应的apk的URi地址,startActivity,便开始的文件的传递。

   Intent intent_bluetooth = new Intent();
                    intent_bluetooth.setAction(Intent.ACTION_SEND);
                    intent_bluetooth.setType("*/*");
                    intent_bluetooth.setClassName("com.android.bluetooth", "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
                    File f = new File("///data/app/com.wifidirect-1/base.apk");
                    intent_bluetooth.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
                    Log.d("ConnectFragment", "onItemLongClick: "+Uri.fromFile(f));
                    startActivity(intent_bluetooth);

在确定文件地址的过程中,从data/app中寻找相应文件。但是不确定是否有误android版本的原因,显示格式不再是查到的data/app + [包名]-N.apk(覆盖安装N次),而是data/app/包名-N/base.apk,并且在我多次覆盖安装后,N也并没有发生变化,直接从该路径读取文件并没有发生问题。

4.手机连接:

查询到的连接方式有ad hoc模式WiFiDirect模式

QQ上的面对面快传以及快牙 从使用上来说,感觉都是采用ad hoc模式,可能是因为ad hoc设备支持比较广,android2.3便可以使用,而WiFiDirect为android4.0以上开始支持。并且从连接方式上,感觉ad hoc比较方便。而WiFiDirect的一些优点:强大的发现功能,如更高的数据速率、企业管理能力、WMM? Quality of Service模式,以及点到点连接的电源管理协议,安全性;在实际使用上,并没有太大的体现。

但是由于找到的WiFiDirect的资料比较多,并且理论上WiFiDirect更为优秀(WiFiDirect在使用中不会对正在使用WiFi网络造成影响,ad hoc则必须断开。)最后还是采用了WiFiDirect作为了连接方式。

个人对其完全只能说是使用的程度,只能罗列自己在学习过程中查询到的资料:

在sdk\samples\android-22\legacy\WiFiDirectDemo 中,可以看到官方的WiFiDriect的demo,虽然比较简单,但是还是有比较大的帮助,在github上搜索,同样可以找到。

WiFi P2P 官方文档

《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]–第七章 深入理解Wi-Fi P2P

Android平台Wifi_Direct使用

5.文件传输:

文件传输方式,采用了与官方WiFiDirect demo中相同的socket方式。由于之前对通信相关的知识完全一点不了解,在这个过程中跌了无数坑,一路模仿着demo,查找着相关内容………..

socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种”打开—读/写—关闭”模式的实现,服务器和客户端各自维护一个”文件”,在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。

基础实现并不复杂,但是又很多可以扩展的,比如多线程,断点传输……..
断点传输查询了一些信息,需要用到数据库,对当前下载文件信息的的记录….然而处于考试月并且ACM的省赛,区域赛需要准备,只能归于未来完成计划。

Socket的文档:

简单理解Socket

很详细的例子Android 基于Socket的聊天室

最后采用的socket的单线程传输方式,因为根据传输带宽由取决于双方的硬件,多线程下载只会使单个文件下载速度下降(不确定)。

官方demo中传输的文件类型唯一,并且传输文件名为随机时间命名。后查询到采用包含文件信息的文件流解决问题。文件信息和文件合并后在写入socket输出流,从中获取信息,先确定文件类型,再写入相应文件。

基于TCP协议的文件传输,传输带文件名等信息的文件流

6.下载信息更新:
通过Handler机制实现。在主线程中,对各个发送状态进行监听,相应的更新UI。在Socket通信过程中,不断更新信息,发送信息。
参考了一些下载器demo的实现。

主要内部实现就是如上,但是只是对于知识点的大概记录,很多方面并没有能够完成依靠自己完成,仅仅知道学习,使用,模仿的程度,如果完全要求自己独立完成,感觉还是比较吃力。已经完成的这部分,就已经相应再进行学习,掌握。
接下来会是对于软件UI的实现记录,主要使用的UI方式,例子。

一些人问的代码分享
这个demo在github上的地址:https://github.com/lucky-code/Practice/tree/master/kuaichuan2.0

其次由于android6.0新的权限管理机制,这个demo需要补上一个权限申请,一个坑以后再填啦…..

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

从原理角度解析Android (Java) http 文件上传

文件上传是我们项目中经常使用的功能,一般我们的服务器可能都是web服务器,当我们使用非浏览器客户端上传文件时,比如手机(Android)等上传,可能就需要对传输的数据进行规范化的拼接,说白了,就是我们...

Android中Socket大文件断点上传

什么是Socket?           所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信连的句柄,应用程序通常通过“套接字”向网络发送请求或者应答网络请求,它就是网络通信过程...

Android连接热点的Socket文件传输

最近把测试丢过来的种种BUG解决后,终于有时间去研究研究Socket通信,再加上以前做的WiFi连接和热点开启,于是有了现在的这篇博文:创建热点发送文件,让另一台手机连接热点接收文件。 两台设备是如...
  • hyq912
  • hyq912
  • 2017-03-31 08:55
  • 2475

(高效开发)Android手机间使用socket进行文件互传实例

说明这是一个Android手机间文件传输的例子,两个手机同时装上此app,然后输入接收端的ip,选择文件,可以多选,点确定,就发送到另一个手机,一个简单快捷文件快传实例。可以直接运用到项目中。 ...

《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第七章 深入理解Wi-Fi P2P

首先感谢各位兄弟姐妹们的耐心等待。根据今天得到的消息,本书预计在下周各大网店提供预订。注意,此处连载的是未经出版社编辑的原始稿件,所以样子会有些非专业。注意,如下是本章目录,本文节选7.1~7.2.2...
  • Innost
  • Innost
  • 2014-03-19 21:13
  • 36381

Android仿茄子快传-实现面对面快传功能

茄子快传是一款文件传输应用,相信大家都很熟悉这款应用,应该很多人用过用来文件的传输。它有两个核心的功能:端到端的文件传输 Web端的文件传输这两个核心的功能我们具体来分析一下! 端到端的文件传输所谓...

Android WiFiDirect 一个jar包搞定一切

概要: 本文主要介绍基于Android原生WiFidirect封装的jar包。其中实现的要点有: 1,IP列表管理; 2,一行代码配置WiFidirect; 3,实现了文本,文件,buffer...

Android开发 Handler引起的内存泄露

如果你在Activity中定义了一个内部Handler类,如下代码: public class MainActivity extends Activity { private Ha...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)