晚上好鸭!!!
故事的开始
公司有个文件拷贝的需求,具体的效果和es浏览器的网络从PC访问应该是一样的
(一)点击网络
(二)点击开启服务
起初和小伙伴是有点懵逼的,但是百度了解一下,觉得还是有可行性的。就去查资料和学习,想办法去实现这个功能。
Just to IT
准备工作
要想快速实现需求,就要用到前人的肩膀了。
1.先导入架包
项目app/libs中导入这六个架包,一个也不能少,我傻乎乎的测试过了。
2.在app/build.gradle中的android中添加代码块
android {
//...
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
}
}
创建服务(FtpService,记得清单文件注册)
FtpService代码如下
//记得导入自己的包
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import java.util.ArrayList;
import java.util.List;
/**
* Created by syt on 2019/11/26.
*/
public class FtpService extends Service {
private FtpServer server;
private String user = "admin";//账号,不需要账号密码就请设置为anonymous
private String password = "123456";//密码
private static String rootPath;//访问路径
private int port = 1234;//端口号
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
try {
init();
Toast.makeText(this, "启动ftp服务成功", Toast.LENGTH_SHORT).show();
} catch (FtpException e) {
e.printStackTrace();
Toast.makeText(this, "启动ftp服务失败", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDestroy() {
super.onDestroy();
release();
Toast.makeText(this, "关闭ftp服务", Toast.LENGTH_SHORT).show();
}
/**
* 初始化
*
* @throws FtpException
*/
public void init() throws FtpException {
release();
startFtp();
}
public void startFtp() throws FtpException {
FtpServerFactory serverFactory = new FtpServerFactory();
//设置访问用户名和密码还有共享路径
BaseUser baseUser = new BaseUser();
baseUser.setName(user);
baseUser.setPassword(password);
baseUser.setHomeDirectory(rootPath);
List<Authority> authorities = new ArrayList<Authority>();
authorities.add(new WritePermission());
baseUser.setAuthorities(authorities);
serverFactory.getUserManager().save(baseUser);
ListenerFactory factory = new ListenerFactory();
factory.setPort(port); //设置端口号 非ROOT不可使用1024以下的端口
serverFactory.addListener("default", factory.createListener());
server = serverFactory.createServer();
server.start();
}
/**
* 释放资源
*/
public void release() {
stopFtp();
}
private void stopFtp() {
if (server != null) {
server.stop();
server = null;
}
}
}
活动中的调用
MenuActivity
//弹出框的调用方式
initService();
AlertDialog.Builder alertDialog=new AlertDialog.Builder(MenuActivity.this);
alertDialog.setTitle("请使用完再点击关闭服务器")
.setMessage(str)
.setCancelable(false)
.setNegativeButton("关闭服务器", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
stopService(new Intent(MenuActivity.this, FtpService.class));
}
})
.create();
alertDialog.show();
//下面是方法
private void initService() {
String ip = getIp();
if(TextUtils.isEmpty(ip)){
ToastUtil.showToast(MenuActivity.this,"获取不到IP,请连接网络");
}else{
str = "请在PC端浏览器上输入网址访问FTP服务\n" +
"ftp://"+ip+":1234";
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
}
}
startService(new Intent(this, FtpService.class));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_CODE) {
int snum=0;
for (int i = 0; i < permissions.length; i++) {
Log.i("MenuActivity", "申请的权限为:" + permissions[i] + ",申请结果:" + grantResults[i]);
if (grantResults[i]==0)
snum+=1;
}
if (snum!=2){//说明权限申请没申请成功,再次申请
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
}
}
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
stopService(new Intent(this, FtpService.class));
}
public String getIp(){
//获取wifi服务
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
//判断wifi是否开启
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = intToIp(ipAddress);
return ip;
}
private String intToIp(int i) {
return (i & 0xFF ) + "." +
((i >> 8 ) & 0xFF) + "." +
((i >> 16 ) & 0xFF) + "." +
( i >> 24 & 0xFF) ;
}
相信只要有点基础的人,都能实现这个效果的
效果
1.app显示
2.PC端浏览器访问
今天就分享到这啦
需要注意的点
1.不需要访问就设置账号为anonymous
给你们看看源码怎么写的嘿嘿
2.记得添加专属混淆,不然无法启动服务
如果开启混淆,没添加架包的混淆保留,server是找不到对应的方法的去初始化的。
我菜找不到,害我今天都是关闭混淆去学习的。。。