1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-05 19:42:17 +02:00

network scanner has been moved to a separate plugin

Conflicts:

	AndroidManifest.xml
	AndroidManifest.xml.pattern
	src/org/geometerplus/android/fbreader/network/ScanLocalNetworkActivity.java
This commit is contained in:
Nikolay Pultsin 2012-02-22 03:37:17 +00:00
parent 97ce1119b5
commit bd032e8523
12 changed files with 9 additions and 542 deletions

View file

@ -5,8 +5,6 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<application android:name="org.geometerplus.android.fbreader.FBReaderApplication" android:icon="@drawable/fbreader" android:label="FBReader">
<activity android:name=".library.BugReportActivity" android:label="FBReader crash" android:configChanges="orientation|keyboardHidden" android:process=":crash" />
<activity android:name="org.geometerplus.android.fbreader.crash.FixBooksDirectoryActivity" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden" android:process=":crash">
@ -187,12 +185,9 @@
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="*" android:scheme="opds" />
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.network.ScanLocalNetworkActivity" android:process=":networkLibrary" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.fbreader.action.ADD_OPDS_CATALOG" />
<action android:name="android.fbreader.action.ADD_OPDS_CATALOG_URL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:host="data.fbreader.org" android:scheme="http" android:path="/add_catalog/scanLocalNetwork"/>
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.network.AuthorizationMenuActivity" android:process=":networkLibrary" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden"/>

View file

@ -5,8 +5,6 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<application android:name="org.geometerplus.android.fbreader.FBReaderApplication" android:icon="@drawable/fbreader" android:label="FBReader">
<activity android:name=".library.BugReportActivity" android:label="FBReader crash" android:configChanges="orientation|keyboardHidden" android:process=":crash" />
<activity android:name="org.geometerplus.android.fbreader.crash.FixBooksDirectoryActivity" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden" android:process=":crash">
@ -188,13 +186,6 @@
<data android:host="*" android:scheme="opds" />
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.network.ScanLocalNetworkActivity" android:process=":networkLibrary" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.fbreader.action.ADD_OPDS_CATALOG" />
<category android:name="android.intent.category.DEFAULT" />
<data android:host="data.fbreader.org" android:scheme="http" android:path="/add_catalog/scanLocalNetwork"/>
</intent-filter>
</activity>
<activity android:name="org.geometerplus.android.fbreader.network.AuthorizationMenuActivity" android:process=":networkLibrary" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden"/>
<activity android:name="org.geometerplus.android.fbreader.network.TopupMenuActivity" android:process=":networkLibrary" android:theme="@android:style/Theme.Dialog" android:configChanges="orientation|keyboardHidden"/>
<activity android:name="org.geometerplus.android.fbreader.network.NetworkBookInfoActivity" android:process=":networkLibrary" android:configChanges="orientation|keyboardHidden">

View file

@ -123,13 +123,6 @@
<node name="addCatalog">
<node name="title" value="Add catalog"/>
<node name="editUrl" value="Enter URL manually"/>
<node name="scanLocalNetwork" value="Scan local network"/>
<node name="localCatalogs" value="Local OPDS catalogs"/>
<node name="noCatalogsFound" value="No catalogs found, sorry"/>
<node name="noLocalConnection" value="Your device is not connected to a local network"/>
<node name="wifiIsTurnedOff" value="WiFi is turned off"/>
<node name="turnWiFiOn" value="Please, turn WiFi on and try again"/>
<node name="scanningLocalNetwork" value="Scanning local network. Please, wait&#8230;"/>
</node>
<node name="menu">
<node name="networkSearch" value="Search"/>
@ -282,8 +275,6 @@
<node name="pay" value="Pay"/>
<node name="refresh" value="Refresh"/>
<node name="authorize" value="Authorize"/>
<node name="rescan" value="Rescan" />
<node name="turnOn" value="Turn on" />
<node name="resetPosition" value="Reset position" />
</node>
<node name="plugin">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="2dip"
android:orientation="horizontal"
android:gravity="center_vertical|left"
>
<ProgressBar
android:id="@+id/local_service_progress"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
style="@android:style/Widget.ProgressBar.Large"
android:gravity="center"
/>
<ImageView
android:id="@+id/local_service_icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:adjustViewBounds="false"
/>
<TextView
android:id="@+id/local_service_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:paddingRight="6dip"
/>
</LinearLayout>

View file

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scan_local_network_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical"
>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:isScrollContainer="true"
/>
<TextView
android:id="@+id/scan_local_network_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#FFFF0000"
/>
<include layout="@layout/ok_cancel_buttons" android:id="@+id/scan_local_network_buttons" />
</LinearLayout>

View file

@ -45,7 +45,7 @@ public class AddCatalogMenuActivity extends MenuActivity {
protected void init() {
setTitle(myResource.getResource("title").getValue());
addItem("editUrl", 1);
addItem("scanLocalNetwork", 2);
//addItem("scanLocalNetwork", 2);
}
@Override

View file

@ -94,7 +94,9 @@ public class AddCustomCatalogActivity extends Activity {
myEditNotAdd = Util.EDIT_CATALOG_ACTION.equals(action);
myLink = null;
Uri uri = null;
if (myEditNotAdd || Intent.ACTION_VIEW.equals(action)) {
if (myEditNotAdd ||
Intent.ACTION_VIEW.equals(action) ||
Util.ADD_CATALOG_URL_ACTION.equals(action)) {
uri = intent.getData();
if (uri != null) {
if ("opds".equals(uri.getScheme())) {
@ -106,10 +108,7 @@ public class AddCustomCatalogActivity extends Activity {
}
}
final INetworkLink.Type type = (INetworkLink.Type)intent.getSerializableExtra(TYPE);
if (type != null) {
myType = type;
}
myType = INetworkLink.Type.byIndex(intent.getIntExtra(TYPE, myType.Index));
}
if (myLink != null) {

View file

@ -1,453 +0,0 @@
/*
* Copyright (C) 2010-2012 Geometer Plus <contact@geometerplus.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.android.fbreader.network;
import java.util.*;
import java.net.*;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import android.app.ListActivity;
import android.content.*;
import android.graphics.Color;
import android.net.*;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import javax.jmdns.*;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.fbreader.network.NetworkLibrary;
import org.geometerplus.fbreader.network.INetworkLink;
import org.geometerplus.zlibrary.ui.android.R;
public class ScanLocalNetworkActivity extends ListActivity {
private final ZLResource myResource =
NetworkLibrary.Instance().resource().getResource("addCatalog");
private WifiManager.MulticastLock myLock;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this));
setContentView(R.layout.scan_local_network);
setListAdapter(new ItemAdapter());
setTitle(myResource.getResource("localCatalogs").getValue());
final View buttonView = findViewById(R.id.scan_local_network_buttons);
final ZLResource buttonResource = ZLResource.resource("dialog").getResource("button");
final Button cancelButton = (Button)buttonView.findViewById(R.id.cancel_button);
cancelButton.setText(buttonResource.getResource("cancel").getValue());
cancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
finish();
}
});
final WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
final int state = wifiManager.getWifiState();
if (state != WifiManager.WIFI_STATE_ENABLED && state != WifiManager.WIFI_STATE_ENABLING) {
setTitle(myResource.getResource("wifiIsTurnedOff").getValue());
final View listView = findViewById(android.R.id.list);
final TextView errorView = (TextView)findViewById(R.id.scan_local_network_error);
listView.setVisibility(View.GONE);
errorView.setVisibility(View.VISIBLE);
errorView.setText(myResource.getResource("turnWiFiOn").getValue());
/*
final Button turnOnButton = (Button)buttonView.findViewById(R.id.ok_button);
turnOnButton.setText(buttonResource.getResource("turnOn").getValue());
turnOnButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
wifiManager.setWifiEnabled(true);
finish();
}
});
*/
buttonView.findViewById(R.id.ok_button).setVisibility(View.GONE);
cancelButton.setText(buttonResource.getResource("ok").getValue());
myLock = null;
} else {
final Button rescanButton = (Button)buttonView.findViewById(R.id.ok_button);
rescanButton.setText(buttonResource.getResource("rescan").getValue());
rescanButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
runOnUiThread(new Runnable() {
public void run() {
clear();
scan();
}
});
}
});
myLock = wifiManager.createMulticastLock("FBReader_lock");
myLock.setReferenceCounted(true);
myLock.acquire();
scan();
}
}
@Override
protected void onDestroy() {
if (myLock != null) {
myLock.release();
}
super.onDestroy();
}
private List<InetAddress> getLocalIpAddresses() {
final List<InetAddress> addresses = new LinkedList<InetAddress>();
Method testPtoPMethod = null;
try {
testPtoPMethod = NetworkInterface.class.getMethod("isPointToPoint");
} catch (NoSuchMethodException e) {
}
try {
for (NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
try {
if (testPtoPMethod != null && (Boolean)testPtoPMethod.invoke(iface)) {
continue;
}
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
for (InetAddress addr : Collections.list(iface.getInetAddresses())) {
if (!addr.isLoopbackAddress() && addr instanceof Inet4Address) {
addresses.add(addr);
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
return addresses;
}
private class ServiceCollector implements ServiceListener {
private final static String STANZA_ZEROCONF_TYPE = "_stanza._tcp.local.";
private final static String CALIBRE_ZEROCONF_TYPE = "_calibre._tcp.local.";
private final static String OPDS_ZEROCONF_TYPE = "_opds._tcp.local.";
private JmDNS myMCDNS;
ServiceCollector(InetAddress address) {
try {
myMCDNS = JmDNS.create(address, "FBReader");
} catch (IOException e) {
return;
}
myMCDNS.addServiceListener(STANZA_ZEROCONF_TYPE, this);
myMCDNS.addServiceListener(CALIBRE_ZEROCONF_TYPE, this);
myMCDNS.addServiceListener(OPDS_ZEROCONF_TYPE, this);
runOnUiThread(new Runnable() {
public void run() {
getListAdapter().addWaitItem();
}
});
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
final ItemAdapter adapter = getListAdapter();
if (adapter.removeWaitItem() && adapter.getCount() == 0) {
setErrorText(myResource.getResource("noCatalogsFound").getValue());
}
}
});
try {
myMCDNS.close();
} catch (IOException e) {
e.printStackTrace();
}
timer.cancel();
}
}, 10000);
}
public void serviceAdded(ServiceEvent event) {
ServiceInfo info = event.getInfo();
if (info == null || !info.hasData()) {
info = myMCDNS.getServiceInfo(event.getType(), event.getName(), true);
}
addInfo(info);
}
public void serviceRemoved(ServiceEvent event) {
// TODO
}
public void serviceResolved(ServiceEvent event) {
addInfo(event.getInfo());
}
private void addInfo(final ServiceInfo info) {
if (info == null || !info.hasData()) {
return;
}
final String path = info.getPropertyString("path");
if (path == null) {
return;
}
final String[] urls = info.getURLs();
if (urls.length != 1) {
return;
}
if (urls[0] == null || !urls[0].endsWith(path)) {
return;
}
final String type = info.getType();
if (STANZA_ZEROCONF_TYPE.equals(info.getType()) || "/stanza".equals(path)) {
urls[0] = urls[0].substring(0, urls[0].length() - path.length()) + "/opds";
}
runOnUiThread(new Runnable() {
public void run() {
getListAdapter().addServiceItem(
info.getName(),
urls[0],
R.drawable.ic_list_library_calibre
);
}
});
}
}
private void scan() {
final List<InetAddress> addresses = getLocalIpAddresses();
if (addresses.isEmpty()) {
runOnUiThread(new Runnable() {
public void run() {
setErrorText(myResource.getResource("noLocalConnection").getValue());
}
});
} else {
for (final InetAddress a : addresses) {
new Thread() {
public void run() {
new ServiceCollector(a);
}
}.start();
}
}
}
private void clear() {
getListAdapter().clear();
final View listView = findViewById(android.R.id.list);
final TextView errorView = (TextView)findViewById(R.id.scan_local_network_error);
listView.setVisibility(View.VISIBLE);
errorView.setVisibility(View.GONE);
}
private void setErrorText(final String errorText) {
final View listView = findViewById(android.R.id.list);
final TextView errorView = (TextView)findViewById(R.id.scan_local_network_error);
listView.setVisibility(View.GONE);
errorView.setVisibility(View.VISIBLE);
errorView.setText(errorText);
}
private class ItemAdapter extends BaseAdapter {
final private WaitItem myWaitItem = new WaitItem(
myResource.getResource("scanningLocalNetwork").getValue()
);
private volatile int myWaitItemCount;
private final ArrayList<ServiceInfoItem> myItems = new ArrayList<ServiceInfoItem>();
@Override
public Item getItem(int position) {
try {
return myItems.get(position);
} catch (Exception e) {
return myWaitItem;
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public synchronized int getCount() {
return myWaitItemCount > 0 ? myItems.size() + 1 : myItems.size();
}
synchronized void clear() {
myItems.clear();
myWaitItemCount = 0;
notifyDataSetChanged();
}
synchronized boolean addWaitItem() {
if (myWaitItemCount++ == 0) {
notifyDataSetChanged();
findViewById(R.id.scan_local_network_container).invalidate();
return true;
}
return false;
}
synchronized boolean removeWaitItem() {
if (myWaitItemCount == 0) {
return false;
}
if (--myWaitItemCount == 0) {
notifyDataSetChanged();
findViewById(R.id.scan_local_network_container).invalidate();
return true;
}
return false;
}
synchronized void addServiceItem(String name, String url, int iconId) {
try {
final ServiceInfoItem item = new ServiceInfoItem(name, Uri.parse(url), iconId);
if (!myItems.contains(item)) {
myItems.add(item);
notifyDataSetChanged();
findViewById(R.id.scan_local_network_container).invalidate();
}
} catch (ParseException e) {
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Item item = getItem(position);
final View view;
if (convertView == null) {
view = LayoutInflater.from(ScanLocalNetworkActivity.this).inflate(R.layout.local_service_item, parent, false);
} else {
view = convertView;
}
final TextView textView = (TextView)view.findViewById(R.id.local_service_text);
final ImageView iconView = (ImageView)view.findViewById(R.id.local_service_icon);
final ProgressBar progress = (ProgressBar)view.findViewById(R.id.local_service_progress);
if (convertView == null) {
view.measure(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int h = view.getMeasuredHeight() * 6 / 10;
iconView.getLayoutParams().width = h;
iconView.getLayoutParams().height = h;
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
iconView.requestLayout();
progress.getLayoutParams().width = h;
progress.getLayoutParams().height = h;
iconView.requestLayout();
}
textView.setText(item.Name);
if (item instanceof ServiceInfoItem) {
iconView.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
iconView.setImageResource(((ServiceInfoItem)item).IconId);
} else /* item instanceof WaitItem */ {
iconView.setVisibility(View.GONE);
progress.setVisibility(View.VISIBLE);
}
return view;
}
}
private static abstract class Item {
public final String Name;
public Item(String name) {
Name = name;
}
}
private static class ServiceInfoItem extends Item {
public final Uri URI;
public final int IconId;
public ServiceInfoItem(String name, Uri uri, int iconId) {
super(name);
URI = uri;
IconId = iconId;
}
@Override
public int hashCode() {
return Name.hashCode() + URI.hashCode();
}
@Override
public boolean equals(Object o) {
return
o instanceof ServiceInfoItem &&
Name.equals(((ServiceInfoItem)o).Name) &&
URI.equals(((ServiceInfoItem)o).URI);
}
}
private static class WaitItem extends Item {
public WaitItem(String name) {
super(name);
}
}
@Override
protected void onListItemClick(ListView parent, View view, int position, long id) {
final Item item = getListAdapter().getItem(position);
if (item instanceof ServiceInfoItem) {
try {
startActivity(new Intent(
Intent.ACTION_VIEW,
((ServiceInfoItem)item).URI,
getApplicationContext(),
AddCustomCatalogActivity.class
).putExtra(AddCustomCatalogActivity.TYPE, INetworkLink.Type.Local));
finish();
} catch (ActivityNotFoundException e) {
}
}
}
@Override
public ItemAdapter getListAdapter() {
return (ItemAdapter)super.getListAdapter();
}
}

View file

@ -41,6 +41,7 @@ public abstract class Util implements UserRegistrationConstants {
static final String SIGNIN_ACTION = "android.fbreader.action.network.SIGNIN";
public static final String ADD_CATALOG_ACTION = "android.fbreader.action.ADD_OPDS_CATALOG";
public static final String ADD_CATALOG_URL_ACTION = "android.fbreader.action.ADD_OPDS_CATALOG_URL";
public static final String EDIT_CATALOG_ACTION = "android.fbreader.action.EDIT_OPDS_CATALOG";
public static Intent intentByLink(Intent intent, INetworkLink link) {

View file

@ -21,6 +21,7 @@ package org.geometerplus.android.fbreader.network.action;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import org.geometerplus.fbreader.network.NetworkTree;
import org.geometerplus.fbreader.network.tree.RootTree;
@ -42,6 +43,6 @@ public class AddCustomCatalogAction extends Action {
@Override
public void run(NetworkTree tree) {
myActivity.startActivity(new Intent(myActivity, AddCatalogMenuActivity.class));
myActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://data.fbreader.org/add_catalog"), myActivity, AddCatalogMenuActivity.class));
}
}