在文件管理器里面添加FTP功能,功能的主要实现是在jar包里面,文件管理只是做了引用而已.
filemanageroperateactivity.java:
import android.support.v4.view.ViewPager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.storage.StorageManager;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.net.InetAddress;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
public class FileManagerOperationActivity extends AbsBaseActivity implements
AdapterView.OnItemLongClickListener, NfcAdapter.CreateBeamUrisCallback {
static {
System.setProperty("java.net.preferIPv6Addresses", "false");
}
private View mViewIpAdress;
private View mViewIpAdress;
private ImageView mImgWifi;
private Button mBtnStartServer;
private TextView mTxtWifiName;
private TextView mTxtIpAdress;
private TextView mTxtFtpMsg;
private StorageManager mStorageManager = null;
private FtpServer mFtpServer;
private String mStrIpAdress;
private boolean mIsMounted = true;
private boolean mIsStartServer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!PermissionUtils.hasStorageReadPermission(getApplicationContext())) {
PermissionUtils.requestPermission(FileManagerOperationActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE_ON_CREATE);
}
// get sort by
mSortType = getPrefsSortBy();
mOrientationConfig = this.getResources().getConfiguration().orientation;
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
LogUtils.w(TAG, "mNfcAdapter == null");
} else if (OptionsUtils.isMtkBeamSurpported()) {
//mNfcAdapter.setMtkBeamPushUrisCallback(this, this);
}
IntentFilter localeFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(mLocaleChangedReceiver, localeFilter);
PDebug.End("FileManagerOperationActivity -- onCreate");
if (mStorageManager == null) {
mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
registerWifiChangeReceiver();
}
}
@Override
protected void onDestroy() {
unregisterReceiver(mLocaleChangedReceiver);
stopServerSettings();
stopServer();
((FileManagerApplication)FileManagerApplication.getInstance()).clearNotification(this);
unregisterWifiChangeReceiver();
super.onDestroy();
}
@Override
public void onEjected(String unMountPoint) {
super.onEjected(unMountPoint);
mIsMounted = false;
stopServer();
updateUI();
}
@Override
protected void serviceConnected() {
LogUtils.d(TAG, "serviceConnected...");
super.serviceConnected();
if (mSavedInstanceState != null) {
int mode = mSavedInstanceState.getInt(CURRENT_VIEW_MODE_KEY,
FileInfoAdapter.MODE_NORMAL);
int position = mSavedInstanceState.getInt(CURRENT_POSTION_KEY, 0);
int top = mSavedInstanceState.getInt(CURRENT_TOP_KEY, -1);
LogUtils.d(TAG, "serviceConnected mode=" + mode);
restoreViewMode(mode, position, top);
}
mListView.setOnItemLongClickListener(this);
showOverflewButton();
loadColors();
loadBrowseData();
bindWidgets();
mMap = new HashMap<Integer,ArrayList<BrowseInfo>>();
mBrowseList = new ArrayList<BrowseInfo>();
mTabBrowse.setOnClickListener(this);
mTabFile.setOnClickListener(this);
mTabFtp.setOnClickListener(this);
mViewPagerAdapter = new FileManagerPagerAdapter(mViews);
mPagerAdapter = new ViewPagerOnChangeListener();
mViewPager.setAdapter(mViewPagerAdapter);
mViewPager.setOnPageChangeListener(mPagerAdapter);
if(ifActionFromDialer){
mViewPager.setCurrentItem(FileUtils.TAB_ON_FILE);
}
}
@Override
public void onClick(View view) {
if (mService.isBusy(this.getClass().getName())) {
LogUtils.d(TAG, "onClick, service is busy,return.");
return;
}
int id = view.getId();
LogUtils.d(TAG, "onClick,id: " + id);
boolean isMounted = mMountPointManager.isRootPathMount(mCurrentPath);
if (mAdapter.isMode(FileInfoAdapter.MODE_EDIT) && isMounted) {
mActionModeCallBack.updateActionMode();
LogUtils.d(TAG, "onClick,retuen.");
return;
}
switch (view.getId()) {
case R.id.browse:
mViewPager.setCurrentItem(FileUtils.TAB_ON_BROWSE);
break;
case R.id.file:
mViewPager.setCurrentItem(FileUtils.TAB_ON_FILE);
break;
case R.id.ftp:
mViewPager.setCurrentItem(FileUtils.TAB_ON_FTP);
break;
case R.id.rgk_file_ftp_btn_start_server:
mIsStartServer = !mIsStartServer;
updateUI();
break;
case R.id.rgk_file_ftp_img_wifi:
jumpToWifiSettings();
break;
}
super.onClick(view);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
LogUtils.d(TAG, "onPrepareOptionsMenu...");
super.onPrepareOptionsMenu(menu);
//here must return, otherwise menu item will null(because of no inflate menu
//onCreateOptionsMenu() and this leads null pointer exception
if (null == mService) {
LogUtils.i(TAG, "onPrepareOptionsMenu, invalid service,return true.");
return true;
}
if (FileUtils.mCurMode == FileUtils.SELECT_FILE_MODE
|| mViewPager.getCurrentItem() == FileUtils.TAB_ON_FTP) {
menu.findItem(R.id.create_folder).setVisible(false);
menu.findItem(R.id.change_mode).setVisible(false);
menu.findItem(R.id.hide).setVisible(false);
menu.findItem(R.id.sort).setVisible(false);
menu.findItem(R.id.paste).setVisible(false);
menu.findItem(R.id.search).setVisible(false);
return true;
}
protected void onNewIntent(Intent intent) {
String action = intent.getAction();
String hotknotPath = null;
LogUtils.d(TAG, "onNewIntent action: " + action);
if (action != null && action.equals(FileUtils.FTP_NOTIFICATION_ACTION)) {
if (mViewPager != null) {
mViewPager.setCurrentItem(FileUtils.TAB_ON_FTP);
}
}
private void bindWidgets() {
mGridView = (WtkBrowseGridView) mBrowseView.findViewById(R.id.gridview);
mGridViewAdapter = new GridViewAdapter();
mGridView.setAdapter(mGridViewAdapter);
mGridView.setOnItemClickListener(new BrowseItemClickListener());
mWtkListView = (WtkListView) mBrowseView.findViewById(R.id.browse_progressbar_listview);
mProgressBarAdapter = new ProgressBarAdapter();
mWtkListView.setAdapter(mProgressBarAdapter);
mViewIpAdress = (View) mFtpView.findViewById(R.id.rgk_file_ftp_ip_adress_view);
mImgWifi = (ImageView) mFtpView.findViewById(R.id.rgk_file_ftp_img_wifi);
mBtnStartServer = (Button) mFtpView.findViewById(R.id.rgk_file_ftp_btn_start_server);
mTxtWifiName = (TextView) mFtpView.findViewById(R.id.rgk_file_ftp_wifi_name);
mTxtIpAdress = (TextView) mFtpView.findViewById(R.id.rgk_file_ftp_ip_adress);
mTxtFtpMsg = (TextView) mFtpView.findViewById(R.id.rgk_file_ftp_msg);
mImgWifi.setOnClickListener(this);
mBtnStartServer.setOnClickListener(this);
@Override
public void onPageSelected(final int arg0) {
if (mViewPager.getCurrentItem() == FileUtils.TAB_ON_FTP) {
updateUI();
resetTabTxtColor();
mTabFtp.setTextColor(mTabTxtColorFocus);
}
private void registerWifiChangeReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction("android.net.wifi.STATE_CHANGE");
registerReceiver(mWifiChangeReceiver, filter);
}
private void unregisterWifiChangeReceiver() {
if (mWifiChangeReceiver != null) {
unregisterReceiver(mWifiChangeReceiver);
}
}
private void jumpToWifiSettings() {
Intent intent = new Intent();
intent.setAction(WIFI_SETTINGS_ACTION);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
private void updateUI() {
if (mTxtWifiName == null || mImgWifi == null || mBtnStartServer== null) {
return;
}
WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifiMgr.getConnectionInfo();
String wifiId = info != null ? info.getSSID() : null;
Log.d(TAG,"wifiId: "+wifiId);
boolean isWifiReady = FileUtils.isConnectedUsingWifi();
Log.d(TAG,"isWifiReady: "+isWifiReady);
if (!TextUtils.isEmpty(wifiId)) {
mTxtWifiName.setText(wifiId);
}
if (!isWifiReady) {
mIsStartServer = false;
}
if (mIsStartServer) {
if (mFtpServer == null || mFtpServer.isStopped()) {
initFtpServer();
InetAddress address = FileUtils.getLocalInetAddress();
if (address != null) {
mStrIpAdress = FileUtils.FTP + address.getHostAddress()
+ FileUtils.FTP_COLON + FileUtils.PORT;
startFtpServer();
startServerSettings();
} else {
stopServer();
mStrIpAdress = "";
stopServerSettings();
}
}
} else {
if (mFtpServer != null && !mFtpServer.isStopped()) {
stopServer();
stopServerSettings();
}
}
mBtnStartServer.setEnabled(isWifiReady);
if (isWifiReady) {
mImgWifi.setImageResource(R.drawable.wifi_state4_light);
mBtnStartServer.setText((mFtpServer != null && !mFtpServer.isStopped()) ? R.string.rgk_file_ftp_stop_server : R.string.rgk_file_ftp_start_server);
} else {
mImgWifi.setImageResource(R.drawable.wifi_state0_light);
mTxtWifiName.setText(R.string.rgk_file_no_wlan);
stopServer();
stopServerSettings();
}
boolean isUsbMassStorage = mStorageManager.isUsbMassStorageEnabled();
Log.d(TAG,"isUsbMassStorage: "+isUsbMassStorage);
Log.d(TAG,"mIsMounted: "+mIsMounted);
if (!mIsMounted) {
mBtnStartServer.setEnabled(false);
} else if (mIsMounted && isWifiReady){
mBtnStartServer.setEnabled(!isUsbMassStorage);
}
if (isUsbMassStorage) {
stopServer();
mStrIpAdress = "";
stopServerSettings();
}
}
private void startServerSettings() {
mBtnStartServer.setText(R.string.rgk_file_ftp_stop_server);
mTxtFtpMsg.setVisibility(View.GONE);
mViewIpAdress.setVisibility(View.VISIBLE);
mTxtIpAdress.setText(mStrIpAdress);
}
private void stopServerSettings() {
mBtnStartServer.setText(R.string.rgk_file_ftp_start_server);
mViewIpAdress.setVisibility(View.GONE);
mTxtFtpMsg.setVisibility(View.VISIBLE);
}
private void startFtpServer() {
try {
if (mFtpServer != null && mFtpServer.isStopped()) {
((FileManagerApplication)FileManagerApplication.getInstance()).setupNotification(this);
mFtpServer.start();
}
} catch (FtpException e) {
e.printStackTrace();
}
}
private void stopServer() {
mIsStartServer = false;
if (mFtpServer != null && !mFtpServer.isStopped()) {
((FileManagerApplication)FileManagerApplication.getInstance()).clearNotification(this);
mFtpServer.stop();
}
}
private BroadcastReceiver mWifiChangeReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
updateUI();
}
};
private void initFtpServer() {
Log.d(TAG,"initFtpServer.");
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
File file = writeToFile();
if (file == null) {
return;
}
userManagerFactory.setFile(file);
serverFactory.setUserManager(userManagerFactory.createUserManager());
factory.setPort(FileUtils.PORT);
serverFactory.addListener("default", factory.createListener());
FtpServer server = serverFactory.createServer();
Log.d(TAG,"Ftp createServer.");
this.mFtpServer = server;
}
private File writeToFile() {
File file = null;
InputStream in = null;
OutputStream out = null;
try {
in = this.getResources().openRawResource(R.raw.users);
file = new File(FileUtils.FTP_USER_PROPERTIES_PATH);
if (file.exists()) {
return file;
}
file.createNewFile();
out = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = in.read(buffer)) > 0) {
out.write(buffer,0, length);
}
out.flush();
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("psm","file : "+file);
return file;
}
FileUtil.java里面的:
import com.mediatek.filemanager.FileManagerApplication;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
public static final int TAB_ON_FTP = 2;
public static String FTP = "ftp://";
public static String FTP_COLON = ":";
public static final String FTP_NOTIFICATION_ACTION = "com.android.FTP_ACTION";
public static final String FTP_USER_PROPERTIES_PATH = "/storage/sdcard0/.users.properties";
public static int PORT = 2121;
public static InetAddress getLocalInetAddress() {
if (!isConnectedToLocalNetwork()) {
Log.e(TAG, "getLocalInetAddress called and no connection");
return null;
}
// @TODO: next if block could probably be removed
if (isConnectedUsingWifi()) {
Context context = FileManagerApplication.getInstance();
WifiManager wm = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
int ipAddress = wm.getConnectionInfo().getIpAddress();
if (ipAddress == 0)
return null;
return intToInet(ipAddress);
}
// This next part should be able to get the local ip address, but in
// some case
// I'm receiving the routable address
try {
Enumeration<NetworkInterface> netinterfaces = NetworkInterface
.getNetworkInterfaces();
while (netinterfaces.hasMoreElements()) {
NetworkInterface netinterface = netinterfaces.nextElement();
Enumeration<InetAddress> adresses = netinterface
.getInetAddresses();
while (adresses.hasMoreElements()) {
InetAddress address = adresses.nextElement();
// this is the condition that sometimes gives problems
if (!address.isLoopbackAddress()
&& !address.isLinkLocalAddress())
return address;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static boolean isConnectedToLocalNetwork() {
Context context = FileManagerApplication.getInstance();
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
// @TODO: this is only defined starting in api level 13
final int TYPE_ETHERNET = 0x00000009;
return ni != null
&& ni.isConnected() == true
&& (ni.getType() & (ConnectivityManager.TYPE_WIFI | TYPE_ETHERNET)) != 0;
}
public static boolean isConnectedUsingWifi() {
Context context = FileManagerApplication.getInstance();
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return ni != null && ni.isConnected() == true
&& ni.getType() == ConnectivityManager.TYPE_WIFI;
}
public static InetAddress intToInet(int value) {
byte[] bytes = new byte[4];
for (int i = 0; i < 4; i++) {
bytes[i] = byteOfInt(value, i);
}
try {
return InetAddress.getByAddress(bytes);
} catch (UnknownHostException e) {
// This only happens if the byte array has a bad length
return null;
}
}
public static byte byteOfInt(int value, int which) {
int shift = which * 8;
return (byte) (value >> shift);
}
FileManagerApplication.java
package com.mediatek.filemanager;
import java.net.InetAddress;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import com.mediatek.filemanager.service.FileManagerService;
import com.mediatek.filemanager.utils.FileUtils;
import com.mediatek.filemanager.utils.LogUtils;
import com.mediatek.filemanager.utils.PDebug;
public class FileManagerApplication extends Application {
public static final String TAG = "FileManagerApplication";
private static FileManagerApplication mInstance;
private final int NOTIFICATIONID = 7890;
private static int mScreenWidth;
@Override
public void onCreate() {
PDebug.Start("FileManagerApplication - onCreate");
super.onCreate();
mInstance = this;
if (startService(new Intent(this.getApplicationContext(),
FileManagerService.class)) == null) {
LogUtils.e(TAG, "startService Fails");
}
PDebug.End("FileManagerApplication - onCreate");
}
public static Context getInstance() {
return mInstance;
}
public static int getScreenWidth() {
DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) mInstance.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
mScreenWidth = dm.widthPixels;
return mScreenWidth;
}
/**
* Get the version from the manifest.
*
* @return The version as a String.
*/
public static String getVersion() {
Context context = getInstance();
String packageName = context.getPackageName();
try {
PackageManager pm = context.getPackageManager();
return pm.getPackageInfo(packageName, 0).versionName;
} catch (NameNotFoundException e) {
Log.e(TAG, "Unable to find the name " + packageName
+ " in the package");
return null;
}
}
public void setupNotification(Context context) {
Log.d(TAG, "Setting up the notification");
// Get NotificationManager reference
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nm = (NotificationManager) context
.getSystemService(ns);
// get ip address
InetAddress address = FileUtils.getLocalInetAddress();
if (address == null) {
Log.w(TAG, "Unable to retreive the local ip address");
return;
}
String iptext = FileUtils.FTP + address.getHostAddress()
+ FileUtils.FTP_COLON + FileUtils.PORT;
// Instantiate a Notification
int icon = R.drawable.notification;
CharSequence tickerText = String.format(
context.getString(R.string.notif_server_starting), iptext);
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
// Define Notification's message and Intent
CharSequence contentTitle = context.getString(R.string.notif_title);
CharSequence contentText = iptext;
Intent notificationIntent = new Intent(context, FileManagerOperationActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
notificationIntent.setAction(FileUtils.FTP_NOTIFICATION_ACTION);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
notification.flags |= Notification.FLAG_ONGOING_EVENT;
// Pass Notification to NotificationManager
nm.notify(NOTIFICATIONID, notification);
Log.d(TAG, "Notication setup done");
}
public void clearNotification(Context context) {
Log.d(TAG, "Clearing the notifications");
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager nm = (NotificationManager) context
.getSystemService(ns);
nm.cancelAll();
Log.d(TAG, "Cleared notification");
}
}
CustomUnderLine.java
public class CustomUnderLine extends View{
private static final String TAG = "CustomUnderLine";
private static final int TAB_COUNTS = 3;
private Paint mPaint;
private int mColor;
private int mScreenWidth;
private int mLineWidth;
private int mCurIndex;
private float mOffset;
public CustomUnderLine(Context context) {
super(context);
}
public CustomUnderLine(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setStrokeWidth(5);
mColor = Color.argb(255, 0, 150, 136);
mPaint.setColor(mColor);
mScreenWidth = FileManagerApplication.getScreenWidth();
mLineWidth = mScreenWidth / TAB_COUNTS;
Log.d(TAG,"mScreenWidth: "+mScreenWidth);
Log.d(TAG,"mLineWidth: "+mLineWidth);
}
public void updateOffset(float offset,int index) {
Log.d(TAG,"mOffset: "+mOffset);
mOffset = (float)( index * mLineWidth + (offset * mScreenWidth) / TAB_COUNTS);
invalidate();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
Log.d(TAG,"draw mOffset: "+mOffset);
Log.d(TAG,"draw mLineWidth: "+mLineWidth);
canvas.drawLine(mOffset, 0, (mOffset + mLineWidth), 0, mPaint);
}
}
AbsbaseActivity.java extends activity {
private void loadViews() {
LayoutInflater inflater = LayoutInflater.from(this);
mBrowseView = inflater.inflate(R.layout.browse, null);
mFileView = inflater.inflate(R.layout.main, null);
mFtpView = inflater.inflate(R.layout.ftp, null);
if (mViews == null) {
mViews = new ArrayList<View>();
}
mViews.add(mBrowseView);
mViews.add(mFileView);
mViews.add(mFtpView);
}
private void bindWidgets() {
mViewPager = (NoScrollViewPager) findViewById(R.id.viewpager);
mTabBrowse = (TextView) findViewById(R.id.browse);
mTabFile = (TextView) findViewById(R.id.file);
mTabFtp = (TextView) findViewById(R.id.ftp);
mCustomUnderLine = (CustomUnderLine) findViewById(R.id.under_line);
}}
此外引入jar包:ftpserver-core-1.0.6.jar
log4j-1.2.14.jar
mina-core-2.0.4.jar
slf4j-log4j12-1.5.2.jar
slf4j-api-1.5.2.jar
Android.mk文件中加:LOCAL_STATIC_JAVA_LIBRARIES := ftpserver \
log4j \
mina \
slf4japi \
slf4jlog4j
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += ftpserver:libs/ftpserver-core-1.0.6.jar \
log4j:libs/log4j-1.2.14.jar \
mina:libs/mina-core-2.0.4.jar \
slf4japi:libs/slf4j-api-1.5.2.jar \
slf4jlog4j:libs/slf4j-log4j12-1.5.2.jar
include $(BUILD_MULTI_PREBUILT)