需求产生
使用Mac一年多,一直有一个小小的需求,怎样快捷的分享一个文件给Android手机呢?一开始我用的是HandShaker这款软件。
HandShaker
这个软件算是Mac上一款十分优秀的Android管理软件了。只要安装Mac端和手机端,同时打开软件,并保证在同一个局域网中,就能很方便的连接。连接成功后可以管理手机照片,音乐,视频,文件,同步剪切板,功能齐全,很棒!但是,我的需求是“快捷分享一个文件到Android机”,它显然不太符合“快捷”这个需求点,两个设备要经过安装>启动>连接这个基本流程才能将文件分享到手机。如果你是给别人分享,还得让别人安装APP,而且这APP也不算大众应用,很有可能在它的应用商店还搜不到,折腾来折腾去,想想就麻烦,弃之!ps:并不是它不好,是我眼光高。
直到后来,我又遇见了另外一个应用,极速分享。
打开软件,拖入要分享的文件,点击分享,就会生成一个局域网链接和链接的二维码,手机用户的话直接扫描二维码打开一个网页,点击文件下载按钮就能把文件下载到手机了。
这个不需要Android机安装任何APP,只是简单的扫码下载就行。不错,终于算是实现了我的需求了。然而在我实际的使用中,慢慢的发现,它还是不够完美。它不能在访达中选中文件的时候直接从右键菜单中一键分享,只能先去打开应用,再回来拖文件,这便产生了体验的割裂感。而我要的是一种无感的分享流程,所以,很遗憾,亦弃之!
思来想去,既然第三方软件帮不了我(或者是我还没发现能实现我需求的软件),干脆我就自己搞吧!当然,不是说我自己写个Mac软件,因为我不会。我要利用Mac本身自带的东西,来实现我的需求,这个过程,要尽量的不依赖外来软件,只靠Mac本身。哦对了,上面提到的两款软件感兴趣的话直接可以在App Store中下载,都是免费的,感谢开发者。
有了自己动手的念头,我大概花了三秒钟,考虑出了一个或许可行的方案。那就是模仿极速分享这款软件,这款软件的原理其实很简单,点击分享其实就是启动了一个服务器,然后将要分享的文件放到服务器资源目录中,再把文件对应的链接甩给用户就行了。如果用我作为程序员的角度来实现的话那很好说,什么Nginx,Tomcat的,随便搞一个配置一下就行了,但是这样的话对不了解这些的朋友而言显然有些不讲武德了,毕竟我们的目标是只靠Mac本身就实现我们的需求。
所需工具
因此我又考虑了三秒钟,把计划完善了一下。首先我们介绍一下所要用到的工具。首先是Mac自带的“自动操作”应用,就是下面这货。
如果你不知道它是做什么的,那我简单介绍一下它,它就类似于iPhone上的“快捷指令”应用,如果你不知道快捷指令是做什么的,那我建议你百度一下,假如你已经被我的文章吸引住实在不想抽身去百度,那我就用我的理解给你解释一下,这个软件里面预置了很多自动化的操作,比如下面圈中的这些。
我们就拿选中的“拷贝访达项目”做一下说明,我们将其拖动到右边作为整个流程的一个步骤,从图中可以看到,当这个流程接收到一个文件的时候,经过第一个步骤“拷贝访达项目”时,它就会把这个文件拷贝到桌面上。然后我们还可以添加更多的步骤,做更多的操作,这个我就不一一举例了,后面我们的实践也会讲到这些具体的操作。看着这里,你可能会疑惑,那这个流程是怎么接收到一个文件的呢?是怎么执行的的?其实在我们打开自动操作的时候,选择新建文稿,这时我们发现会有以下几个类型让你选择。
我挑最常用的几个类型讲一下,选择“应用程序”,我们可以将之后创建流程生成一个Mac应用,如果你的流程是操作一个文件,那么只需将文件拖动到生成的应用上,它就会自动执行流程了。选择快速操作,它最终生成的是一个服务,这个服务就是我们今天的重点。
它是个什么玩意儿呢?你可以看一下当前打开应用的菜单栏,直接点击应用名>服务,就能看到它们。比如我现在选中的内容是一段文本,它就会出现文本对应的服务(百度一下),同时它也是一个URL,因此还有互联网对应的服务(打开URL)。
同样的,在访达里面如果你选中了一个文件,我们可以更方便的直接在文件的右键菜单里面看到文件对应的服务,比如下面这样:
所以说,所谓服务,就是针对你当前选中内容的一个功能菜单。怎样管理它呢?打开系统偏好设置,选择键盘>快捷键>服务,找到对应服务取消勾选就行了,鼠标右键点击服务,还可以直接在访达中显示,或者直接在自动操作中编辑这个服务。在这里,统一管理第三方应用自带的服务和自己开发的服务。
扯得有点多了。我们继续介绍下一个所需的东西:一个服务器软件。这东西哪里找呢,前面说了可以用第三方,但是我偏不用。百度一番之后,发现原来Mac自带了一个Apache服务器。
实现方案
讲到这里,我可以整体的说一下我的方案了。其实就是新建一个服务,这个服务的流程就是接收一个文件,将文件复制到服务器的资源目录,然后启动服务器,生成文件链接,最好是再生成一个二维码让用户扫,之后关闭服务器,再删除刚刚复制到资源目录中的文件,整个流程结束。之后我们只要在访达中任意选中一个文件,右键选择这个服务,就能执行以上流程,将这个文件分享出去,美滋滋。
所遇问题
然而无情的事实是这个方案虽然嘴上说起来很简单,但是实行起来却遇到了诸多的困难,甚至最终的解决方案也并没有做到十分的完美。
首先便是这个所谓的系统自带的Apache服务器,我没用过,不是很了解。我按照上面博文中的方法启动了之后,往它默认的资源目录(
/Library/WebServer/Documents)中放文件的时候发现需要输密码授权,因为这个服务器本身连同这个资源目录,都是属于系统的,只有root权限才能操作,我们普通用户操作的时候必须输密码。如果我在服务的流程中执行shell脚本,因为它是在后台运行的,根本没法输密码?就比如下面这句启动服务器的命令:
sudo apachectl start
正常情况下我们在终端里面输入之后点击回车,此时就需要手动输密码了,这对于我们的服务来说肯定是不现实的,就算我有能力让流程执行过程中弹出输入框让用户输密码,但这样会使整个流程的体验直线下降。所以几经百度,终于找到了解决办法。将上面的命令修改为下面这样就可以省去手动输密码的步骤:
echo '这里写上密码' | sudo -S apachectl start
具体的实现原理我就不解释了,感兴趣可以自行百度。
紧接着又出现了问题,上面提到我启动了Apache服务器并将一个名为"test.png"的图片复制到了它的资源目录中。之后通过http://127.0.0.1/test.png成功访问到了这张图片。然而怎么将这个文件链接发给Android手机呢?用微信QQ?屁,如果用微信QQ了,那我直接把文件发给它不更好?搞这些有的没的,脑袋秀逗了啊?因此,最好的方案就是将这个链接转为二维码并显示在屏幕上。重复一下,这是两个步骤,一是要将链接转为二维码,二是要将二维码显示在屏幕上。那要怎么实现呢?我找遍自动操作里面的所有内置操作,遗憾的是并不能实现我的这两个看似简单的需求。除非借助第三方的力量,比如用Java将链接转为二维码,再用Java启动一个窗口展示这个二维码。然而对于普通用户来说,难道还要让人家装个jdk?配下环境变量?不讲武德,Shit!
最终,我找到了一个还算可以的解决方案。那就是借助第三方http接口。
我只要把我的文件链接以参数形式拼接到它的请求URL上,形成一个新的URL,之后用浏览器打开这个URL,就能直接显示我的文件链接对应的二维码了,妙!
我试了下上述方法,很成功,用Android机扫描之后直接便打开了我分享的图片,那一瞬间我激动万分。然而很快我就发现不对劲。我是要下载文件到本地啊,它这直接把文件给我打开了,那怎么能行?这也让我产生了深深地疑惑:为什么极速分享生成的链接打开之后就是直接去下载文件,而我的是却是打开文件?都是普通的http链接啊,问题出在哪里?思考了一会儿,身为程序员的直觉告诉我,问题应该出现在这个链接返回的请求头上,于是我用postman调了一下极速分享的文件下载链接,在返回信息头部找到了这个:
我百度了这个Header代表的意思,说的都是一些晦涩难懂之词,翻译成人话就是,这个Header表示这个请求返回的是一个附件,是希望浏览器去下载,而不是打开,我的请求返回信息中没这个,所以浏览器直接就打开图片了。因此我需要让我的Apache服务器返回信息中包含这个Header。就这简单地需求,着实花费了我好长时间去百度去研究,好在最后算是解决了。方法就是修改服务器的配置文件:文件绝对路径是:/etc/apache2/httpd.conf,虽然我们可以在访达中找到这个这个文件并打开,但是修改后是不能保存的,因为没有root权限,所以我选择使用终端对这个文件进行修改,具体如下:
# 首先我们先临时获取root用户权限,回车后输入当前用户密码
sudo su
# 切换到配置文件目录
cd /etc/apache2
# 先备份配置文件当当前目录
cp httpd.conf httpd.conf.bak
# 之后开始修改配置文件
vim httpd.conf
如果是对命令行不了解的小伙伴,看图操作,下面便是执行vim httpd.conf命令之后的界面,其实它展示的就是该文件的内容:
我们按着方向下键,直到找到下面的内容:
此时点击键盘上的“i”键,进入输入模式,把圈中的部分修改成下面的内容:
Header set Content-Disposition "attachment"
它的作用是保证当请求的内容是文件时,为返回信息添加一个名为Content-Disposition的Header,这样浏览器看到这个Header时,就会恍然大悟:“oh~~~返回的是个文件啊,那我就把它下载下来吧”。之后点击键盘上的“esc”键退出编辑模式,然后输入“:wq”,回车,这样配置文件就修改好了。这里插一嘴,“:wq”中的w指的是英文write(写),q是英文quit(退出),所以“:wq”就是退出vim并保存文件。如果只保存不退出,那就是“:w”,只退出不保存,自己琢磨。
如果你已经尝试这么修改配置文件了,不如再改一些其它的内容。上面提到过,Apache服务器的默认资源目录路径是:
/Library/WebServer/Documents,这个路径是系统路径,如果老是往里面塞东西删东西,万一对系统造成啥危害了这就不好了,所以我们可以修改一下这个默认路径,建议修改到当前登录用户的用户文件夹下。打开访达,在菜单栏中点击前往>前往文件夹,输入“/User”,找到你的用户文件夹(文件夹名是你电脑的用户名),点进去,新建一个文件夹,比如:Share,这里最好用英文命名。建好之后鼠标右键点击该文件夹,弹出右键菜单之后按住键盘上的“option”键,会发现原来的“拷贝”按钮变成了“将Share拷贝为路径名称”,点击它,这个文件夹的绝对路径就复制下来了,接下来我们继续编辑配置文件。找到下面的内容:
看到这里熟悉的路径“
/Library/WebServer/Documents”了吗?把它俩都删掉改为刚刚拷贝的路径,然后退出保存。这样,Apache服务器默认的资源目录就更改为你刚刚新建的文件夹了,到时候我们只需要往这个文件夹中倒腾文件就行了。
至此,整个过程中唯一需要考验动手能力的步骤已经结束了,下面的则都可以直接使用我现成的劳动成果了。我呢,则是将这个成果的内容介绍一遍。
流程讲解
接下来,让我介绍一下这个至关重要的服务中的流程是怎样具体实现的。首先打开自动操作,选择新建文稿,类型选:快速操作,开始编辑流程。
注:shell脚本中,$*和$@表示的是从上一步接收的全部参数,$#表示的是参数个数
①这里我们选择文件或文件夹,因为我们分享的无论是图片,音乐统统属这个范畴。
②这里我们选访达就好,一般都是在访达中选中文件进行分享的。
③这个步骤就是运行shell脚本,将要分享的文件放入Apache服务器资源目录并启动Apache服务器,然而具体步骤并没有这么简单,因为如果只选择了一个文件那就很简单,直接将文件复制过去就好,但如果用户选择的是文件夹或者是多个文件,又或者是有文件又有文件夹,那怎么搞?我给出的方案是把它们打包,然后让用户下载这个压缩包,于是乎,脚本如下:
# 判断是否只选中了一个文件(夹)并且它是一个文件而非文件夹
if [ $# = 1 ] && [ -f $* ];
then
# 如果选中的仅仅是一个文件,则将该文件复制到Apache服务器资源目录中
cp $* ~/Share
# 返回选中文件的文件名
echo ${*##*/}
else
# 走到这里说明选中的是多个文件(夹)或者是一个文件夹,需将它们打包到Apache服务器资源目录中
# 遍历选中的文件(夹)
for i in $*
do
# 获取文件(夹)名称
fileName=${i##*/}
# 获取文件(夹)所在目录
folderName=${i%/*}
# 切换到其所在目录
cd $folderName
# 将该文件(夹)打包到指定的zip文件中(整个循环过程其实是将各个文件(夹)追加到了这个zip包中)
zip -qr ~/Share/files.zip $fileName
done
# 返回打包好的zip文件的文件名
echo files.zip
fi
# 启动Apache服务器
echo '这里写上密码' | sudo -S apachectl start
④将文件名赋值给变量“fileName”以备后用。
⑤经过上面的步骤,文件或者是打包的压缩包已经拷贝到了服务器资源目录了,并且服务器也已经启动,这里我们就需要拼接出这个文件或是压缩包的访问链接。拼接方法是“http://”+"Mac在局域网中的IP地址"+“/”+"文件名",效果类似这样:
http://192.168.50.9/test.png。不废话,上脚本:
#获取本机在局域网中的IP,拼接文件名,生成文件URL
fileURL=http://$(ifconfig | grep "broadcast" |awk '{print $2}')/$@
echo $fileURL
⑥这步接收上一步返回的文件链接,直接拷贝到剪切板中,方便分享。
⑦将文件链接进行URLEncode处理并作为参数拼接到二维码接口上面,之后返回拼接好的二维码地址
function run(input, parameters) {
input = "https://wenhairu.com/static/api/qr/?size=350&text=" + encodeURI(input);
return input;
}
⑧显示一条通知,提示用户分享成功。还要提示用户在下一步的网页弹出式菜单中点击“好”才会停止分享,点“取消”的话流程就此结束,需要自己使用命令行关闭Apache服务器并删除资源目录中的文件。
⑨用网站弹出式菜单加载二维码地址,展示二维码。因为我用的二维码接口返回的二维码是固定尺寸的,所以我设置了这个弹出式菜单的大小以获得更好的展示效果,如果后期更换了二维码接口无法保证返回的二维码的尺寸,这里弹出式菜单的大小尽量设置的大一点以保证二维码能展示全。
⑩获取文件名。
(11)这是最终步骤了,停止Apache服务器,删除复制到Apache资源目录中的文件。
# 关闭Apache服务器
echo '这里写上密码' | sudo -S apachectl stop
# 删除Apache服务器资源目录中的文件
rm -rf ~/Share/$@
效果展示
最后展示一下效果
接收文件
安装使用
①首先在用户目录下面新建一个名为Share的目录
mkdir ~/Share
②开始修改Apache服务器配置文件
# 我们先临时获取root用户权限,回车后输入当前用户密码
sudo su
# 切换到配置文件目录
cd /etc/apache2
# 备份配置文件到当前目录
cp httpd.conf httpd.conf.bak
# 开始修改配置文件
vim httpd.conf
# 之后照着上文中的操作修改配置文件
③去我的码云(链接放在文末)把服务文件:文件分享.workflow下载下来,做一点小修改。修改的时候右键这个文件,选择“自动操作.app”打开,切记是“自动操作.app”,不是“自动操作安装器.app”,后者是要把服务安装到系统中时用的。
打开之后按照下图所示,将这两处的密码改成自己电脑的密码,然后command+s保存即可。
④保存之后再右击服务文件,选择“自动操作安装器.app”,此时服务就会被安装到系统中。理论上到此也就大功告成了。如果有问题,欢迎在评论区谈论。
本文暂时没有评论,来添加一个吧(●'◡'●)